bgpkit-commons 0.8.2

A library for common BGP-related data and functions.
Documentation
//! # Overview
//!
//! BGPKIT-Commons is a library for common BGP-related data and functions.
//!
//! It provides the following modules:
//! - `mrt_collectors`: public RouteViews and RIPE RIS MRT mrt_collectors information extracted from their official APIs
//! - `asinfo`: Autonomous System (AS) information and country lookup
//! - `countries`: country code to name and other information lookup
//! - `rpki`: RPKI validation data. Historical data from RIPE NCC and real-time data from Cloudflare
//! - `bogons`: IP prefix and ASN bogon lookup
//! - `as2rel`: AS-level relationship data, generated by BGPKIT
//!
//! ## Basic Usage
//!
//! Add `bgpkit-commons` to your `Cargo.toml`'s `dependencies` section:
//! ```toml
//! bgpkit-commons = "0.8"
//! ```
//!
//! `bgpkit-commons` is designed to load only the data you need. Here is an example of checking if an ASN is a bogon ASN:
//!
//! ```rust
//! use bgpkit_commons::BgpkitCommons;
//!
//! let mut bgpkit = BgpkitCommons::new();
//! bgpkit.load_bogons().unwrap();
//! assert!(bgpkit.bogons_match("23456").unwrap());
//! ```
//!
//! The common steps include:
//! 1. create a mutable `BgpkitCommons` instance
//! 2. load the data you need by calling `bgpkit.load_xxx()` functions
//! 3. use the data by calling the corresponding functions, named as `bgpkit.xxx_yyy()`
//!
//! For detailed usages, please refer to the module documentation.
//!
//! ## Feature Flags
//!
//! - `rustls` (default): use rustls instead of native-tls for the underlying HTTPS requests
//! - `native-tls`: use native-tls as the backend

#![doc(
    html_logo_url = "https://raw.githubusercontent.com/bgpkit/assets/main/logos/icon-transparent.png",
    html_favicon_url = "https://raw.githubusercontent.com/bgpkit/assets/main/logos/favicon.ico"
)]

use crate::as2rel::As2relBgpkit;
use crate::asinfo::AsInfoUtils;
use crate::bogons::Bogons;
use crate::countries::Countries;
use crate::mrt_collectors::{MrtCollector, MrtCollectorPeer};
use crate::rpki::RpkiTrie;
use anyhow::Result;
use chrono::NaiveDate;

pub mod as2rel;
pub mod asinfo;
pub mod bogons;
pub mod countries;
pub mod mrt_collectors;
pub mod rpki;

#[derive(Default)]
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>,
}

impl BgpkitCommons {
    pub fn new() -> Self {
        Self::default()
    }

    /// Reload all data sources that are already loaded
    pub fn reload(&mut self) -> Result<()> {
        if self.countries.is_some() {
            self.load_countries()?;
        }
        if let Some(rpki) = self.rpki_trie.as_mut() {
            rpki.reload()?;
        }
        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()?;
        }
        if let Some(asinfo) = self.asinfo.as_mut() {
            asinfo.reload()?;
        }
        if self.as2rel.is_some() {
            self.load_as2rel()?;
        }

        Ok(())
    }

    /// Load countries data
    pub fn load_countries(&mut self) -> Result<()> {
        self.countries = Some(Countries::new()?);
        Ok(())
    }

    /// Load RPKI data
    pub fn load_rpki(&mut self, date_opt: Option<NaiveDate>) -> Result<()> {
        if let Some(date) = date_opt {
            self.rpki_trie = Some(RpkiTrie::from_ripe_historical(date)?);
        } else {
            self.rpki_trie = Some(RpkiTrie::from_cloudflare()?);
        }
        Ok(())
    }

    /// Load MRT mrt_collectors data
    pub fn load_mrt_collectors(&mut self) -> Result<()> {
        self.mrt_collectors = Some(mrt_collectors::get_all_collectors()?);
        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()?);
        Ok(())
    }

    /// Load AS name and country data
    pub fn load_asinfo(
        &mut self,
        load_as2org: bool,
        load_population: bool,
        load_hegemony: bool,
        load_peeringdb: bool,
    ) -> Result<()> {
        self.asinfo = Some(AsInfoUtils::new(
            load_as2org,
            load_population,
            load_hegemony,
            load_peeringdb,
        )?);
        Ok(())
    }

    pub fn load_asinfo_cached(&mut self) -> Result<()> {
        self.asinfo = Some(AsInfoUtils::new_from_cached()?);
        Ok(())
    }

    /// Load AS-level relationship data
    pub fn load_as2rel(&mut self) -> Result<()> {
        self.as2rel = Some(As2relBgpkit::new()?);
        Ok(())
    }
}