X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fbgp_client.rs;h=1fa92501c2601ee16ed28c4cec4661e935a44c83;hb=96812ac2c2b769c977e23c0e55a4667a708193e9;hp=8f264c660e49840674137be1192ed75cf1ec1b26;hpb=2ad1116fe90722943347b2b222cef89dd5abcf7e;p=dnsseed-rust diff --git a/src/bgp_client.rs b/src/bgp_client.rs index 8f264c6..1fa9250 100644 --- a/src/bgp_client.rs +++ b/src/bgp_client.rs @@ -46,14 +46,14 @@ impl RoutingTable { ($addrty: ty, $addr: expr, $table: expr, $addr_bits: expr) => { { let mut res = Vec::new(); //TODO: Optimize this! - for i in (0..($addr_bits + 1)).rev() { + for i in (0..$addr_bits).rev() { let mut lookup = $addr.octets(); for b in 0..(i / 8) { - lookup[lookup.len() - b] = 0; + lookup[lookup.len() - b - 1] = 0; } - lookup[lookup.len() - (i/8)] &= !(((1u16 << (i % 8)) - 1) as u8); + lookup[lookup.len() - (i/8) - 1] &= !(((1u16 << (i % 8)) - 1) as u8); let lookup_addr = <$addrty>::from(lookup); - for attrs in $table.range((Included((lookup_addr, $addr_bits, 0)), Included((lookup_addr, $addr_bits, std::u32::MAX)))) { + for attrs in $table.range((Included((lookup_addr, $addr_bits - i as u8, 0)), Included((lookup_addr, $addr_bits - i as u8, std::u32::MAX)))) { res.push(Arc::clone(&attrs.1)); } if !res.is_empty() { break; } @@ -176,13 +176,24 @@ pub struct BGPClient { impl BGPClient { pub fn get_asn(&self, addr: IpAddr) -> u32 { let mut path_vecs = self.routes.lock().unwrap().get_route_attrs(addr).clone(); + if path_vecs.is_empty() { return 0; } + path_vecs.sort_unstable_by(|path_a, path_b| { path_a.pref.cmp(&path_b.pref) .then(path_b.path.len().cmp(&path_a.path.len())) .then(path_b.med.cmp(&path_a.med)) }); - // TODO: Find last common ASN among all paths - *path_vecs[0].path.last().unwrap_or(&0) + + let primary_route = path_vecs.pop().unwrap(); + 'asn_candidates: for asn in primary_route.path.iter().rev() { + for secondary_route in path_vecs.iter() { + if !secondary_route.path.contains(asn) { + continue 'asn_candidates; + } + } + return *asn; + } + *primary_route.path.last().unwrap_or(&0) } pub fn disconnect(&self) { @@ -257,7 +268,9 @@ impl BGPClient { } match bgp_msg { Message::Open(_) => { - printer.add_line("Connected to BGP route provider".to_string(), true); + client.routes.lock().unwrap().v4_table.clear(); + client.routes.lock().unwrap().v6_table.clear(); + printer.add_line("Connected to BGP route provider".to_string(), false); }, Message::KeepAlive => { let _ = sender.try_send(Message::KeepAlive);