Skip to content

Commit

Permalink
add load_mrt_collector_peers()
Browse files Browse the repository at this point in the history
  • Loading branch information
digizeph committed Oct 31, 2024
1 parent 7249d79 commit 98d71dd
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ use crate::as2rel::As2relBgpkit;
use crate::asinfo::AsInfoUtils;
use crate::bogons::Bogons;
use crate::countries::Countries;
use crate::mrt_collectors::MrtCollector;
use crate::mrt_collectors::{MrtCollector, MrtCollectorPeer};
use crate::rpki::RpkiTrie;
use anyhow::Result;
use chrono::NaiveDate;
Expand All @@ -65,6 +65,7 @@ pub struct BgpkitCommons {
countries: Option<Countries>,
rpki_trie: Option<RpkiTrie>,
mrt_collectors: Option<Vec<MrtCollector>>,
mrt_collector_peers: Option<Vec<MrtCollectorPeer>>,
bogons: Option<Bogons>,
asinfo: Option<AsInfoUtils>,
as2rel: Option<As2relBgpkit>,
Expand All @@ -86,6 +87,9 @@ impl BgpkitCommons {
if self.mrt_collectors.is_some() {
self.load_mrt_collectors()?;
}
if self.mrt_collector_peers.is_some() {
self.load_mrt_collector_peers()?;
}
if self.bogons.is_some() {
self.load_bogons()?;
}
Expand Down Expand Up @@ -121,6 +125,12 @@ impl BgpkitCommons {
Ok(())
}

/// Load MRT mrt_collectors data
pub fn load_mrt_collector_peers(&mut self) -> Result<()> {
self.mrt_collector_peers = Some(mrt_collectors::get_mrt_collector_peers()?);
Ok(())
}

/// Load bogons data
pub fn load_bogons(&mut self) -> Result<()> {
self.bogons = Some(Bogons::new()?);
Expand Down
26 changes: 26 additions & 0 deletions src/mrt_collectors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ use serde::{Deserialize, Serialize, Serializer};
use std::cmp::Ordering;
use std::fmt::{Display, Formatter};

mod peers;
mod riperis;
mod routeviews;

use crate::BgpkitCommons;
pub use peers::{get_mrt_collector_peers, MrtCollectorPeer};
pub use riperis::get_riperis_collectors;
pub use routeviews::get_routeviews_collectors;

Expand Down Expand Up @@ -119,4 +121,28 @@ impl BgpkitCommons {
.as_ref()
.map(|c| c.iter().filter(|x| x.country == country).cloned().collect())
}

pub fn mrt_collector_peers_all(&self) -> Result<Vec<MrtCollectorPeer>> {
if self.mrt_collector_peers.is_none() {
return Err(anyhow!(
"mrt_collector_peers is not loaded, call commons.load_mrt_collector_peers() first"
));
}
Ok(self.mrt_collector_peers.clone().unwrap())
}

pub fn mrt_collector_peers_full_feed(&self) -> Result<Vec<MrtCollectorPeer>> {
if self.mrt_collector_peers.is_none() {
return Err(anyhow!("mrt_collector_peers is not loaded"));
}
// Filter out mrt_collectors that have full feed
Ok(self
.mrt_collector_peers
.as_ref()
.unwrap()
.iter()
.filter(|x| x.is_full_feed())
.cloned()
.collect())
}
}
68 changes: 68 additions & 0 deletions src/mrt_collectors/peers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use anyhow::Result;
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
use std::net::IpAddr;

const COLLECTOR_PEERS_URL: &str = "https://api.bgpkit.com/v3/peers/list";

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MrtCollectorPeersData {
pub count: u32,
pub data: Vec<MrtCollectorPeer>,
}

/// MRT collector meta information
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct MrtCollectorPeer {
/// latest available dated
pub date: NaiveDate,
/// collector peer IP
pub ip: IpAddr,
/// collector peer ASN
pub asn: u32,
/// collector name
pub collector: String,
/// number of IPv4 prefixes
pub num_v4_pfxs: u32,
/// number of IPv6 prefixes
pub num_v6_pfxs: u32,
/// number of connected ASNs
pub num_connected_asns: u32,
}

impl MrtCollectorPeer {
pub fn is_full_feed_v4(&self) -> bool {
self.num_v4_pfxs >= 700_000
}

pub fn is_full_feed_v6(&self) -> bool {
self.num_v6_pfxs >= 100_000
}

pub fn is_full_feed(&self) -> bool {
self.is_full_feed_v4() || self.is_full_feed_v6()
}
}

pub fn get_mrt_collector_peers() -> Result<Vec<MrtCollectorPeer>> {
let peers: MrtCollectorPeersData = oneio::read_json_struct(COLLECTOR_PEERS_URL)?;

Ok(peers.data)
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_get_peers() {
let mut peers = get_mrt_collector_peers().unwrap();
assert!(!peers.is_empty());
// sort peers by the number of connected ASNs
peers.sort_by(|a, b| b.num_connected_asns.cmp(&a.num_connected_asns));
// print top 10 peers
for peer in peers.iter().take(10) {
println!("{:?}", peer);
}
}
}
19 changes: 19 additions & 0 deletions tests/mrt_collectors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#[test]
fn test_get_collectors() {
let mut commons = bgpkit_commons::BgpkitCommons::new();
commons.load_mrt_collectors().unwrap();

let collectors = commons.mrt_collectors_all().unwrap();
assert!(!collectors.is_empty());
}

#[test]
fn test_get_collector_peers() {
let mut commons = bgpkit_commons::BgpkitCommons::new();
commons.load_mrt_collector_peers().unwrap();
let all_collector_peers = commons.mrt_collector_peers_all().unwrap();
assert!(!all_collector_peers.is_empty());
let full_feed_collector_peers = commons.mrt_collector_peers_full_feed().unwrap();
assert!(!full_feed_collector_peers.is_empty());
assert!(full_feed_collector_peers.len() < all_collector_peers.len());
}

0 comments on commit 98d71dd

Please sign in to comment.