xref: /webrtc/ice/src/network_type/mod.rs (revision 5d8fe953)
1 #[cfg(test)]
2 mod network_type_test;
3 
4 use crate::error::*;
5 
6 use serde::{Deserialize, Serialize};
7 use std::fmt;
8 use std::net::IpAddr;
9 
10 pub(crate) const UDP: &str = "udp";
11 pub(crate) const TCP: &str = "tcp";
12 
13 #[must_use]
supported_network_types() -> Vec<NetworkType>14 pub fn supported_network_types() -> Vec<NetworkType> {
15     vec![
16         NetworkType::Udp4,
17         NetworkType::Udp6,
18         //NetworkType::TCP4,
19         //NetworkType::TCP6,
20     ]
21 }
22 
23 /// Represents the type of network.
24 #[derive(PartialEq, Debug, Copy, Clone, Eq, Hash, Serialize, Deserialize)]
25 pub enum NetworkType {
26     #[serde(rename = "unspecified")]
27     Unspecified,
28 
29     /// Indicates UDP over IPv4.
30     #[serde(rename = "udp4")]
31     Udp4,
32 
33     /// Indicates UDP over IPv6.
34     #[serde(rename = "udp6")]
35     Udp6,
36 
37     /// Indicates TCP over IPv4.
38     #[serde(rename = "tcp4")]
39     Tcp4,
40 
41     /// Indicates TCP over IPv6.
42     #[serde(rename = "tcp6")]
43     Tcp6,
44 }
45 
46 impl From<u8> for NetworkType {
from(v: u8) -> Self47     fn from(v: u8) -> Self {
48         match v {
49             1 => Self::Udp4,
50             2 => Self::Udp6,
51             3 => Self::Tcp4,
52             4 => Self::Tcp6,
53             _ => Self::Unspecified,
54         }
55     }
56 }
57 
58 impl fmt::Display for NetworkType {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result59     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60         let s = match *self {
61             Self::Udp4 => "udp4",
62             Self::Udp6 => "udp6",
63             Self::Tcp4 => "tcp4",
64             Self::Tcp6 => "tcp6",
65             Self::Unspecified => "unspecified",
66         };
67         write!(f, "{s}")
68     }
69 }
70 
71 impl Default for NetworkType {
default() -> Self72     fn default() -> Self {
73         Self::Unspecified
74     }
75 }
76 
77 impl NetworkType {
78     /// Returns true when network is UDP4 or UDP6.
79     #[must_use]
is_udp(self) -> bool80     pub fn is_udp(self) -> bool {
81         self == Self::Udp4 || self == Self::Udp6
82     }
83 
84     /// Returns true when network is TCP4 or TCP6.
85     #[must_use]
is_tcp(self) -> bool86     pub fn is_tcp(self) -> bool {
87         self == Self::Tcp4 || self == Self::Tcp6
88     }
89 
90     /// Returns the short network description.
91     #[must_use]
network_short(self) -> String92     pub fn network_short(self) -> String {
93         match self {
94             Self::Udp4 | Self::Udp6 => UDP.to_owned(),
95             Self::Tcp4 | Self::Tcp6 => TCP.to_owned(),
96             Self::Unspecified => "Unspecified".to_owned(),
97         }
98     }
99 
100     /// Returns true if the network is reliable.
101     #[must_use]
is_reliable(self) -> bool102     pub const fn is_reliable(self) -> bool {
103         match self {
104             Self::Tcp4 | Self::Tcp6 => true,
105             Self::Udp4 | Self::Udp6 | Self::Unspecified => false,
106         }
107     }
108 
109     /// Returns whether the network type is IPv4 or not.
110     #[must_use]
is_ipv4(self) -> bool111     pub const fn is_ipv4(self) -> bool {
112         match self {
113             Self::Udp4 | Self::Tcp4 => true,
114             Self::Udp6 | Self::Tcp6 | Self::Unspecified => false,
115         }
116     }
117 
118     /// Returns whether the network type is IPv6 or not.
119     #[must_use]
is_ipv6(self) -> bool120     pub const fn is_ipv6(self) -> bool {
121         match self {
122             Self::Udp6 | Self::Tcp6 => true,
123             Self::Udp4 | Self::Tcp4 | Self::Unspecified => false,
124         }
125     }
126 }
127 
128 /// Determines the type of network based on the short network string and an IP address.
determine_network_type(network: &str, ip: &IpAddr) -> Result<NetworkType>129 pub(crate) fn determine_network_type(network: &str, ip: &IpAddr) -> Result<NetworkType> {
130     let ipv4 = ip.is_ipv4();
131     let net = network.to_lowercase();
132     if net.starts_with(UDP) {
133         if ipv4 {
134             Ok(NetworkType::Udp4)
135         } else {
136             Ok(NetworkType::Udp6)
137         }
138     } else if net.starts_with(TCP) {
139         if ipv4 {
140             Ok(NetworkType::Tcp4)
141         } else {
142             Ok(NetworkType::Tcp6)
143         }
144     } else {
145         Err(Error::ErrDetermineNetworkType)
146     }
147 }
148