Skip to content

Commit

Permalink
Merge pull request #15 from bgpkit/feature/hegemony
Browse files Browse the repository at this point in the history
add support for loading hegemony score from bgpkit mirror
  • Loading branch information
digizeph authored Jun 24, 2024
2 parents 43b194b + 5b6306c commit 42285f1
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/asnames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use bgpkit_commons::asnames::{get_asnames, AsName};
use std::collections::HashMap;

fn main() {
tracing_subscriber::fmt::init();
let asnames: HashMap<u32, AsName> = get_asnames().unwrap();
println!(
"{}",
Expand Down
80 changes: 80 additions & 0 deletions src/asnames/hegemony.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use tracing::{info, warn};

const IIJ_IHR_HEGEMONY_IPV4_GLOBAL: &str =
"https://data.bgpkit.com/ihr/hegemony/ipv4/global/latest-simplified.csv.gz";
const IIJ_IHR_HEGEMONY_IPV6_GLOBAL: &str =
"https://data.bgpkit.com/ihr/hegemony/ipv6/global/latest-simplified.csv.gz";

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Hegemony {
hegemony_map: HashMap<u32, HegemonyData>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HegemonyData {
pub asn: u32,
pub ipv4: f64,
pub ipv6: f64,
}

fn load_hegemony(path: &str) -> Result<Vec<(u32, f64)>> {
info!("loading hegemony scores from {}", path);
// load global hegemony scores data CSV file with header where there are two columns: ASN, score
let mut hegemony = Vec::new();
for line in oneio::read_lines(path)? {
let text = line.ok().ok_or(anyhow!("error reading line"))?;
if text.trim() == "" || text.starts_with("asn") {
continue;
}
let splits: Vec<&str> = text.split(',').map(|x| x.trim()).collect();
if splits.len() != 2 {
return Err(anyhow!("row missing fields: {}", text.as_str()));
}
let asn = match splits[0].parse::<u32>() {
Ok(asn) => asn,
Err(_) => {
warn!("invalid ASN: {}", text);
continue;
}
};
let score = splits[1].parse::<f64>()?;
hegemony.push((asn, score));
}
Ok(hegemony)
}

impl Hegemony {
pub fn new() -> Result<Self> {
let ipv4 = load_hegemony(IIJ_IHR_HEGEMONY_IPV4_GLOBAL)?;
let ipv6 = load_hegemony(IIJ_IHR_HEGEMONY_IPV6_GLOBAL)?;
let mut hegemony_map = HashMap::new();
for (asn, score) in ipv4 {
hegemony_map.insert(
asn,
HegemonyData {
asn,
ipv4: score,
ipv6: 0.0,
},
);
}
for (asn, score) in ipv6 {
hegemony_map
.entry(asn)
.or_insert_with(|| HegemonyData {
asn,
ipv4: 0.0,
ipv6: 0.0,
})
.ipv6 = score;
}
Ok(Self { hegemony_map })
}

pub fn get_score(&self, asn: u32) -> Option<&HegemonyData> {
self.hegemony_map.get(&asn)
}
}
6 changes: 6 additions & 0 deletions src/asnames/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@
//! assert_eq!(asnames.get(&400644).unwrap().country, "US");
//! ```
mod hegemony;
mod population;

use crate::asnames::hegemony::HegemonyData;
use crate::asnames::population::AsnPopulationData;
use anyhow::Result;
use serde::{Deserialize, Serialize};
Expand All @@ -60,6 +62,7 @@ pub struct AsName {
pub country: String,
pub as2org: Option<As2orgInfo>,
pub population: Option<AsnPopulationData>,
pub hegemony: Option<HegemonyData>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
Expand All @@ -79,6 +82,8 @@ pub fn get_asnames() -> Result<HashMap<u32, AsName>> {
let as2org = as2org_rs::As2org::new(None)?;
info!("loading ASN population data from APNIC...");
let population = population::AsnPopulation::new()?;
info!("loading IIJ IHR hegemony score data from BGPKIT mirror...");
let hegemony = hegemony::Hegemony::new()?;

let asnames = text
.lines()
Expand All @@ -105,6 +110,7 @@ pub fn get_asnames() -> Result<HashMap<u32, AsName>> {
country: country_str.to_string(),
as2org,
population,
hegemony: hegemony.get_score(asn).cloned(),
})
})
.collect::<Vec<AsName>>();
Expand Down

0 comments on commit 42285f1

Please sign in to comment.