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