rust_p2p_core/nat/
mod.rs

1use crate::extend::addr::is_ipv6_global;
2use serde::{Deserialize, Serialize};
3use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
4
5#[derive(Debug, PartialEq, Eq, Clone, Copy, Serialize, Deserialize, Default)]
6pub enum NatType {
7    #[default]
8    Cone,
9    Symmetric,
10}
11
12impl NatType {
13    #[inline]
14    pub fn is_cone(&self) -> bool {
15        self == &NatType::Cone
16    }
17    #[inline]
18    pub fn is_symmetric(&self) -> bool {
19        self == &NatType::Symmetric
20    }
21}
22
23#[derive(Clone, Debug, Serialize, Deserialize)]
24pub struct NatInfo {
25    /// nat type of the network
26    pub nat_type: NatType,
27    /// the set of public Ipv4
28    pub public_ips: Vec<Ipv4Addr>,
29    /// the set of public ports mapped from the nat
30    pub public_udp_ports: Vec<u16>,
31    /// the set of mapped addresses where `TCP` serves on
32    pub mapping_tcp_addr: Vec<SocketAddr>,
33    /// the set of mapped addresses where `UDP` serves on
34    pub mapping_udp_addr: Vec<SocketAddr>,
35    /// The predicted range of public ports, it is used when the nat_type is symmetric
36    pub public_port_range: u16,
37    /// local IP address
38    pub local_ipv4: Ipv4Addr,
39    /// The public IPv6 address
40    pub ipv6: Option<Ipv6Addr>,
41    /// The local ports where the `UDP` services bind
42    pub local_udp_ports: Vec<u16>,
43    /// The local ports where the `TCP` services bind
44    pub local_tcp_port: u16,
45    /// The public port of `TCP` service, which works when there is either `nat1` or no `nat` exists
46    pub public_tcp_port: u16,
47}
48impl NatInfo {
49    pub(crate) fn flag(&self) -> Option<SocketAddr> {
50        let vec = self.public_ipv4_addr();
51        if let Some(v) = vec.first() {
52            return Some(*v);
53        }
54        let vec = self.public_ipv4_tcp();
55        if let Some(v) = vec.first() {
56            return Some(*v);
57        }
58        let vec = self.local_ipv4_addrs();
59        if let Some(v) = vec.first() {
60            return Some(*v);
61        }
62        let option = self.local_ipv4_tcp();
63        if option.is_some() {
64            return option;
65        }
66        None
67    }
68    pub fn ipv6_udp_addr(&self) -> Vec<SocketAddr> {
69        if let Some(ipv6) = self.ipv6 {
70            if is_ipv6_global(&ipv6) {
71                return self
72                    .local_udp_ports
73                    .iter()
74                    .map(|&port| SocketAddrV6::new(ipv6, port, 0, 0).into())
75                    .collect();
76            }
77        }
78        vec![]
79    }
80    pub fn ipv6_tcp_addr(&self) -> Option<SocketAddr> {
81        self.ipv6
82            .map(|ipv6| SocketAddrV6::new(ipv6, self.local_tcp_port, 0, 0).into())
83    }
84    pub fn public_ipv4_addr(&self) -> Vec<SocketAddr> {
85        if self.public_ips.is_empty() || self.public_udp_ports.is_empty() {
86            return vec![];
87        }
88        if self.public_ips.len() == 1 {
89            let ip = self.public_ips[0];
90            return self
91                .public_udp_ports
92                .iter()
93                .map(|&port| SocketAddrV4::new(ip, port).into())
94                .collect();
95        }
96        let port = self.public_udp_ports[0];
97        self.public_ips
98            .iter()
99            .map(|&ip| SocketAddrV4::new(ip, port).into())
100            .collect()
101    }
102    pub fn local_ipv4_addrs(&self) -> Vec<SocketAddr> {
103        if self.local_ipv4.is_unspecified()
104            || self.local_ipv4.is_multicast()
105            || self.local_ipv4.is_broadcast()
106        {
107            return vec![];
108        }
109        self.local_udp_ports
110            .iter()
111            .map(|&port| SocketAddrV4::new(self.local_ipv4, port).into())
112            .collect()
113    }
114    pub fn local_ipv4_tcp(&self) -> Option<SocketAddr> {
115        if self.local_ipv4.is_unspecified()
116            || self.local_ipv4.is_multicast()
117            || self.local_ipv4.is_broadcast()
118            || self.local_tcp_port == 0
119        {
120            return None;
121        }
122        Some(SocketAddrV4::new(self.local_ipv4, self.local_tcp_port).into())
123    }
124    pub fn public_ipv4_tcp(&self) -> Vec<SocketAddr> {
125        if self.public_tcp_port == 0 {
126            return vec![];
127        }
128        self.public_ips
129            .iter()
130            .map(|&ip| SocketAddrV4::new(ip, self.public_tcp_port).into())
131            .collect()
132    }
133}