From ae70c4b9148319b3432b2d8baf30f9227ae5f41e Mon Sep 17 00:00:00 2001 From: bauen1 Date: Tue, 19 May 2020 08:44:54 +0200 Subject: [PATCH] fix parsing of burbles new route object --- src/main.rs | 75 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index 76cbc19..7c79dd0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,42 +36,69 @@ impl fmt::Display for ROA { impl TryFrom for ROA { type Error = &'static str; + fn try_from(file: File) -> Result { + let mut attributes: Vec<(String, String)> = vec![]; + + for wrapped_line in std::io::BufReader::new(file).lines() { + let line = wrapped_line.unwrap(); + + /* is this a continuation of the previous attribute ? */ + if line.starts_with(' ') { + if attributes.is_empty() { + return Err("Invalid route object starting with whitespace"); + } + + let (_, ref mut v) = attributes.last_mut().unwrap(); + v.push_str(line.trim_start()); + } + + /* newline continuation */ + if line.starts_with('+') { + if attributes.is_empty() { + return Err("Invalid route object starting with a newline continuation"); + } + + let (_, ref mut v) = attributes.last_mut().unwrap(); + v.push('\n'); + } + + let fields: Vec<&str> = line.splitn(2, ' ').collect(); + if fields.is_empty() { + return Err("Invalid route object"); + } + + attributes.push(( + (*fields.get(0).unwrap()).to_string(), + fields.get(1).unwrap_or(&"").trim_start().to_string() + )); + } + + let mut route: Option = None; let mut origins: Vec = Vec::new(); let mut maxlen: Option = None; - for line in std::io::BufReader::new(file).lines() { - let real_line = line.unwrap(); - let fields: Vec<&str> = real_line.split_whitespace().collect(); - - match fields[0] { + for (key, value) in attributes { + match key.as_ref() { "route:" | "route6:" => { - route = Some(fields[1].parse().map_err(|_| "invalid route attribute")?); - } - + let v: IpCidr = value.parse::().map_err(|_| "invalid route attribute")?; + route = Some(v); + }, "origin:" => { - origins.push( - fields[1] - .trim_start_matches("AS") - .parse() - .map_err(|_| "invalid origin attribute")?, - ); - } - + let origin: u32 = value.trim_start_matches("AS").parse().map_err(|_| "invalid origin attribute")?; + origins.push(origin); + }, "max-length:" => { - maxlen = Some( - fields[1] - .parse() - .map_err(|_| "invalid max-length attribute")?, - ); - } - + maxlen = Some(value.parse().map_err(|_| "invalid max-length attribute")?); + }, _ => {} } } - assert!(!origins.is_empty(), "missing origin attribute"); + if origins.is_empty() { + return Err("missing origin attributes"); + } Ok(Self { route: route.expect("missing route attribute"),