rws_proxy/traffic/
hosting.rs1use std::net::IpAddr;
14use std::sync::OnceLock;
15
16use super::geo::Table;
17
18#[cfg(feature = "geo")]
19static BUNDLED: &[u8] = include_bytes!("hosting.bin");
20
21const PROVIDERS: [(&[u8; 2], &str); 20] = [
23 (b"AW", "AWS"),
24 (b"GC", "Google Cloud"),
25 (b"AZ", "Azure"),
26 (b"OR", "Oracle Cloud"),
27 (b"AL", "Alibaba Cloud"),
28 (b"TC", "Tencent Cloud"),
29 (b"HW", "Huawei Cloud"),
30 (b"DO", "DigitalOcean"),
31 (b"LI", "Linode"),
32 (b"VU", "Vultr"),
33 (b"OV", "OVHcloud"),
34 (b"HZ", "Hetzner"),
35 (b"CB", "Contabo"),
36 (b"SC", "Scaleway"),
37 (b"LW", "Leaseweb"),
38 (b"IO", "IONOS"),
39 (b"HG", "Hostinger"),
40 (b"IB", "IBM Cloud"),
41 (b"RS", "Rackspace"),
42 (b"DC", "other hosting"),
43];
44
45pub fn table() -> Option<&'static Table> {
47 static TABLE: OnceLock<Option<Table>> = OnceLock::new();
48 TABLE.get_or_init(bundled).as_ref()
49}
50
51#[cfg(feature = "geo")]
52fn bundled() -> Option<Table> {
53 match Table::decode(BUNDLED) {
54 Ok(table) => Some(table),
55 Err(e) => {
56 eprintln!("traffic: built-in hosting table: {e}");
57 None
58 }
59 }
60}
61
62#[cfg(not(feature = "geo"))]
63fn bundled() -> Option<Table> {
64 None
65}
66
67pub fn provider(ip: IpAddr) -> Option<&'static str> {
70 provider_in(table()?, ip)
71}
72
73#[doc(hidden)]
75pub fn provider_in(table: &Table, ip: IpAddr) -> Option<&'static str> {
76 let code = table.country(ip)?;
77 Some(PROVIDERS.iter().find(|(c, _)| **c == code).map_or("other hosting", |(_, name)| name))
78}