Răsfoiți Sursa

Merge pull request #619 from smoltcp-rs/ownership-refactor

Interface ownership refactor
Dario Nieuwenhuis 2 ani în urmă
părinte
comite
19a78bb577

+ 12 - 10
examples/benchmark.rs

@@ -11,7 +11,7 @@ use std::os::unix::io::AsRawFd;
 use std::sync::atomic::{AtomicBool, Ordering};
 use std::thread;
 
-use smoltcp::iface::{InterfaceBuilder, NeighborCache};
+use smoltcp::iface::{InterfaceBuilder, NeighborCache, SocketSet};
 use smoltcp::phy::{wait as phy_wait, Device, Medium};
 use smoltcp::socket::tcp;
 use smoltcp::time::{Duration, Instant};
@@ -74,7 +74,8 @@ fn main() {
     let mut matches = utils::parse_options(&opts, free);
     let device = utils::parse_tuntap_options(&mut matches);
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
     let mode = match matches.free[0].as_ref() {
         "reader" => Client::Reader,
         "writer" => Client::Writer,
@@ -94,23 +95,24 @@ fn main() {
     let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
     let ip_addrs = [IpCidr::new(IpAddress::v4(192, 168, 69, 1), 24)];
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![]).ip_addrs(ip_addrs);
+    let mut builder = InterfaceBuilder::new().ip_addrs(ip_addrs);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(ethernet_addr.into())
             .neighbor_cache(neighbor_cache);
     }
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
-    let tcp1_handle = iface.add_socket(tcp1_socket);
-    let tcp2_handle = iface.add_socket(tcp2_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let tcp1_handle = sockets.add(tcp1_socket);
+    let tcp2_handle = sockets.add(tcp2_socket);
     let default_timeout = Some(Duration::from_millis(1000));
 
     thread::spawn(move || client(mode));
     let mut processed = 0;
     while !CLIENT_DONE.load(Ordering::SeqCst) {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
@@ -118,7 +120,7 @@ fn main() {
         }
 
         // tcp:1234: emit data
-        let socket = iface.get_socket::<tcp::Socket>(tcp1_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp1_handle);
         if !socket.is_open() {
             socket.listen(1234).unwrap();
         }
@@ -136,7 +138,7 @@ fn main() {
         }
 
         // tcp:1235: sink data
-        let socket = iface.get_socket::<tcp::Socket>(tcp2_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp2_handle);
         if !socket.is_open() {
             socket.listen(1235).unwrap();
         }
@@ -153,7 +155,7 @@ fn main() {
             }
         }
 
-        match iface.poll_at(timestamp) {
+        match iface.poll_at(timestamp, &sockets) {
             Some(poll_at) if timestamp < poll_at => {
                 phy_wait(fd, Some(poll_at - timestamp)).expect("wait error");
             }

+ 14 - 12
examples/client.rs

@@ -5,7 +5,7 @@ use std::collections::BTreeMap;
 use std::os::unix::io::AsRawFd;
 use std::str::{self, FromStr};
 
-use smoltcp::iface::{InterfaceBuilder, NeighborCache, Routes};
+use smoltcp::iface::{InterfaceBuilder, NeighborCache, Routes, SocketSet};
 use smoltcp::phy::{wait as phy_wait, Device, Medium};
 use smoltcp::socket::tcp;
 use smoltcp::time::Instant;
@@ -24,7 +24,8 @@ fn main() {
     let device = utils::parse_tuntap_options(&mut matches);
 
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
     let address = IpAddress::from_str(&matches.free[0]).expect("invalid address format");
     let port = u16::from_str(&matches.free[1]).expect("invalid port format");
 
@@ -42,32 +43,33 @@ fn main() {
     routes.add_default_ipv4_route(default_v4_gw).unwrap();
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
-        .ip_addrs(ip_addrs)
-        .routes(routes);
+    let mut builder = InterfaceBuilder::new().ip_addrs(ip_addrs).routes(routes);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(ethernet_addr.into())
             .neighbor_cache(neighbor_cache);
     }
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
-    let tcp_handle = iface.add_socket(tcp_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let tcp_handle = sockets.add(tcp_socket);
 
-    let (socket, cx) = iface.get_socket_and_context::<tcp::Socket>(tcp_handle);
-    socket.connect(cx, (address, port), 49500).unwrap();
+    let socket = sockets.get_mut::<tcp::Socket>(tcp_handle);
+    socket
+        .connect(iface.context(), (address, port), 49500)
+        .unwrap();
 
     let mut tcp_active = false;
     loop {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        let socket = iface.get_socket::<tcp::Socket>(tcp_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp_handle);
         if socket.is_active() && !tcp_active {
             debug!("connected");
         } else if !socket.is_active() && tcp_active {
@@ -104,6 +106,6 @@ fn main() {
             socket.close();
         }
 
-        phy_wait(fd, iface.poll_delay(timestamp)).expect("wait error");
+        phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
     }
 }

+ 11 - 14
examples/dhcp_client.rs

@@ -5,7 +5,7 @@ use log::*;
 use std::collections::BTreeMap;
 use std::os::unix::io::AsRawFd;
 
-use smoltcp::iface::{Interface, InterfaceBuilder, NeighborCache, Routes};
+use smoltcp::iface::{Interface, InterfaceBuilder, NeighborCache, Routes, SocketSet};
 use smoltcp::socket::dhcpv4;
 use smoltcp::time::Instant;
 use smoltcp::wire::{EthernetAddress, IpCidr, Ipv4Address, Ipv4Cidr};
@@ -25,7 +25,8 @@ fn main() {
     let mut matches = utils::parse_options(&opts, free);
     let device = utils::parse_tuntap_options(&mut matches);
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
 
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
     let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
@@ -34,15 +35,13 @@ fn main() {
     let routes = Routes::new(&mut routes_storage[..]);
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
-        .ip_addrs(ip_addrs)
-        .routes(routes);
+    let mut builder = InterfaceBuilder::new().ip_addrs(ip_addrs).routes(routes);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(ethernet_addr.into())
             .neighbor_cache(neighbor_cache);
     }
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
     let mut dhcp_socket = dhcpv4::Socket::new();
 
@@ -52,15 +51,16 @@ fn main() {
     // IMPORTANT: This should be removed in production.
     dhcp_socket.set_max_lease_duration(Some(Duration::from_secs(10)));
 
-    let dhcp_handle = iface.add_socket(dhcp_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let dhcp_handle = sockets.add(dhcp_socket);
 
     loop {
         let timestamp = Instant::now();
-        if let Err(e) = iface.poll(timestamp) {
+        if let Err(e) = iface.poll(timestamp, &mut device, &mut sockets) {
             debug!("poll error: {}", e);
         }
 
-        let event = iface.get_socket::<dhcpv4::Socket>(dhcp_handle).poll();
+        let event = sockets.get_mut::<dhcpv4::Socket>(dhcp_handle).poll();
         match event {
             None => {}
             Some(dhcpv4::Event::Configured(config)) => {
@@ -90,14 +90,11 @@ fn main() {
             }
         }
 
-        phy_wait(fd, iface.poll_delay(timestamp)).expect("wait error");
+        phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
     }
 }
 
-fn set_ipv4_addr<DeviceT>(iface: &mut Interface<'_, DeviceT>, cidr: Ipv4Cidr)
-where
-    DeviceT: for<'d> Device<'d>,
-{
+fn set_ipv4_addr(iface: &mut Interface<'_>, cidr: Ipv4Cidr) {
     iface.update_ip_addrs(|addrs| {
         let dest = addrs.iter_mut().next().unwrap();
         *dest = IpCidr::Ipv4(cidr);

+ 13 - 13
examples/dns.rs

@@ -7,7 +7,7 @@ extern crate smoltcp;
 
 mod utils;
 
-use smoltcp::iface::{InterfaceBuilder, NeighborCache, Routes};
+use smoltcp::iface::{InterfaceBuilder, NeighborCache, Routes, SocketSet};
 use smoltcp::phy::Device;
 use smoltcp::phy::{wait as phy_wait, Medium};
 use smoltcp::socket::dns::{self, GetQueryResultError};
@@ -29,7 +29,8 @@ fn main() {
     let mut matches = utils::parse_options(&opts, free);
     let device = utils::parse_tuntap_options(&mut matches);
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
     let name = &matches.free[0];
 
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
@@ -55,34 +56,33 @@ fn main() {
     routes.add_default_ipv6_route(default_v6_gw).unwrap();
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
-        .ip_addrs(ip_addrs)
-        .routes(routes);
+    let mut builder = InterfaceBuilder::new().ip_addrs(ip_addrs).routes(routes);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(HardwareAddress::Ethernet(ethernet_addr))
             .neighbor_cache(neighbor_cache);
     }
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
-    let dns_handle = iface.add_socket(dns_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let dns_handle = sockets.add(dns_socket);
 
-    let (socket, cx) = iface.get_socket_and_context::<dns::Socket>(dns_handle);
-    let query = socket.start_query(cx, name).unwrap();
+    let socket = sockets.get_mut::<dns::Socket>(dns_handle);
+    let query = socket.start_query(iface.context(), name).unwrap();
 
     loop {
         let timestamp = Instant::now();
         debug!("timestamp {:?}", timestamp);
 
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        match iface
-            .get_socket::<dns::Socket>(dns_handle)
+        match sockets
+            .get_mut::<dns::Socket>(dns_handle)
             .get_query_result(query)
         {
             Ok(addrs) => {
@@ -93,6 +93,6 @@ fn main() {
             Err(e) => panic!("query failed: {:?}", e),
         }
 
-        phy_wait(fd, iface.poll_delay(timestamp)).expect("wait error");
+        phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
     }
 }

+ 11 - 10
examples/httpclient.rs

@@ -6,7 +6,7 @@ use std::os::unix::io::AsRawFd;
 use std::str::{self, FromStr};
 use url::Url;
 
-use smoltcp::iface::{InterfaceBuilder, NeighborCache, Routes};
+use smoltcp::iface::{InterfaceBuilder, NeighborCache, Routes, SocketSet};
 use smoltcp::phy::{wait as phy_wait, Device, Medium};
 use smoltcp::socket::tcp;
 use smoltcp::time::Instant;
@@ -24,7 +24,8 @@ fn main() {
     let mut matches = utils::parse_options(&opts, free);
     let device = utils::parse_tuntap_options(&mut matches);
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
     let address = IpAddress::from_str(&matches.free[0]).expect("invalid address format");
     let url = Url::parse(&matches.free[1]).expect("invalid url format");
 
@@ -48,17 +49,16 @@ fn main() {
     routes.add_default_ipv6_route(default_v6_gw).unwrap();
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
-        .ip_addrs(ip_addrs)
-        .routes(routes);
+    let mut builder = InterfaceBuilder::new().ip_addrs(ip_addrs).routes(routes);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(ethernet_addr.into())
             .neighbor_cache(neighbor_cache);
     }
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
-    let tcp_handle = iface.add_socket(tcp_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let tcp_handle = sockets.add(tcp_socket);
 
     enum State {
         Connect,
@@ -69,14 +69,15 @@ fn main() {
 
     loop {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        let (socket, cx) = iface.get_socket_and_context::<tcp::Socket>(tcp_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp_handle);
+        let cx = iface.context();
 
         state = match state {
             State::Connect if !socket.is_active() => {
@@ -115,6 +116,6 @@ fn main() {
             _ => state,
         };
 
-        phy_wait(fd, iface.poll_delay(timestamp)).expect("wait error");
+        phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
     }
 }

+ 13 - 11
examples/loopback.rs

@@ -9,7 +9,7 @@ mod utils;
 use core::str;
 use log::{debug, error, info};
 
-use smoltcp::iface::{InterfaceBuilder, NeighborCache};
+use smoltcp::iface::{InterfaceBuilder, NeighborCache, SocketSet};
 use smoltcp::phy::{Loopback, Medium};
 use smoltcp::socket::tcp;
 use smoltcp::time::{Duration, Instant};
@@ -71,7 +71,7 @@ fn main() {
     let device = Loopback::new(Medium::Ethernet);
 
     #[cfg(feature = "std")]
-    let device = {
+    let mut device = {
         let clock = clock.clone();
         utils::setup_logging_with_clock("", move || clock.elapsed());
 
@@ -86,12 +86,11 @@ fn main() {
     let mut neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]);
 
     let mut ip_addrs = [IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)];
-    let mut sockets: [_; 2] = Default::default();
-    let mut iface = InterfaceBuilder::new(device, &mut sockets[..])
+    let mut iface = InterfaceBuilder::new()
         .hardware_addr(EthernetAddress::default().into())
         .neighbor_cache(neighbor_cache)
         .ip_addrs(ip_addrs)
-        .finalize();
+        .finalize(&mut device);
 
     let server_socket = {
         // It is not strictly necessary to use a `static mut` and unsafe code here, but
@@ -113,21 +112,23 @@ fn main() {
         tcp::Socket::new(tcp_rx_buffer, tcp_tx_buffer)
     };
 
-    let server_handle = iface.add_socket(server_socket);
-    let client_handle = iface.add_socket(client_socket);
+    let mut sockets: [_; 2] = Default::default();
+    let mut sockets = SocketSet::new(&mut sockets[..]);
+    let server_handle = sockets.add(server_socket);
+    let client_handle = sockets.add(client_socket);
 
     let mut did_listen = false;
     let mut did_connect = false;
     let mut done = false;
     while !done && clock.elapsed() < Instant::from_millis(10_000) {
-        match iface.poll(clock.elapsed()) {
+        match iface.poll(clock.elapsed(), &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        let mut socket = iface.get_socket::<tcp::Socket>(server_handle);
+        let mut socket = sockets.get_mut::<tcp::Socket>(server_handle);
         if !socket.is_active() && !socket.is_listening() {
             if !did_listen {
                 debug!("listening");
@@ -145,7 +146,8 @@ fn main() {
             done = true;
         }
 
-        let (mut socket, cx) = iface.get_socket_and_context::<tcp::Socket>(client_handle);
+        let mut socket = sockets.get_mut::<tcp::Socket>(client_handle);
+        let cx = iface.context();
         if !socket.is_open() {
             if !did_connect {
                 debug!("connecting");
@@ -162,7 +164,7 @@ fn main() {
             socket.close();
         }
 
-        match iface.poll_delay(clock.elapsed()) {
+        match iface.poll_delay(clock.elapsed(), &sockets) {
             Some(Duration::ZERO) => debug!("resuming"),
             Some(delay) => {
                 debug!("sleeping for {} ms", delay);

+ 14 - 11
examples/multicast.rs

@@ -4,7 +4,7 @@ use log::debug;
 use std::collections::BTreeMap;
 use std::os::unix::io::AsRawFd;
 
-use smoltcp::iface::{InterfaceBuilder, NeighborCache};
+use smoltcp::iface::{InterfaceBuilder, NeighborCache, SocketSet};
 use smoltcp::phy::wait as phy_wait;
 use smoltcp::socket::{raw, udp};
 use smoltcp::time::Instant;
@@ -26,7 +26,8 @@ fn main() {
     let mut matches = utils::parse_options(&opts, free);
     let device = utils::parse_tuntap_options(&mut matches);
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
 
     let local_addr = Ipv4Address::new(192, 168, 69, 2);
@@ -34,19 +35,21 @@ fn main() {
     let ethernet_addr = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x02]);
     let ip_addr = IpCidr::new(IpAddress::from(local_addr), 24);
     let mut ipv4_multicast_storage = [None; 1];
-    let mut iface = InterfaceBuilder::new(device, vec![])
+    let mut iface = InterfaceBuilder::new()
         .hardware_addr(ethernet_addr.into())
         .neighbor_cache(neighbor_cache)
         .ip_addrs([ip_addr])
         .ipv4_multicast_groups(&mut ipv4_multicast_storage[..])
-        .finalize();
+        .finalize(&mut device);
 
     let now = Instant::now();
     // Join a multicast group to receive mDNS traffic
     iface
-        .join_multicast_group(Ipv4Address::from_bytes(&MDNS_GROUP), now)
+        .join_multicast_group(&mut device, Ipv4Address::from_bytes(&MDNS_GROUP), now)
         .unwrap();
 
+    let mut sockets = SocketSet::new(vec![]);
+
     // Must fit at least one IGMP packet
     let raw_rx_buffer = raw::PacketBuffer::new(vec![raw::PacketMetadata::EMPTY; 2], vec![0; 512]);
     // Will not send IGMP
@@ -57,25 +60,25 @@ fn main() {
         raw_rx_buffer,
         raw_tx_buffer,
     );
-    let raw_handle = iface.add_socket(raw_socket);
+    let raw_handle = sockets.add(raw_socket);
 
     // Must fit mDNS payload of at least one packet
     let udp_rx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY; 4], vec![0; 1024]);
     // Will not send mDNS
     let udp_tx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 0]);
     let udp_socket = udp::Socket::new(udp_rx_buffer, udp_tx_buffer);
-    let udp_handle = iface.add_socket(udp_socket);
+    let udp_handle = sockets.add(udp_socket);
 
     loop {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        let socket = iface.get_socket::<raw::Socket>(raw_handle);
+        let socket = sockets.get_mut::<raw::Socket>(raw_handle);
 
         if socket.can_recv() {
             // For display purposes only - normally we wouldn't process incoming IGMP packets
@@ -92,7 +95,7 @@ fn main() {
             }
         }
 
-        let socket = iface.get_socket::<udp::Socket>(udp_handle);
+        let socket = sockets.get_mut::<udp::Socket>(udp_handle);
         if !socket.is_open() {
             socket.bind(MDNS_PORT).unwrap()
         }
@@ -106,6 +109,6 @@ fn main() {
                 .unwrap_or_else(|e| println!("Recv UDP error: {:?}", e));
         }
 
-        phy_wait(fd, iface.poll_delay(timestamp)).expect("wait error");
+        phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
     }
 }

+ 10 - 9
examples/ping.rs

@@ -2,6 +2,7 @@ mod utils;
 
 use byteorder::{ByteOrder, NetworkEndian};
 use log::debug;
+use smoltcp::iface::SocketSet;
 use std::cmp;
 use std::collections::BTreeMap;
 use std::collections::HashMap;
@@ -86,7 +87,8 @@ fn main() {
     let mut matches = utils::parse_options(&opts, free);
     let device = utils::parse_tuntap_options(&mut matches);
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
     let device_caps = device.capabilities();
     let address = IpAddress::from_str(&matches.free[0]).expect("invalid address format");
     let count = matches
@@ -127,17 +129,16 @@ fn main() {
     routes.add_default_ipv6_route(default_v6_gw).unwrap();
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
-        .ip_addrs(ip_addrs)
-        .routes(routes);
+    let mut builder = InterfaceBuilder::new().ip_addrs(ip_addrs).routes(routes);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(ethernet_addr.into())
             .neighbor_cache(neighbor_cache);
     }
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
-    let icmp_handle = iface.add_socket(icmp_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let icmp_handle = sockets.add(icmp_socket);
 
     let mut send_at = Instant::from_millis(0);
     let mut seq_no = 0;
@@ -148,7 +149,7 @@ fn main() {
 
     loop {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
@@ -156,7 +157,7 @@ fn main() {
         }
 
         let timestamp = Instant::now();
-        let socket = iface.get_socket::<icmp::Socket>(icmp_handle);
+        let socket = sockets.get_mut::<icmp::Socket>(icmp_handle);
         if !socket.is_open() {
             socket.bind(icmp::Endpoint::Ident(ident)).unwrap();
             send_at = timestamp;
@@ -255,7 +256,7 @@ fn main() {
         }
 
         let timestamp = Instant::now();
-        match iface.poll_at(timestamp) {
+        match iface.poll_at(timestamp, &sockets) {
             Some(poll_at) if timestamp < poll_at => {
                 let resume_at = cmp::min(poll_at, send_at);
                 phy_wait(fd, Some(resume_at - timestamp)).expect("wait error");

+ 18 - 16
examples/server.rs

@@ -6,7 +6,7 @@ use std::fmt::Write;
 use std::os::unix::io::AsRawFd;
 use std::str;
 
-use smoltcp::iface::{InterfaceBuilder, NeighborCache};
+use smoltcp::iface::{InterfaceBuilder, NeighborCache, SocketSet};
 use smoltcp::phy::{wait as phy_wait, Device, Medium};
 use smoltcp::socket::{tcp, udp};
 use smoltcp::time::{Duration, Instant};
@@ -22,7 +22,8 @@ fn main() {
     let mut matches = utils::parse_options(&opts, free);
     let device = utils::parse_tuntap_options(&mut matches);
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
 
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
 
@@ -54,24 +55,25 @@ fn main() {
     ];
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![]).ip_addrs(ip_addrs);
+    let mut builder = InterfaceBuilder::new().ip_addrs(ip_addrs);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(ethernet_addr.into())
             .neighbor_cache(neighbor_cache);
     }
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
-    let udp_handle = iface.add_socket(udp_socket);
-    let tcp1_handle = iface.add_socket(tcp1_socket);
-    let tcp2_handle = iface.add_socket(tcp2_socket);
-    let tcp3_handle = iface.add_socket(tcp3_socket);
-    let tcp4_handle = iface.add_socket(tcp4_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let udp_handle = sockets.add(udp_socket);
+    let tcp1_handle = sockets.add(tcp1_socket);
+    let tcp2_handle = sockets.add(tcp2_socket);
+    let tcp3_handle = sockets.add(tcp3_socket);
+    let tcp4_handle = sockets.add(tcp4_socket);
 
     let mut tcp_6970_active = false;
     loop {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
@@ -79,7 +81,7 @@ fn main() {
         }
 
         // udp:6969: respond "hello"
-        let socket = iface.get_socket::<udp::Socket>(udp_handle);
+        let socket = sockets.get_mut::<udp::Socket>(udp_handle);
         if !socket.is_open() {
             socket.bind(6969).unwrap()
         }
@@ -105,7 +107,7 @@ fn main() {
         }
 
         // tcp:6969: respond "hello"
-        let socket = iface.get_socket::<tcp::Socket>(tcp1_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp1_handle);
         if !socket.is_open() {
             socket.listen(6969).unwrap();
         }
@@ -118,7 +120,7 @@ fn main() {
         }
 
         // tcp:6970: echo with reverse
-        let socket = iface.get_socket::<tcp::Socket>(tcp2_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp2_handle);
         if !socket.is_open() {
             socket.listen(6970).unwrap()
         }
@@ -160,7 +162,7 @@ fn main() {
         }
 
         // tcp:6971: sinkhole
-        let socket = iface.get_socket::<tcp::Socket>(tcp3_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp3_handle);
         if !socket.is_open() {
             socket.listen(6971).unwrap();
             socket.set_keep_alive(Some(Duration::from_millis(1000)));
@@ -181,7 +183,7 @@ fn main() {
         }
 
         // tcp:6972: fountain
-        let socket = iface.get_socket::<tcp::Socket>(tcp4_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp4_handle);
         if !socket.is_open() {
             socket.listen(6972).unwrap()
         }
@@ -200,6 +202,6 @@ fn main() {
                 .unwrap();
         }
 
-        phy_wait(fd, iface.poll_delay(timestamp)).expect("wait error");
+        phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
     }
 }

+ 13 - 11
examples/sixlowpan.rs

@@ -47,7 +47,7 @@ use std::collections::BTreeMap;
 use std::os::unix::io::AsRawFd;
 use std::str;
 
-use smoltcp::iface::{FragmentsCache, InterfaceBuilder, NeighborCache};
+use smoltcp::iface::{FragmentsCache, InterfaceBuilder, NeighborCache, SocketSet};
 use smoltcp::phy::{wait as phy_wait, Medium, RawSocket};
 use smoltcp::socket::tcp;
 use smoltcp::socket::udp;
@@ -65,7 +65,8 @@ fn main() {
     let device = RawSocket::new("wpan1", Medium::Ieee802154).unwrap();
 
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
 
     let neighbor_cache = NeighborCache::new(BTreeMap::new());
 
@@ -89,7 +90,7 @@ fn main() {
 
     let mut out_packet_buffer = [0u8; 1280];
 
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new()
         .ip_addrs(ip_addrs)
         .pan_id(Ieee802154Pan(0xbeef));
     builder = builder
@@ -97,12 +98,13 @@ fn main() {
         .neighbor_cache(neighbor_cache)
         .sixlowpan_fragments_cache(cache)
         .sixlowpan_out_packet_cache(&mut out_packet_buffer[..]);
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
-    let udp_handle = iface.add_socket(udp_socket);
-    let tcp_handle = iface.add_socket(tcp_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let udp_handle = sockets.add(udp_socket);
+    let tcp_handle = sockets.add(tcp_socket);
 
-    let socket = iface.get_socket::<tcp::Socket>(tcp_handle);
+    let socket = sockets.get_mut::<tcp::Socket>(tcp_handle);
     socket.listen(50000).unwrap();
 
     let mut tcp_active = false;
@@ -112,7 +114,7 @@ fn main() {
 
         let mut poll = true;
         while poll {
-            match iface.poll(timestamp) {
+            match iface.poll(timestamp, &mut device, &mut sockets) {
                 Ok(r) => poll = r,
                 Err(e) => {
                     debug!("poll error: {}", e);
@@ -122,7 +124,7 @@ fn main() {
         }
 
         // udp:6969: respond "hello"
-        let socket = iface.get_socket::<udp::Socket>(udp_handle);
+        let socket = sockets.get_mut::<udp::Socket>(udp_handle);
         if !socket.is_open() {
             socket.bind(6969).unwrap()
         }
@@ -148,7 +150,7 @@ fn main() {
             socket.send_slice(&buffer[..len], endpoint).unwrap();
         }
 
-        let socket = iface.get_socket::<tcp::Socket>(tcp_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp_handle);
         if socket.is_active() && !tcp_active {
             debug!("connected");
         } else if !socket.is_active() && tcp_active {
@@ -182,6 +184,6 @@ fn main() {
             socket.close();
         }
 
-        phy_wait(fd, iface.poll_delay(timestamp)).expect("wait error");
+        phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
     }
 }

+ 12 - 10
examples/sixlowpan_benchmark.rs

@@ -48,7 +48,7 @@ use std::collections::BTreeMap;
 use std::os::unix::io::AsRawFd;
 use std::str;
 
-use smoltcp::iface::{FragmentsCache, InterfaceBuilder, NeighborCache};
+use smoltcp::iface::{FragmentsCache, InterfaceBuilder, NeighborCache, SocketSet};
 use smoltcp::phy::{wait as phy_wait, Medium, RawSocket};
 use smoltcp::socket::tcp;
 use smoltcp::wire::{Ieee802154Pan, IpAddress, IpCidr};
@@ -139,7 +139,8 @@ fn main() {
     let device = RawSocket::new("wpan1", Medium::Ieee802154).unwrap();
 
     let fd = device.as_raw_fd();
-    let device = utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
+    let mut device =
+        utils::parse_middleware_options(&mut matches, device, /*loopback=*/ false);
 
     let mode = match matches.free[0].as_ref() {
         "reader" => Client::Reader,
@@ -167,7 +168,7 @@ fn main() {
 
     let cache = FragmentsCache::new(vec![], BTreeMap::new());
 
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new()
         .ip_addrs(ip_addrs)
         .pan_id(Ieee802154Pan(0xbeef));
     builder = builder
@@ -175,10 +176,11 @@ fn main() {
         .neighbor_cache(neighbor_cache)
         .sixlowpan_fragments_cache(cache)
         .sixlowpan_out_packet_cache(vec![]);
-    let mut iface = builder.finalize();
+    let mut iface = builder.finalize(&mut device);
 
-    let tcp1_handle = iface.add_socket(tcp1_socket);
-    let tcp2_handle = iface.add_socket(tcp2_socket);
+    let mut sockets = SocketSet::new(vec![]);
+    let tcp1_handle = sockets.add(tcp1_socket);
+    let tcp2_handle = sockets.add(tcp2_socket);
 
     let default_timeout = Some(Duration::from_millis(1000));
 
@@ -187,7 +189,7 @@ fn main() {
 
     while !CLIENT_DONE.load(Ordering::SeqCst) {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut device, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
@@ -195,7 +197,7 @@ fn main() {
         }
 
         // tcp:1234: emit data
-        let socket = iface.get_socket::<tcp::Socket>(tcp1_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp1_handle);
         if !socket.is_open() {
             socket.listen(1234).unwrap();
         }
@@ -211,7 +213,7 @@ fn main() {
         }
 
         // tcp:1235: sink data
-        let socket = iface.get_socket::<tcp::Socket>(tcp2_handle);
+        let socket = sockets.get_mut::<tcp::Socket>(tcp2_handle);
         if !socket.is_open() {
             socket.listen(1235).unwrap();
         }
@@ -226,7 +228,7 @@ fn main() {
             processed += length;
         }
 
-        match iface.poll_at(timestamp) {
+        match iface.poll_at(timestamp, &sockets) {
             Some(poll_at) if timestamp < poll_at => {
                 phy_wait(fd, Some(poll_at - timestamp)).expect("wait error");
             }

+ 2 - 2
fuzz/fuzz_targets/tcp_headers.rs

@@ -132,11 +132,11 @@ fuzz_target!(|data: &[u8]| {
     let neighbor_cache = NeighborCache::new(&mut neighbor_cache_entries[..]);
 
     let ip_addrs = [IpCidr::new(IpAddress::v4(127, 0, 0, 1), 8)];
-    let mut iface = InterfaceBuilder::new(device)
+    let mut iface = InterfaceBuilder::new()
         .ethernet_addr(EthernetAddress::default())
         .neighbor_cache(neighbor_cache)
         .ip_addrs(ip_addrs)
-        .finalize();
+        .finalize(&mut device);
 
     let server_socket = {
         // It is not strictly necessary to use a `static mut` and unsafe code here, but

Fișier diff suprimat deoarece este prea mare
+ 158 - 217
src/iface/interface.rs


+ 1 - 1
src/iface/mod.rs

@@ -20,7 +20,7 @@ pub use self::neighbor::Cache as NeighborCache;
 #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
 pub use self::neighbor::Neighbor;
 pub use self::route::{Route, Routes};
-pub use socket_set::{SocketHandle, SocketStorage};
+pub use socket_set::{SocketHandle, SocketSet, SocketStorage};
 
 #[cfg(feature = "proto-sixlowpan")]
 pub use self::fragmentation::{PacketAssembler, PacketAssemblerSet as FragmentsCache};

+ 29 - 6
src/iface/socket_set.rs

@@ -39,7 +39,7 @@ impl fmt::Display for SocketHandle {
 ///
 /// The lifetime `'a` is used when storing a `Socket<'a>`.
 #[derive(Debug)]
-pub(crate) struct SocketSet<'a> {
+pub struct SocketSet<'a> {
     sockets: ManagedSlice<'a, SocketStorage<'a>>,
 }
 
@@ -93,15 +93,28 @@ impl<'a> SocketSet<'a> {
     /// # Panics
     /// This function may panic if the handle does not belong to this socket set
     /// or the socket has the wrong type.
-    pub fn get<T: AnySocket<'a>>(&mut self, handle: SocketHandle) -> &mut T {
-        match self.sockets[handle.0].inner.as_mut() {
+    pub fn get<T: AnySocket<'a>>(&self, handle: SocketHandle) -> &T {
+        match self.sockets[handle.0].inner.as_ref() {
             Some(item) => {
-                T::downcast(&mut item.socket).expect("handle refers to a socket of a wrong type")
+                T::downcast(&item.socket).expect("handle refers to a socket of a wrong type")
             }
             None => panic!("handle does not refer to a valid socket"),
         }
     }
 
+    /// Get a mutable socket from the set by its handle, as mutable.
+    ///
+    /// # Panics
+    /// This function may panic if the handle does not belong to this socket set
+    /// or the socket has the wrong type.
+    pub fn get_mut<T: AnySocket<'a>>(&mut self, handle: SocketHandle) -> &mut T {
+        match self.sockets[handle.0].inner.as_mut() {
+            Some(item) => T::downcast_mut(&mut item.socket)
+                .expect("handle refers to a socket of a wrong type"),
+            None => panic!("handle does not refer to a valid socket"),
+        }
+    }
+
     /// Remove a socket from the set, without changing its state.
     ///
     /// # Panics
@@ -114,13 +127,23 @@ impl<'a> SocketSet<'a> {
         }
     }
 
+    /// Get an iterator to the inner sockets.
+    pub fn iter(&self) -> impl Iterator<Item = (SocketHandle, &Socket<'a>)> {
+        self.items().map(|i| (i.meta.handle, &i.socket))
+    }
+
+    /// Get a mutable iterator to the inner sockets.
+    pub fn iter_mut(&mut self) -> impl Iterator<Item = (SocketHandle, &mut Socket<'a>)> {
+        self.items_mut().map(|i| (i.meta.handle, &mut i.socket))
+    }
+
     /// Iterate every socket in this set.
-    pub fn iter(&self) -> impl Iterator<Item = &Item<'a>> + '_ {
+    pub(crate) fn items(&self) -> impl Iterator<Item = &Item<'a>> + '_ {
         self.sockets.iter().filter_map(|x| x.inner.as_ref())
     }
 
     /// Iterate every socket in this set.
-    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut Item<'a>> + '_ {
+    pub(crate) fn items_mut(&mut self) -> impl Iterator<Item = &mut Item<'a>> + '_ {
         self.sockets.iter_mut().filter_map(|x| x.inner.as_mut())
     }
 }

+ 0 - 7
src/lib.rs

@@ -1,12 +1,5 @@
 #![cfg_attr(not(any(test, feature = "std")), no_std)]
 #![deny(unsafe_code)]
-#![cfg_attr(
-    all(
-        any(feature = "proto-ipv4", feature = "proto-ipv6"),
-        feature = "medium-ethernet"
-    ),
-    deny(unused)
-)]
 
 //! The _smoltcp_ library is built in a layered structure, with the layers corresponding
 //! to the levels of API abstraction. Only the highest layers would be used by a typical

+ 11 - 2
src/socket/mod.rs

@@ -93,7 +93,8 @@ impl<'a> Socket<'a> {
 /// A conversion trait for network sockets.
 pub trait AnySocket<'a>: Sized {
     fn upcast(self) -> Socket<'a>;
-    fn downcast<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self>;
+    fn downcast<'c>(socket: &'c Socket<'a>) -> Option<&'c Self>;
+    fn downcast_mut<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self>;
 }
 
 macro_rules! from_socket {
@@ -103,7 +104,15 @@ macro_rules! from_socket {
                 Socket::$variant(self)
             }
 
-            fn downcast<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self> {
+            fn downcast<'c>(socket: &'c Socket<'a>) -> Option<&'c Self> {
+                #[allow(unreachable_patterns)]
+                match socket {
+                    Socket::$variant(socket) => Some(socket),
+                    _ => None,
+                }
+            }
+
+            fn downcast_mut<'c>(socket: &'c mut Socket<'a>) -> Option<&'c mut Self> {
                 #[allow(unreachable_patterns)]
                 match socket {
                     Socket::$variant(socket) => Some(socket),

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff