hopr_network_types/
addr.rs1use std::net::IpAddr;
2
3use multiaddr::Multiaddr;
4
5pub fn is_public(ip_addr: IpAddr) -> bool {
7 match ip_addr {
8 IpAddr::V4(ip) => !ip.is_unspecified() && !ip.is_private() && !ip.is_loopback() && !ip.is_link_local(),
9 IpAddr::V6(ip) => {
10 !ip.is_unspecified() && !ip.is_loopback() && !ip.is_unicast_link_local() && !ip.is_unique_local()
11 }
12 }
13}
14
15pub fn is_public_address(addr: &Multiaddr) -> bool {
17 addr.iter().all(|protocol| match protocol {
18 multiaddr::Protocol::Ip4(ip) => is_public(ip.into()),
19 multiaddr::Protocol::Ip6(ip) => is_public(ip.into()),
20 _ => true,
21 })
22}
23
24#[cfg(test)]
25mod tests {
26 use std::str::FromStr;
27
28 use super::*;
29
30 #[test]
31 fn test_is_public_address_ipv4() -> anyhow::Result<()> {
32 assert!(is_public_address(&Multiaddr::from_str("/ip4/8.8.8.8")?));
34 assert!(is_public_address(&Multiaddr::from_str("/ip4/1.1.1.1")?));
35 assert!(is_public_address(&Multiaddr::from_str("/ip4/104.16.0.0")?));
36
37 assert!(!is_public_address(&Multiaddr::from_str("/ip4/192.168.0.1")?));
39 assert!(!is_public_address(&Multiaddr::from_str("/ip4/192.168.1.254")?));
40 assert!(!is_public_address(&Multiaddr::from_str("/ip4/10.0.0.1")?));
41 assert!(!is_public_address(&Multiaddr::from_str("/ip4/10.1.0.1")?));
42 assert!(!is_public_address(&Multiaddr::from_str("/ip4/10.255.255.255")?));
43 assert!(!is_public_address(&Multiaddr::from_str("/ip4/172.16.0.0")?));
44 assert!(!is_public_address(&Multiaddr::from_str("/ip4/172.31.255.255")?));
45
46 assert!(!is_public_address(&Multiaddr::from_str("/ip4/127.0.0.1")?));
48 assert!(!is_public_address(&Multiaddr::from_str("/ip4/127.255.255.255")?));
49
50 assert!(!is_public_address(&Multiaddr::from_str("/ip4/169.254.1.1")?));
52 assert!(!is_public_address(&Multiaddr::from_str("/ip4/169.254.254.254")?));
53
54 assert!(!is_public_address(&Multiaddr::from_str("/ip4/0.0.0.0")?));
56
57 Ok(())
58 }
59
60 #[test]
61 fn test_is_public_address_ipv6() -> anyhow::Result<()> {
62 assert!(is_public_address(&Multiaddr::from_str("/ip6/2001:4860:4860::8888")?));
64 assert!(is_public_address(&Multiaddr::from_str("/ip6/2606:4700:4700::1111")?));
65 assert!(is_public_address(&Multiaddr::from_str(
66 "/ip6/2a00:1450:4001:830::200e"
67 )?));
68
69 assert!(!is_public_address(&Multiaddr::from_str("/ip6/::1")?));
71
72 assert!(!is_public_address(&Multiaddr::from_str("/ip6/fc00::1")?));
74 assert!(!is_public_address(&Multiaddr::from_str("/ip6/fd00::1")?));
75 assert!(!is_public_address(&Multiaddr::from_str(
76 "/ip6/fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
77 )?));
78
79 assert!(!is_public_address(&Multiaddr::from_str("/ip6/fe80::1")?));
81 assert!(!is_public_address(&Multiaddr::from_str(
82 "/ip6/fe80::dead:beef:cafe:babe"
83 )?));
84 assert!(!is_public_address(&Multiaddr::from_str(
85 "/ip6/febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
86 )?));
87
88 assert!(!is_public_address(&Multiaddr::from_str("/ip6/::")?));
90
91 Ok(())
92 }
93
94 #[test]
95 fn test_is_public_address_with_protocols() -> anyhow::Result<()> {
96 assert!(is_public_address(&Multiaddr::from_str("/ip4/8.8.8.8/tcp/4001")?));
98 assert!(is_public_address(&Multiaddr::from_str("/ip4/1.1.1.1/udp/30303")?));
99 assert!(is_public_address(&Multiaddr::from_str(
100 "/ip4/8.8.8.8/tcp/4001/p2p/12D3KooWEyoppNCUx8Yx66oV9fJnriXwCcXwDDUA2kj6vnc6iDEp"
101 )?));
102 assert!(is_public_address(&Multiaddr::from_str(
103 "/ip6/2001:4860:4860::8888/tcp/4001"
104 )?));
105 assert!(is_public_address(&Multiaddr::from_str(
106 "/ip6/2001:4860:4860::8888/udp/30303"
107 )?));
108 assert!(is_public_address(&Multiaddr::from_str(
109 "/ip6/2606:4700:4700::1111/tcp/443/wss"
110 )?));
111
112 assert!(!is_public_address(&Multiaddr::from_str("/ip4/192.168.0.1/tcp/4001")?));
114 assert!(!is_public_address(&Multiaddr::from_str("/ip4/127.0.0.1/tcp/8080")?));
115 assert!(!is_public_address(&Multiaddr::from_str("/ip4/10.0.0.1/tcp/8080")?));
116 assert!(!is_public_address(&Multiaddr::from_str("/ip4/10.1.0.1/tcp/8080")?));
117 assert!(!is_public_address(&Multiaddr::from_str("/ip4/169.254.1.1/udp/5060")?));
118 assert!(!is_public_address(&Multiaddr::from_str("/ip4/0.0.0.0/tcp/3000")?));
119 assert!(!is_public_address(&Multiaddr::from_str("/ip6/::1/tcp/4001")?));
120 assert!(!is_public_address(&Multiaddr::from_str("/ip6/fe80::1/udp/30303")?));
121 assert!(!is_public_address(&Multiaddr::from_str("/ip6/fc00::1/tcp/443")?));
122 assert!(!is_public_address(&Multiaddr::from_str("/ip6/::/tcp/8080")?));
123
124 Ok(())
125 }
126
127 #[test]
128 fn test_is_public_address_mixed_protocols() -> anyhow::Result<()> {
129 assert!(is_public_address(&Multiaddr::from_str("/dns/example.com")?));
131 assert!(is_public_address(&Multiaddr::from_str("/dns4/example.com/tcp/443")?));
132 assert!(is_public_address(&Multiaddr::from_str("/dns6/example.com/tcp/443")?));
133
134 Ok(())
135 }
136
137 #[test]
138 fn test_non_local_addresses() -> anyhow::Result<()> {
139 assert!(!is_public_address(&Multiaddr::from_str("/ip4/127.0.0.1")?));
140 assert!(!is_public_address(&Multiaddr::from_str("/ip4/192.168.1.1")?));
141 assert!(!is_public_address(&Multiaddr::from_str("/ip4/10.0.0.1")?));
142 assert!(!is_public_address(&Multiaddr::from_str("/ip4/172.16.0.1")?));
143 assert!(!is_public_address(&Multiaddr::from_str("/ip6/::1")?));
144 assert!(!is_public_address(&Multiaddr::from_str("/ip6/fe80::1")?));
145
146 Ok(())
147 }
148}