xref: /webrtc/util/src/vnet/net.rs (revision c9409ba1)
1 #[cfg(test)]
2 mod net_test;
3 
4 use super::conn_map::*;
5 use super::interface::*;
6 use crate::error::*;
7 use crate::vnet::chunk::Chunk;
8 use crate::vnet::conn::{ConnObserver, UdpConn};
9 use crate::vnet::router::*;
10 use crate::{conn, ifaces, Conn};
11 
12 use async_trait::async_trait;
13 use ipnet::IpNet;
14 use std::collections::HashMap;
15 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
16 use std::str::FromStr;
17 use std::sync::atomic::{AtomicU64, Ordering};
18 use std::sync::Arc;
19 use tokio::net::UdpSocket;
20 use tokio::sync::Mutex;
21 
22 pub(crate) const LO0_STR: &str = "lo0";
23 pub(crate) const UDP_STR: &str = "udp";
24 
25 lazy_static! {
26     pub static ref MAC_ADDR_COUNTER: AtomicU64 = AtomicU64::new(0xBEEFED910200);
27 }
28 
29 pub(crate) type HardwareAddr = Vec<u8>;
30 
new_mac_address() -> HardwareAddr31 pub(crate) fn new_mac_address() -> HardwareAddr {
32     let b = MAC_ADDR_COUNTER
33         .fetch_add(1, Ordering::SeqCst)
34         .to_be_bytes();
35     b[2..].to_vec()
36 }
37 
38 #[derive(Default)]
39 pub(crate) struct VNetInternal {
40     pub(crate) interfaces: Vec<Interface>,         // read-only
41     pub(crate) router: Option<Arc<Mutex<Router>>>, // read-only
42     pub(crate) udp_conns: UdpConnMap,              // read-only
43 }
44 
45 impl VNetInternal {
get_interface(&self, ifc_name: &str) -> Option<&Interface>46     fn get_interface(&self, ifc_name: &str) -> Option<&Interface> {
47         self.interfaces.iter().find(|ifc| ifc.name == ifc_name)
48     }
49 }
50 
51 #[async_trait]
52 impl ConnObserver for VNetInternal {
write(&self, c: Box<dyn Chunk + Send + Sync>) -> Result<()>53     async fn write(&self, c: Box<dyn Chunk + Send + Sync>) -> Result<()> {
54         if c.network() == UDP_STR && c.get_destination_ip().is_loopback() {
55             if let Some(conn) = self.udp_conns.find(&c.destination_addr()).await {
56                 let read_ch_tx = conn.get_inbound_ch();
57                 let ch_tx = read_ch_tx.lock().await;
58                 if let Some(tx) = &*ch_tx {
59                     let _ = tx.send(c).await;
60                 }
61             }
62             return Ok(());
63         }
64 
65         if let Some(r) = &self.router {
66             let p = r.lock().await;
67             p.push(c).await;
68             Ok(())
69         } else {
70             Err(Error::ErrNoRouterLinked)
71         }
72     }
73 
on_closed(&self, addr: SocketAddr)74     async fn on_closed(&self, addr: SocketAddr) {
75         let _ = self.udp_conns.delete(&addr).await;
76     }
77 
78     // This method determines the srcIP based on the dstIP when locIP
79     // is any IP address ("0.0.0.0" or "::"). If locIP is a non-any addr,
80     // this method simply returns locIP.
81     // caller must hold the mutex
determine_source_ip(&self, loc_ip: IpAddr, dst_ip: IpAddr) -> Option<IpAddr>82     fn determine_source_ip(&self, loc_ip: IpAddr, dst_ip: IpAddr) -> Option<IpAddr> {
83         if !loc_ip.is_unspecified() {
84             return Some(loc_ip);
85         }
86 
87         if dst_ip.is_loopback() {
88             let src_ip = if let Ok(src_ip) = IpAddr::from_str("127.0.0.1") {
89                 Some(src_ip)
90             } else {
91                 None
92             };
93             return src_ip;
94         }
95 
96         if let Some(ifc) = self.get_interface("eth0") {
97             for ipnet in ifc.addrs() {
98                 if (ipnet.addr().is_ipv4() && loc_ip.is_ipv4())
99                     || (ipnet.addr().is_ipv6() && loc_ip.is_ipv6())
100                 {
101                     return Some(ipnet.addr());
102                 }
103             }
104         }
105 
106         None
107     }
108 }
109 
110 #[derive(Default)]
111 pub struct VNet {
112     pub(crate) interfaces: Vec<Interface>, // read-only
113     pub(crate) static_ips: Vec<IpAddr>,    // read-only
114     pub(crate) vi: Arc<Mutex<VNetInternal>>,
115 }
116 
117 #[async_trait]
118 impl Nic for VNet {
get_interface(&self, ifc_name: &str) -> Option<Interface>119     async fn get_interface(&self, ifc_name: &str) -> Option<Interface> {
120         for ifc in &self.interfaces {
121             if ifc.name == ifc_name {
122                 return Some(ifc.clone());
123             }
124         }
125         None
126     }
127 
add_addrs_to_interface(&mut self, ifc_name: &str, addrs: &[IpNet]) -> Result<()>128     async fn add_addrs_to_interface(&mut self, ifc_name: &str, addrs: &[IpNet]) -> Result<()> {
129         {
130             let mut vi = self.vi.lock().await;
131             for ifc in &mut vi.interfaces {
132                 if ifc.name == ifc_name {
133                     for addr in addrs {
134                         ifc.add_addr(*addr);
135                     }
136                     break;
137                 }
138             }
139         }
140 
141         for ifc in &mut self.interfaces {
142             if ifc.name == ifc_name {
143                 for addr in addrs {
144                     ifc.add_addr(*addr);
145                 }
146                 return Ok(());
147             }
148         }
149 
150         Err(Error::ErrNotFound)
151     }
152 
set_router(&self, r: Arc<Mutex<Router>>) -> Result<()>153     async fn set_router(&self, r: Arc<Mutex<Router>>) -> Result<()> {
154         let mut vi = self.vi.lock().await;
155         vi.router = Some(r);
156 
157         Ok(())
158     }
159 
on_inbound_chunk(&self, c: Box<dyn Chunk + Send + Sync>)160     async fn on_inbound_chunk(&self, c: Box<dyn Chunk + Send + Sync>) {
161         if c.network() == UDP_STR {
162             let vi = self.vi.lock().await;
163             if let Some(conn) = vi.udp_conns.find(&c.destination_addr()).await {
164                 let read_ch_tx = conn.get_inbound_ch();
165                 let ch_tx = read_ch_tx.lock().await;
166                 if let Some(tx) = &*ch_tx {
167                     let _ = tx.send(c).await;
168                 }
169             }
170         }
171     }
172 
get_static_ips(&self) -> Vec<IpAddr>173     async fn get_static_ips(&self) -> Vec<IpAddr> {
174         self.static_ips.clone()
175     }
176 }
177 
178 impl VNet {
get_interfaces(&self) -> &[Interface]179     pub(crate) fn get_interfaces(&self) -> &[Interface] {
180         &self.interfaces
181     }
182 
183     // caller must hold the mutex
get_all_ipaddrs(&self, ipv6: bool) -> Vec<IpAddr>184     pub(crate) fn get_all_ipaddrs(&self, ipv6: bool) -> Vec<IpAddr> {
185         let mut ips = vec![];
186 
187         for ifc in &self.interfaces {
188             for ipnet in ifc.addrs() {
189                 if (ipv6 && ipnet.addr().is_ipv6()) || (!ipv6 && ipnet.addr().is_ipv4()) {
190                     ips.push(ipnet.addr());
191                 }
192             }
193         }
194 
195         ips
196     }
197 
198     // caller must hold the mutex
has_ipaddr(&self, ip: IpAddr) -> bool199     pub(crate) fn has_ipaddr(&self, ip: IpAddr) -> bool {
200         for ifc in &self.interfaces {
201             for ipnet in ifc.addrs() {
202                 let loc_ip = ipnet.addr();
203 
204                 match ip.to_string().as_str() {
205                     "0.0.0.0" => {
206                         if loc_ip.is_ipv4() {
207                             return true;
208                         }
209                     }
210                     "::" => {
211                         if loc_ip.is_ipv6() {
212                             return true;
213                         }
214                     }
215                     _ => {
216                         if loc_ip == ip {
217                             return true;
218                         }
219                     }
220                 }
221             }
222         }
223 
224         false
225     }
226 
227     // caller must hold the mutex
allocate_local_addr(&self, ip: IpAddr, port: u16) -> Result<()>228     pub(crate) async fn allocate_local_addr(&self, ip: IpAddr, port: u16) -> Result<()> {
229         // gather local IP addresses to bind
230         let mut ips = vec![];
231         if ip.is_unspecified() {
232             ips = self.get_all_ipaddrs(ip.is_ipv6());
233         } else if self.has_ipaddr(ip) {
234             ips.push(ip);
235         }
236 
237         if ips.is_empty() {
238             return Err(Error::ErrBindFailed);
239         }
240 
241         // check if all these transport addresses are not in use
242         for ip2 in ips {
243             let addr = SocketAddr::new(ip2, port);
244             let vi = self.vi.lock().await;
245             if vi.udp_conns.find(&addr).await.is_some() {
246                 return Err(Error::ErrAddressAlreadyInUse);
247             }
248         }
249 
250         Ok(())
251     }
252 
253     // caller must hold the mutex
assign_port(&self, ip: IpAddr, start: u16, end: u16) -> Result<u16>254     pub(crate) async fn assign_port(&self, ip: IpAddr, start: u16, end: u16) -> Result<u16> {
255         // choose randomly from the range between start and end (inclusive)
256         if end < start {
257             return Err(Error::ErrEndPortLessThanStart);
258         }
259 
260         let space = end + 1 - start;
261         let offset = rand::random::<u16>() % space;
262         for i in 0..space {
263             let port = ((offset + i) % space) + start;
264             let result = self.allocate_local_addr(ip, port).await;
265             if result.is_ok() {
266                 return Ok(port);
267             }
268         }
269 
270         Err(Error::ErrPortSpaceExhausted)
271     }
272 
resolve_addr(&self, use_ipv4: bool, address: &str) -> Result<SocketAddr>273     pub(crate) async fn resolve_addr(&self, use_ipv4: bool, address: &str) -> Result<SocketAddr> {
274         let v: Vec<&str> = address.splitn(2, ':').collect();
275         if v.len() != 2 {
276             return Err(Error::ErrAddrNotUdpAddr);
277         }
278         let (host, port) = (v[0], v[1]);
279 
280         // Check if host is a domain name
281         let ip: IpAddr = match host.parse() {
282             Ok(ip) => ip,
283             Err(_) => {
284                 let host = host.to_lowercase();
285                 if host == "localhost" {
286                     if use_ipv4 {
287                         Ipv4Addr::new(127, 0, 0, 1).into()
288                     } else {
289                         Ipv6Addr::from_str("::1")?.into()
290                     }
291                 } else {
292                     // host is a domain name. resolve IP address by the name
293                     let vi = self.vi.lock().await;
294                     if let Some(router) = &vi.router {
295                         let r = router.lock().await;
296                         let resolver = r.resolver.lock().await;
297                         if let Some(ip) = resolver.lookup(host).await {
298                             ip
299                         } else {
300                             return Err(Error::ErrNotFound);
301                         }
302                     } else {
303                         return Err(Error::ErrNoRouterLinked);
304                     }
305                 }
306             }
307         };
308 
309         let port: u16 = port.parse()?;
310 
311         let remote_addr = SocketAddr::new(ip, port);
312         if (use_ipv4 && remote_addr.is_ipv4()) || (!use_ipv4 && remote_addr.is_ipv6()) {
313             Ok(remote_addr)
314         } else {
315             Err(Error::Other(format!(
316                 "No available {} IP address found!",
317                 if use_ipv4 { "ipv4" } else { "ipv6" },
318             )))
319         }
320     }
321 
322     // caller must hold the mutex
bind( &self, mut local_addr: SocketAddr, ) -> Result<Arc<dyn Conn + Send + Sync>>323     pub(crate) async fn bind(
324         &self,
325         mut local_addr: SocketAddr,
326     ) -> Result<Arc<dyn Conn + Send + Sync>> {
327         // validate address. do we have that address?
328         if !self.has_ipaddr(local_addr.ip()) {
329             return Err(Error::ErrCantAssignRequestedAddr);
330         }
331 
332         if local_addr.port() == 0 {
333             // choose randomly from the range between 5000 and 5999
334             local_addr.set_port(self.assign_port(local_addr.ip(), 5000, 5999).await?);
335         } else {
336             let vi = self.vi.lock().await;
337             if vi.udp_conns.find(&local_addr).await.is_some() {
338                 return Err(Error::ErrAddressAlreadyInUse);
339             }
340         }
341 
342         let v = Arc::clone(&self.vi) as Arc<Mutex<dyn ConnObserver + Send + Sync>>;
343         let conn = Arc::new(UdpConn::new(local_addr, None, v));
344 
345         {
346             let vi = self.vi.lock().await;
347             vi.udp_conns.insert(Arc::clone(&conn)).await?;
348         }
349 
350         Ok(conn)
351     }
352 
dail( &self, use_ipv4: bool, remote_addr: &str, ) -> Result<Arc<dyn Conn + Send + Sync>>353     pub(crate) async fn dail(
354         &self,
355         use_ipv4: bool,
356         remote_addr: &str,
357     ) -> Result<Arc<dyn Conn + Send + Sync>> {
358         let rem_addr = self.resolve_addr(use_ipv4, remote_addr).await?;
359 
360         // Determine source address
361         let src_ip = {
362             let vi = self.vi.lock().await;
363             let any_ip = if use_ipv4 {
364                 Ipv4Addr::new(0, 0, 0, 0).into()
365             } else {
366                 Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).into()
367             };
368             if let Some(src_ip) = vi.determine_source_ip(any_ip, rem_addr.ip()) {
369                 src_ip
370             } else {
371                 any_ip
372             }
373         };
374 
375         let loc_addr = SocketAddr::new(src_ip, 0);
376 
377         let conn = self.bind(loc_addr).await?;
378         conn.connect(rem_addr).await?;
379 
380         Ok(conn)
381     }
382 }
383 
384 // NetConfig is a bag of configuration parameters passed to NewNet().
385 #[derive(Debug, Default)]
386 pub struct NetConfig {
387     // static_ips is an array of static IP addresses to be assigned for this Net.
388     // If no static IP address is given, the router will automatically assign
389     // an IP address.
390     pub static_ips: Vec<String>,
391 
392     // static_ip is deprecated. Use static_ips.
393     pub static_ip: String,
394 }
395 
396 // Net represents a local network stack euivalent to a set of layers from NIC
397 // up to the transport (UDP / TCP) layer.
398 pub enum Net {
399     VNet(Arc<Mutex<VNet>>),
400     Ifs(Vec<Interface>),
401 }
402 
403 impl Net {
404     // NewNet creates an instance of Net.
405     // If config is nil, the virtual network is disabled. (uses corresponding
406     // net.Xxxx() operations.
407     // By design, it always have lo0 and eth0 interfaces.
408     // The lo0 has the address 127.0.0.1 assigned by default.
409     // IP address for eth0 will be assigned when this Net is added to a router.
new(config: Option<NetConfig>) -> Self410     pub fn new(config: Option<NetConfig>) -> Self {
411         if let Some(config) = config {
412             let mut lo0 = Interface::new(LO0_STR.to_owned(), vec![]);
413             if let Ok(ipnet) = Interface::convert(
414                 SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), 0),
415                 Some(SocketAddr::new(Ipv4Addr::new(255, 0, 0, 0).into(), 0)),
416             ) {
417                 lo0.add_addr(ipnet);
418             }
419 
420             let eth0 = Interface::new("eth0".to_owned(), vec![]);
421 
422             let mut static_ips = vec![];
423             for ip_str in &config.static_ips {
424                 if let Ok(ip) = IpAddr::from_str(ip_str) {
425                     static_ips.push(ip);
426                 }
427             }
428             if !config.static_ip.is_empty() {
429                 if let Ok(ip) = IpAddr::from_str(&config.static_ip) {
430                     static_ips.push(ip);
431                 }
432             }
433 
434             let vnet = VNet {
435                 interfaces: vec![lo0.clone(), eth0.clone()],
436                 static_ips,
437                 vi: Arc::new(Mutex::new(VNetInternal {
438                     interfaces: vec![lo0, eth0],
439                     router: None,
440                     udp_conns: UdpConnMap::new(),
441                 })),
442             };
443 
444             Net::VNet(Arc::new(Mutex::new(vnet)))
445         } else {
446             let interfaces = match ifaces::ifaces() {
447                 Ok(ifs) => ifs,
448                 Err(_) => vec![],
449             };
450 
451             let mut m: HashMap<String, Vec<IpNet>> = HashMap::new();
452             for iface in interfaces {
453                 if let Some(addrs) = m.get_mut(&iface.name) {
454                     if let Some(addr) = iface.addr {
455                         if let Ok(inet) = Interface::convert(addr, iface.mask) {
456                             addrs.push(inet);
457                         }
458                     }
459                 } else if let Some(addr) = iface.addr {
460                     if let Ok(inet) = Interface::convert(addr, iface.mask) {
461                         m.insert(iface.name, vec![inet]);
462                     }
463                 }
464             }
465 
466             let mut ifs = vec![];
467             for (name, addrs) in m.into_iter() {
468                 ifs.push(Interface::new(name, addrs));
469             }
470 
471             Net::Ifs(ifs)
472         }
473     }
474 
475     // Interfaces returns a list of the system's network interfaces.
get_interfaces(&self) -> Vec<Interface>476     pub async fn get_interfaces(&self) -> Vec<Interface> {
477         match self {
478             Net::VNet(vnet) => {
479                 let net = vnet.lock().await;
480                 net.get_interfaces().to_vec()
481             }
482             Net::Ifs(ifs) => ifs.clone(),
483         }
484     }
485 
486     // InterfaceByName returns the interface specified by name.
get_interface(&self, ifc_name: &str) -> Option<Interface>487     pub async fn get_interface(&self, ifc_name: &str) -> Option<Interface> {
488         match self {
489             Net::VNet(vnet) => {
490                 let net = vnet.lock().await;
491                 net.get_interface(ifc_name).await
492             }
493             Net::Ifs(ifs) => {
494                 for ifc in ifs {
495                     if ifc.name == ifc_name {
496                         return Some(ifc.clone());
497                     }
498                 }
499                 None
500             }
501         }
502     }
503 
504     // IsVirtual tests if the virtual network is enabled.
is_virtual(&self) -> bool505     pub fn is_virtual(&self) -> bool {
506         match self {
507             Net::VNet(_) => true,
508             Net::Ifs(_) => false,
509         }
510     }
511 
resolve_addr(&self, use_ipv4: bool, address: &str) -> Result<SocketAddr>512     pub async fn resolve_addr(&self, use_ipv4: bool, address: &str) -> Result<SocketAddr> {
513         match self {
514             Net::VNet(vnet) => {
515                 let net = vnet.lock().await;
516                 net.resolve_addr(use_ipv4, address).await
517             }
518             Net::Ifs(_) => Ok(conn::lookup_host(use_ipv4, address).await?),
519         }
520     }
521 
bind(&self, addr: SocketAddr) -> Result<Arc<dyn Conn + Send + Sync>>522     pub async fn bind(&self, addr: SocketAddr) -> Result<Arc<dyn Conn + Send + Sync>> {
523         match self {
524             Net::VNet(vnet) => {
525                 let net = vnet.lock().await;
526                 net.bind(addr).await
527             }
528             Net::Ifs(_) => Ok(Arc::new(UdpSocket::bind(addr).await?)),
529         }
530     }
531 
dail( &self, use_ipv4: bool, remote_addr: &str, ) -> Result<Arc<dyn Conn + Send + Sync>>532     pub async fn dail(
533         &self,
534         use_ipv4: bool,
535         remote_addr: &str,
536     ) -> Result<Arc<dyn Conn + Send + Sync>> {
537         match self {
538             Net::VNet(vnet) => {
539                 let net = vnet.lock().await;
540                 net.dail(use_ipv4, remote_addr).await
541             }
542             Net::Ifs(_) => {
543                 let any_ip = if use_ipv4 {
544                     Ipv4Addr::new(0, 0, 0, 0).into()
545                 } else {
546                     Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0).into()
547                 };
548                 let local_addr = SocketAddr::new(any_ip, 0);
549 
550                 let conn = UdpSocket::bind(local_addr).await?;
551                 conn.connect(remote_addr).await?;
552 
553                 Ok(Arc::new(conn))
554             }
555         }
556     }
557 
get_nic(&self) -> Result<Arc<Mutex<dyn Nic + Send + Sync>>>558     pub fn get_nic(&self) -> Result<Arc<Mutex<dyn Nic + Send + Sync>>> {
559         match self {
560             Net::VNet(vnet) => Ok(Arc::clone(vnet) as Arc<Mutex<dyn Nic + Send + Sync>>),
561             Net::Ifs(_) => Err(Error::ErrVnetDisabled),
562         }
563     }
564 }
565