1use std::{
4 io,
5 net::{Ipv4Addr, Ipv6Addr, SocketAddr},
6 sync::{
7 Arc,
8 atomic::{AtomicU16, Ordering},
9 },
10};
11
12use device::BufferDevice;
13use futures::Future;
14use reactor::Reactor;
15pub use smoltcp;
16use smoltcp::{
17 iface::{Config, Interface, Routes},
18 time::{Duration, Instant},
19 wire::{HardwareAddress, IpAddress, IpCidr, IpProtocol, IpVersion},
20};
21pub use socket::{RawSocket, TcpListener, TcpStream, UdpSocket};
22pub use socket_allocator::BufferSize;
23use tokio::sync::Notify;
24
25pub mod device;
27mod reactor;
28mod socket;
29mod socket_allocator;
30
31pub const FOREVER: Instant =
34 Instant::from_micros_const(i64::max_value() - Duration::from_millis(60_000).micros() as i64);
35
36pub struct Neighbor {
37 pub protocol_addr: IpAddress,
38 pub hardware_addr: HardwareAddress,
39 pub timestamp: Instant,
40}
41
42#[non_exhaustive]
46pub struct NetConfig {
47 pub interface_config: Config,
48 pub ip_addr: IpCidr,
49 pub gateway: Vec<IpAddress>,
50 pub buffer_size: BufferSize,
51}
52
53impl NetConfig {
54 pub fn new(interface_config: Config, ip_addr: IpCidr, gateway: Vec<IpAddress>) -> Self {
55 Self {
56 interface_config,
57 ip_addr,
58 gateway,
59 buffer_size: Default::default(),
60 }
61 }
62}
63
64pub struct Net {
69 reactor: Arc<Reactor>,
70 ip_addr: IpCidr,
71 from_port: AtomicU16,
72 stopper: Arc<Notify>,
73}
74
75impl Net {
76 pub fn new<D: device::AsyncDevice + 'static>(device: D, config: NetConfig) -> Net {
78 let (net, fut) = Self::new2(device, config);
79 tokio::spawn(fut);
80 net
81 }
82
83 fn new2<D: device::AsyncDevice + 'static>(
84 device: D,
85 config: NetConfig,
86 ) -> (Net, impl Future<Output = io::Result<()>> + Send) {
87 let mut buffer_device = BufferDevice::new(device.capabilities().clone());
88 let mut iface = Interface::new(config.interface_config, &mut buffer_device, Instant::now());
89 let ip_addr = config.ip_addr;
90 iface.update_ip_addrs(|ip_addrs| {
91 ip_addrs.push(ip_addr).unwrap();
92 });
93 for gateway in config.gateway {
94 match gateway {
95 IpAddress::Ipv4(v4) => {
96 iface.routes_mut().add_default_ipv4_route(v4).unwrap();
97 }
98 IpAddress::Ipv6(v6) => {
99 iface.routes_mut().add_default_ipv6_route(v6).unwrap();
100 }
101 #[allow(unreachable_patterns)]
102 _ => panic!("Unsupported address"),
103 };
104 }
105
106 let stopper = Arc::new(Notify::new());
107 let (reactor, fut) = Reactor::new(
108 device,
109 iface,
110 buffer_device,
111 config.buffer_size,
112 stopper.clone(),
113 );
114
115 (
116 Net {
117 reactor: Arc::new(reactor),
118 ip_addr: config.ip_addr,
119 from_port: AtomicU16::new(10001),
120 stopper,
121 },
122 fut,
123 )
124 }
125 fn get_port(&self) -> u16 {
126 self.from_port
127 .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| {
128 Some(if x > 60000 { 10000 } else { x + 1 })
129 })
130 .unwrap()
131 }
132 pub async fn tcp_bind(&self, addr: SocketAddr) -> io::Result<TcpListener> {
134 let addr = self.set_address(addr);
135 TcpListener::new(self.reactor.clone(), addr.into()).await
136 }
137 pub async fn tcp_connect(&self, addr: SocketAddr) -> io::Result<TcpStream> {
139 TcpStream::connect(
140 self.reactor.clone(),
141 (self.ip_addr.address(), self.get_port()).into(),
142 addr.into(),
143 )
144 .await
145 }
146 pub fn tcp_connect_lazy(
147 &self,
148 addr: SocketAddr,
149 ) -> (
150 SocketAddr,
151 impl Future<Output = Result<TcpStream, std::io::Error>>,
152 ) {
153 let local_endpoint: SocketAddr = (self.ip_addr.address(), self.get_port()).into();
154 let future = TcpStream::connect(self.reactor.clone(), local_endpoint.into(), addr.into());
155 (local_endpoint, future)
156 }
157 pub async fn udp_bind(&self, addr: SocketAddr) -> io::Result<UdpSocket> {
159 let addr = self.set_address(addr);
160 UdpSocket::new(self.reactor.clone(), addr.into()).await
161 }
162 pub async fn raw_socket(
164 &self,
165 ip_version: IpVersion,
166 ip_protocol: IpProtocol,
167 ) -> io::Result<RawSocket> {
168 RawSocket::new(self.reactor.clone(), ip_version, ip_protocol).await
169 }
170 fn set_address(&self, mut addr: SocketAddr) -> SocketAddr {
171 if addr.ip().is_unspecified() {
172 addr.set_ip(match self.ip_addr.address() {
173 IpAddress::Ipv4(ip) => Ipv4Addr::from(ip).into(),
174 IpAddress::Ipv6(ip) => Ipv6Addr::from(ip).into(),
175 #[allow(unreachable_patterns)]
176 _ => panic!("address must not be unspecified"),
177 });
178 }
179 if addr.port() == 0 {
180 addr.set_port(self.get_port());
181 }
182 addr
183 }
184
185 pub fn set_any_ip(&self, any_ip: bool) {
187 let iface = self.reactor.iface().clone();
188 let mut iface: parking_lot::lock_api::MutexGuard<'_, parking_lot::RawMutex, Interface> =
189 iface.lock();
190 iface.set_any_ip(any_ip);
191 }
192
193 pub fn any_ip(&self) -> bool {
195 let iface = self.reactor.iface().clone();
196 let iface = iface.lock();
197 iface.any_ip()
198 }
199
200 pub fn routes<F: FnOnce(&Routes)>(&self, f: F) {
201 let iface = self.reactor.iface().clone();
202 let iface = iface.lock();
203 let routes = iface.routes();
204 f(routes)
205 }
206
207 pub fn routes_mut<F: FnOnce(&mut Routes)>(&self, f: F) {
208 let iface = self.reactor.iface().clone();
209 let mut iface = iface.lock();
210 let routes = iface.routes_mut();
211 f(routes)
212 }
213}
214
215impl Drop for Net {
216 fn drop(&mut self) {
217 self.stopper.notify_waiters()
218 }
219}