Skip to content

Commit ed45164

Browse files
committed
add extended network sibling check based on sibling orgs
1 parent e9c4ccc commit ed45164

File tree

3 files changed

+105
-2
lines changed

3 files changed

+105
-2
lines changed

src/asinfo/mod.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,13 @@
6262
6363
mod hegemony;
6464
mod population;
65+
mod sibling_orgs;
6566

6667
pub use crate::asinfo::hegemony::HegemonyData;
6768
pub use crate::asinfo::population::AsnPopulationData;
69+
use crate::asinfo::sibling_orgs::SiblingOrgsUtils;
6870
use crate::BgpkitCommons;
6971
use anyhow::{anyhow, Result};
70-
use oneio::OneIoError;
7172
use serde::{Deserialize, Serialize};
7273
use std::collections::HashMap;
7374
use tracing::info;
@@ -95,6 +96,7 @@ const BGPKIT_ASN_TXT_MIRROR_URL: &str = "https://data.bgpkit.com/commons/asn.txt
9596

9697
pub struct AsInfoUtils {
9798
pub asinfo_map: HashMap<u32, AsInfo>,
99+
pub sibling_orgs: Option<SiblingOrgsUtils>,
98100
pub load_as2org: bool,
99101
pub load_population: bool,
100102
pub load_hegemony: bool,
@@ -103,8 +105,14 @@ pub struct AsInfoUtils {
103105
impl AsInfoUtils {
104106
pub fn new(load_as2org: bool, load_population: bool, load_hegemony: bool) -> Result<Self> {
105107
let asinfo_map = get_asinfo_map(load_as2org, load_population, load_hegemony)?;
108+
let sibling_orgs = if load_as2org {
109+
Some(SiblingOrgsUtils::new()?)
110+
} else {
111+
None
112+
};
106113
Ok(AsInfoUtils {
107114
asinfo_map,
115+
sibling_orgs,
108116
load_as2org,
109117
load_population,
110118
load_hegemony,
@@ -225,7 +233,18 @@ impl BgpkitCommons {
225233
let org_1_opt = info_1_opt.unwrap().as2org;
226234
let org_2_opt = info_2_opt.unwrap().as2org;
227235
if org_1_opt.is_some() && org_2_opt.is_some() {
228-
return Ok(org_1_opt.unwrap().org_id == org_2_opt.unwrap().org_id);
236+
let org_id_1 = org_1_opt.unwrap().org_id;
237+
let org_id_2 = org_2_opt.unwrap().org_id;
238+
239+
return Ok(org_id_1 == org_id_2
240+
|| self
241+
.asinfo
242+
.as_ref()
243+
.unwrap()
244+
.sibling_orgs
245+
.as_ref()
246+
.unwrap()
247+
.are_sibling_orgs(org_id_1.as_str(), org_id_2.as_str()));
229248
}
230249
}
231250
Ok(false)

src/asinfo/sibling_orgs.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
use anyhow::Result;
2+
use std::collections::{HashMap, HashSet};
3+
use tracing::info;
4+
5+
const BGPKIT_SIBLING_ORGS_URL: &str = "https://data.bgpkit.com/commons/sibling-orgs.txt";
6+
7+
pub struct SiblingOrgsUtils {
8+
sibling_orgs_map: HashMap<String, HashSet<String>>,
9+
}
10+
11+
impl SiblingOrgsUtils {
12+
pub fn new() -> Result<Self> {
13+
info!(
14+
"loading sibling orgs information from {}",
15+
BGPKIT_SIBLING_ORGS_URL
16+
);
17+
let mut sibling_orgs = vec![];
18+
for line in oneio::read_lines(BGPKIT_SIBLING_ORGS_URL)? {
19+
let line_str = line?.trim().to_string();
20+
if line_str.is_empty() || line_str.starts_with('#') {
21+
// skip empty line or line started with #
22+
continue;
23+
}
24+
let orgs: Vec<String> = line_str.split_whitespace().map(|x| x.to_owned()).collect();
25+
sibling_orgs.push(orgs);
26+
}
27+
28+
let mut res_map = HashMap::new();
29+
for sibling_lst in sibling_orgs {
30+
let mut org_set: HashSet<String> = HashSet::new();
31+
sibling_lst.iter().for_each(|org| {
32+
org_set.insert(org.to_lowercase());
33+
});
34+
35+
sibling_lst.iter().for_each(|org| {
36+
let org_id = org.to_owned();
37+
res_map.insert(org_id.to_lowercase(), org_set.clone());
38+
});
39+
}
40+
41+
Ok(SiblingOrgsUtils {
42+
sibling_orgs_map: res_map,
43+
})
44+
}
45+
46+
pub fn are_sibling_orgs(&self, org_1: &str, org_2: &str) -> bool {
47+
if let Some(s) = self.sibling_orgs_map.get(org_1.to_lowercase().as_str()) {
48+
if s.contains(org_2.to_lowercase().as_str()) {
49+
return true;
50+
}
51+
}
52+
53+
false
54+
}
55+
}
56+
57+
#[cfg(test)]
58+
mod tests {
59+
use super::*;
60+
61+
#[test]
62+
fn test_sibling_orgs() {
63+
let utils = SiblingOrgsUtils::new().unwrap();
64+
65+
// GTT
66+
assert!(utils.are_sibling_orgs("GC-494-ARIN", "ORG-GCI2-RIPE"));
67+
// GTT with random cases
68+
assert!(utils.are_sibling_orgs("Gc-494-ArIn", "OrG-gCi2-RiPe"));
69+
// GTT and Cogent (not sibling)
70+
assert!(!utils.are_sibling_orgs("GC-494-ARIN", "COGC-ARIN"));
71+
}
72+
}

src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,15 @@ impl BgpkitCommons {
148148
Ok(())
149149
}
150150
}
151+
152+
#[cfg(test)]
153+
mod tests {
154+
use super::*;
155+
156+
#[test]
157+
fn test_siblings() {
158+
let mut commons = BgpkitCommons::new();
159+
commons.load_asinfo(true, false, false).unwrap();
160+
assert!(commons.asinfo_are_siblings(174, 1239).unwrap());
161+
}
162+
}

0 commit comments

Comments
 (0)