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