Browse Source

iface: borrow the SocketSet instead of owning.

Dario Nieuwenhuis 2 years ago
parent
commit
b71ffcb6cc

+ 9 - 8
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};
@@ -94,7 +94,7 @@ 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(device).ip_addrs(ip_addrs);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(ethernet_addr.into())
@@ -102,15 +102,16 @@ fn main() {
     }
     let mut iface = builder.finalize();
 
-    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 sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
@@ -118,7 +119,7 @@ fn main() {
         }
 
         // tcp:1234: emit data
-        let socket = iface.get_socket::<tcp::Socket>(tcp1_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp1_handle);
         if !socket.is_open() {
             socket.listen(1234).unwrap();
         }
@@ -136,7 +137,7 @@ fn main() {
         }
 
         // tcp:1235: sink data
-        let socket = iface.get_socket::<tcp::Socket>(tcp2_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp2_handle);
         if !socket.is_open() {
             socket.listen(1235).unwrap();
         }
@@ -153,7 +154,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");
             }

+ 11 - 8
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;
@@ -42,7 +42,7 @@ fn main() {
     routes.add_default_ipv4_route(default_v4_gw).unwrap();
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new(device)
         .ip_addrs(ip_addrs)
         .routes(routes);
     if medium == Medium::Ethernet {
@@ -52,22 +52,25 @@ fn main() {
     }
     let mut iface = builder.finalize();
 
-    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::<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 sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        let socket = iface.get_socket::<tcp::Socket>(tcp_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp_handle);
         if socket.is_active() && !tcp_active {
             debug!("connected");
         } else if !socket.is_active() && tcp_active {
@@ -104,6 +107,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");
     }
 }

+ 7 - 6
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};
@@ -34,7 +34,7 @@ fn main() {
     let routes = Routes::new(&mut routes_storage[..]);
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new(device)
         .ip_addrs(ip_addrs)
         .routes(routes);
     if medium == Medium::Ethernet {
@@ -52,15 +52,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 sockets) {
             debug!("poll error: {}", e);
         }
 
-        let event = iface.get_socket::<dhcpv4::Socket>(dhcp_handle).poll();
+        let event = sockets.get::<dhcpv4::Socket>(dhcp_handle).poll();
         match event {
             None => {}
             Some(dhcpv4::Event::Configured(config)) => {
@@ -90,7 +91,7 @@ fn main() {
             }
         }
 
-        phy_wait(fd, iface.poll_delay(timestamp)).expect("wait error");
+        phy_wait(fd, iface.poll_delay(timestamp, &sockets)).expect("wait error");
     }
 }
 

+ 10 - 9
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};
@@ -55,7 +55,7 @@ fn main() {
     routes.add_default_ipv6_route(default_v6_gw).unwrap();
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new(device)
         .ip_addrs(ip_addrs)
         .routes(routes);
     if medium == Medium::Ethernet {
@@ -65,24 +65,25 @@ fn main() {
     }
     let mut iface = builder.finalize();
 
-    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::<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 sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        match iface
-            .get_socket::<dns::Socket>(dns_handle)
+        match sockets
+            .get::<dns::Socket>(dns_handle)
             .get_query_result(query)
         {
             Ok(addrs) => {
@@ -93,6 +94,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");
     }
 }

+ 8 - 6
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;
@@ -48,7 +48,7 @@ fn main() {
     routes.add_default_ipv6_route(default_v6_gw).unwrap();
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new(device)
         .ip_addrs(ip_addrs)
         .routes(routes);
     if medium == Medium::Ethernet {
@@ -58,7 +58,8 @@ fn main() {
     }
     let mut iface = builder.finalize();
 
-    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 +70,15 @@ fn main() {
 
     loop {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &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::<tcp::Socket>(tcp_handle);
+        let cx = iface.context();
 
         state = match state {
             State::Connect if !socket.is_active() => {
@@ -115,6 +117,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");
     }
 }

+ 11 - 9
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};
@@ -86,8 +86,7 @@ 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(device)
         .hardware_addr(EthernetAddress::default().into())
         .neighbor_cache(neighbor_cache)
         .ip_addrs(ip_addrs)
@@ -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 sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        let mut socket = iface.get_socket::<tcp::Socket>(server_handle);
+        let mut socket = sockets.get::<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::<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);

+ 10 - 8
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;
@@ -34,7 +34,7 @@ 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(device)
         .hardware_addr(ethernet_addr.into())
         .neighbor_cache(neighbor_cache)
         .ip_addrs([ip_addr])
@@ -47,6 +47,8 @@ fn main() {
         .join_multicast_group(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 +59,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 sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
             }
         }
 
-        let socket = iface.get_socket::<raw::Socket>(raw_handle);
+        let socket = sockets.get::<raw::Socket>(raw_handle);
 
         if socket.can_recv() {
             // For display purposes only - normally we wouldn't process incoming IGMP packets
@@ -92,7 +94,7 @@ fn main() {
             }
         }
 
-        let socket = iface.get_socket::<udp::Socket>(udp_handle);
+        let socket = sockets.get::<udp::Socket>(udp_handle);
         if !socket.is_open() {
             socket.bind(MDNS_PORT).unwrap()
         }
@@ -106,6 +108,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");
     }
 }

+ 7 - 5
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;
@@ -127,7 +128,7 @@ fn main() {
     routes.add_default_ipv6_route(default_v6_gw).unwrap();
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new(device)
         .ip_addrs(ip_addrs)
         .routes(routes);
     if medium == Medium::Ethernet {
@@ -137,7 +138,8 @@ fn main() {
     }
     let mut iface = builder.finalize();
 
-    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 +150,7 @@ fn main() {
 
     loop {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
@@ -156,7 +158,7 @@ fn main() {
         }
 
         let timestamp = Instant::now();
-        let socket = iface.get_socket::<icmp::Socket>(icmp_handle);
+        let socket = sockets.get::<icmp::Socket>(icmp_handle);
         if !socket.is_open() {
             socket.bind(icmp::Endpoint::Ident(ident)).unwrap();
             send_at = timestamp;
@@ -255,7 +257,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");

+ 15 - 14
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};
@@ -54,7 +54,7 @@ fn main() {
     ];
 
     let medium = device.capabilities().medium;
-    let mut builder = InterfaceBuilder::new(device, vec![]).ip_addrs(ip_addrs);
+    let mut builder = InterfaceBuilder::new(device).ip_addrs(ip_addrs);
     if medium == Medium::Ethernet {
         builder = builder
             .hardware_addr(ethernet_addr.into())
@@ -62,16 +62,17 @@ fn main() {
     }
     let mut iface = builder.finalize();
 
-    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 sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
@@ -79,7 +80,7 @@ fn main() {
         }
 
         // udp:6969: respond "hello"
-        let socket = iface.get_socket::<udp::Socket>(udp_handle);
+        let socket = sockets.get::<udp::Socket>(udp_handle);
         if !socket.is_open() {
             socket.bind(6969).unwrap()
         }
@@ -105,7 +106,7 @@ fn main() {
         }
 
         // tcp:6969: respond "hello"
-        let socket = iface.get_socket::<tcp::Socket>(tcp1_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp1_handle);
         if !socket.is_open() {
             socket.listen(6969).unwrap();
         }
@@ -118,7 +119,7 @@ fn main() {
         }
 
         // tcp:6970: echo with reverse
-        let socket = iface.get_socket::<tcp::Socket>(tcp2_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp2_handle);
         if !socket.is_open() {
             socket.listen(6970).unwrap()
         }
@@ -160,7 +161,7 @@ fn main() {
         }
 
         // tcp:6971: sinkhole
-        let socket = iface.get_socket::<tcp::Socket>(tcp3_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp3_handle);
         if !socket.is_open() {
             socket.listen(6971).unwrap();
             socket.set_keep_alive(Some(Duration::from_millis(1000)));
@@ -181,7 +182,7 @@ fn main() {
         }
 
         // tcp:6972: fountain
-        let socket = iface.get_socket::<tcp::Socket>(tcp4_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp4_handle);
         if !socket.is_open() {
             socket.listen(6972).unwrap()
         }
@@ -200,6 +201,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");
     }
 }

+ 10 - 9
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;
@@ -89,7 +89,7 @@ fn main() {
 
     let mut out_packet_buffer = [0u8; 1280];
 
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new(device)
         .ip_addrs(ip_addrs)
         .pan_id(Ieee802154Pan(0xbeef));
     builder = builder
@@ -99,10 +99,11 @@ fn main() {
         .sixlowpan_out_packet_cache(&mut out_packet_buffer[..]);
     let mut iface = builder.finalize();
 
-    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::<tcp::Socket>(tcp_handle);
     socket.listen(50000).unwrap();
 
     let mut tcp_active = false;
@@ -112,7 +113,7 @@ fn main() {
 
         let mut poll = true;
         while poll {
-            match iface.poll(timestamp) {
+            match iface.poll(timestamp, &mut sockets) {
                 Ok(r) => poll = r,
                 Err(e) => {
                     debug!("poll error: {}", e);
@@ -122,7 +123,7 @@ fn main() {
         }
 
         // udp:6969: respond "hello"
-        let socket = iface.get_socket::<udp::Socket>(udp_handle);
+        let socket = sockets.get::<udp::Socket>(udp_handle);
         if !socket.is_open() {
             socket.bind(6969).unwrap()
         }
@@ -148,7 +149,7 @@ fn main() {
             socket.send_slice(&buffer[..len], endpoint).unwrap();
         }
 
-        let socket = iface.get_socket::<tcp::Socket>(tcp_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp_handle);
         if socket.is_active() && !tcp_active {
             debug!("connected");
         } else if !socket.is_active() && tcp_active {
@@ -182,6 +183,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");
     }
 }

+ 9 - 8
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};
@@ -167,7 +167,7 @@ fn main() {
 
     let cache = FragmentsCache::new(vec![], BTreeMap::new());
 
-    let mut builder = InterfaceBuilder::new(device, vec![])
+    let mut builder = InterfaceBuilder::new(device)
         .ip_addrs(ip_addrs)
         .pan_id(Ieee802154Pan(0xbeef));
     builder = builder
@@ -177,8 +177,9 @@ fn main() {
         .sixlowpan_out_packet_cache(vec![]);
     let mut iface = builder.finalize();
 
-    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 +188,7 @@ fn main() {
 
     while !CLIENT_DONE.load(Ordering::SeqCst) {
         let timestamp = Instant::now();
-        match iface.poll(timestamp) {
+        match iface.poll(timestamp, &mut sockets) {
             Ok(_) => {}
             Err(e) => {
                 debug!("poll error: {}", e);
@@ -195,7 +196,7 @@ fn main() {
         }
 
         // tcp:1234: emit data
-        let socket = iface.get_socket::<tcp::Socket>(tcp1_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp1_handle);
         if !socket.is_open() {
             socket.listen(1234).unwrap();
         }
@@ -211,7 +212,7 @@ fn main() {
         }
 
         // tcp:1235: sink data
-        let socket = iface.get_socket::<tcp::Socket>(tcp2_handle);
+        let socket = sockets.get::<tcp::Socket>(tcp2_handle);
         if !socket.is_open() {
             socket.listen(1235).unwrap();
         }
@@ -226,7 +227,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");
             }

+ 87 - 144
src/iface/interface.rs

@@ -8,7 +8,6 @@ use managed::{ManagedMap, ManagedSlice};
 #[cfg(feature = "proto-sixlowpan")]
 use super::fragmentation::PacketAssemblerSet;
 use super::socket_set::SocketSet;
-use super::{SocketHandle, SocketStorage};
 use crate::iface::Routes;
 #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
 use crate::iface::{NeighborAnswer, NeighborCache};
@@ -99,7 +98,6 @@ macro_rules! check {
 /// a `&mut [T]`, or `Vec<T>` if a heap is available.
 pub struct Interface<'a, DeviceT: for<'d> Device<'d>> {
     device: DeviceT,
-    sockets: SocketSet<'a>,
     inner: InterfaceInner<'a>,
     fragments: FragmentsBuffer<'a>,
     out_packets: OutPackets<'a>,
@@ -148,7 +146,6 @@ pub struct InterfaceBuilder<'a, DeviceT: for<'d> Device<'d>> {
     #[cfg(feature = "medium-ieee802154")]
     pan_id: Option<Ieee802154Pan>,
     ip_addrs: ManagedSlice<'a, IpCidr>,
-    sockets: SocketSet<'a>,
     #[cfg(feature = "proto-ipv4")]
     any_ip: bool,
     routes: Routes<'a>,
@@ -187,7 +184,7 @@ let neighbor_cache = // ...
 # NeighborCache::new(BTreeMap::new());
 let ip_addrs = // ...
 # [];
-let iface = InterfaceBuilder::new(device, vec![])
+let iface = InterfaceBuilder::new(device)
         .hardware_addr(hw_addr.into())
         .neighbor_cache(neighbor_cache)
         .ip_addrs(ip_addrs)
@@ -195,13 +192,9 @@ let iface = InterfaceBuilder::new(device, vec![])
 ```
     "##
     )]
-    pub fn new<SocketsT>(device: DeviceT, sockets: SocketsT) -> Self
-    where
-        SocketsT: Into<ManagedSlice<'a, SocketStorage<'a>>>,
-    {
+    pub fn new(device: DeviceT) -> Self {
         InterfaceBuilder {
             device,
-            sockets: SocketSet::new(sockets),
 
             #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
             hardware_addr: None,
@@ -434,7 +427,6 @@ let iface = InterfaceBuilder::new(device, vec![])
 
         Interface {
             device: self.device,
-            sockets: self.sockets,
             fragments: FragmentsBuffer {
                 #[cfg(feature = "proto-sixlowpan")]
                 sixlowpan_fragments: self
@@ -635,43 +627,11 @@ impl<'a, DeviceT> Interface<'a, DeviceT>
 where
     DeviceT: for<'d> Device<'d>,
 {
-    /// Add a socket to the interface, and return its handle.
-    ///
-    /// # Panics
-    /// This function panics if the storage is fixed-size (not a `Vec`) and is full.
-    pub fn add_socket<T: AnySocket<'a>>(&mut self, socket: T) -> SocketHandle {
-        self.sockets.add(socket)
-    }
-
-    /// Get a socket from the interface 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_socket<T: AnySocket<'a>>(&mut self, handle: SocketHandle) -> &mut T {
-        self.sockets.get(handle)
-    }
-
-    /// Get a socket by handle, and the socket context.
+    /// Get the socket context.
     ///
     /// The context is needed for some socket methods.
-    ///
-    /// # 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_socket_and_context<T: AnySocket<'a>>(
-        &mut self,
-        handle: SocketHandle,
-    ) -> (&mut T, &mut InterfaceInner<'a>) {
-        (self.sockets.get(handle), &mut self.inner)
-    }
-
-    /// Remove a socket from the set, without changing its state.
-    ///
-    /// # Panics
-    /// This function may panic if the handle does not belong to this socket set.
-    pub fn remove_socket(&mut self, handle: SocketHandle) -> Socket<'a> {
-        self.sockets.remove(handle)
+    pub fn context(&mut self) -> &mut InterfaceInner<'a> {
+        &mut self.inner
     }
 
     /// Get the HardwareAddress address of the interface.
@@ -732,18 +692,6 @@ where
         &mut self.device
     }
 
-    /// Get an iterator to the inner sockets.
-    pub fn sockets(&self) -> impl Iterator<Item = (SocketHandle, &Socket<'a>)> {
-        self.sockets.iter().map(|i| (i.meta.handle, &i.socket))
-    }
-
-    /// Get a mutable iterator to the inner sockets.
-    pub fn sockets_mut(&mut self) -> impl Iterator<Item = (SocketHandle, &mut Socket<'a>)> {
-        self.sockets
-            .iter_mut()
-            .map(|i| (i.meta.handle, &mut i.socket))
-    }
-
     /// Add an address to a list of subscribed multicast IP addresses.
     ///
     /// Returns `Ok(announce_sent)` if the address was added successfully, where `annouce_sent`
@@ -883,7 +831,7 @@ where
     /// packets containing any unsupported protocol, option, or form, which is
     /// a very common occurrence and on a production system it should not even
     /// be logged.
-    pub fn poll(&mut self, timestamp: Instant) -> Result<bool> {
+    pub fn poll(&mut self, timestamp: Instant, sockets: &mut SocketSet<'_>) -> Result<bool> {
         self.inner.now = timestamp;
 
         let mut readiness_may_have_changed = false;
@@ -916,8 +864,8 @@ where
         }
 
         loop {
-            let processed_any = self.socket_ingress();
-            let emitted_any = self.socket_egress();
+            let processed_any = self.socket_ingress(sockets);
+            let emitted_any = self.socket_egress(sockets);
 
             #[cfg(feature = "proto-igmp")]
             self.igmp_egress()?;
@@ -940,13 +888,13 @@ where
     ///
     /// [poll]: #method.poll
     /// [Instant]: struct.Instant.html
-    pub fn poll_at(&mut self, timestamp: Instant) -> Option<Instant> {
+    pub fn poll_at(&mut self, timestamp: Instant, sockets: &SocketSet<'_>) -> Option<Instant> {
         self.inner.now = timestamp;
 
         let inner = &mut self.inner;
 
-        self.sockets
-            .iter()
+        sockets
+            .items()
             .filter_map(move |item| {
                 let socket_poll_at = item.socket.poll_at(inner);
                 match item
@@ -969,20 +917,19 @@ where
     ///
     /// [poll]: #method.poll
     /// [Duration]: struct.Duration.html
-    pub fn poll_delay(&mut self, timestamp: Instant) -> Option<Duration> {
-        match self.poll_at(timestamp) {
+    pub fn poll_delay(&mut self, timestamp: Instant, sockets: &SocketSet<'_>) -> Option<Duration> {
+        match self.poll_at(timestamp, sockets) {
             Some(poll_at) if timestamp < poll_at => Some(poll_at - timestamp),
             Some(_) => Some(Duration::from_millis(0)),
             _ => None,
         }
     }
 
-    fn socket_ingress(&mut self) -> bool {
+    fn socket_ingress(&mut self, sockets: &mut SocketSet<'_>) -> bool {
         let mut processed_any = false;
         let Self {
             device,
             inner,
-            sockets,
             fragments: _fragments,
             out_packets: _out_packets,
         } = self;
@@ -1032,18 +979,17 @@ where
         processed_any
     }
 
-    fn socket_egress(&mut self) -> bool {
+    fn socket_egress(&mut self, sockets: &mut SocketSet<'_>) -> bool {
         let Self {
             device,
             inner,
-            sockets,
             out_packets: _out_packets,
             ..
         } = self;
         let _caps = device.capabilities();
 
         let mut emitted_any = false;
-        for item in sockets.iter_mut() {
+        for item in sockets.items_mut() {
             if !item
                 .meta
                 .egress_permitted(inner.now, |ip_addr| inner.has_neighbor(&ip_addr))
@@ -1670,7 +1616,7 @@ impl<'a> InterfaceInner<'a> {
                         // However, we cannot use that one because the payload passed to it is a
                         // normal IPv6 UDP payload, which is not what we have here.
                         for udp_socket in sockets
-                            .iter_mut()
+                            .items_mut()
                             .filter_map(|i| udp::Socket::downcast(&mut i.socket))
                         {
                             if udp_socket.accepts(self, &IpRepr::Ipv6(ipv6_repr), &udp_repr) {
@@ -1799,7 +1745,7 @@ impl<'a> InterfaceInner<'a> {
 
         // Pass every IP packet to all raw sockets we have registered.
         for raw_socket in sockets
-            .iter_mut()
+            .items_mut()
             .filter_map(|i| raw::Socket::downcast(&mut i.socket))
         {
             if raw_socket.accepts(ip_repr) {
@@ -1917,7 +1863,7 @@ impl<'a> InterfaceInner<'a> {
                     && udp_packet.dst_port() == DHCP_CLIENT_PORT
                 {
                     if let Some(dhcp_socket) = sockets
-                        .iter_mut()
+                        .items_mut()
                         .filter_map(|i| dhcpv4::Socket::downcast(&mut i.socket))
                         .next()
                     {
@@ -2096,7 +2042,7 @@ impl<'a> InterfaceInner<'a> {
 
         #[cfg(all(feature = "socket-icmp", feature = "proto-ipv6"))]
         for icmp_socket in _sockets
-            .iter_mut()
+            .items_mut()
             .filter_map(|i| icmp::Socket::downcast(&mut i.socket))
         {
             if icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) {
@@ -2275,7 +2221,7 @@ impl<'a> InterfaceInner<'a> {
 
         #[cfg(all(feature = "socket-icmp", feature = "proto-ipv4"))]
         for icmp_socket in _sockets
-            .iter_mut()
+            .items_mut()
             .filter_map(|i| icmp::Socket::downcast(&mut i.socket))
         {
             if icmp_socket.accepts(self, &ip_repr, &icmp_repr.into()) {
@@ -2400,7 +2346,7 @@ impl<'a> InterfaceInner<'a> {
 
         #[cfg(feature = "socket-udp")]
         for udp_socket in sockets
-            .iter_mut()
+            .items_mut()
             .filter_map(|i| udp::Socket::downcast(&mut i.socket))
         {
             if udp_socket.accepts(self, &ip_repr, &udp_repr) {
@@ -2411,7 +2357,7 @@ impl<'a> InterfaceInner<'a> {
 
         #[cfg(feature = "socket-dns")]
         for dns_socket in sockets
-            .iter_mut()
+            .items_mut()
             .filter_map(|i| dns::Socket::downcast(&mut i.socket))
         {
             if dns_socket.accepts(&ip_repr, &udp_repr) {
@@ -2468,7 +2414,7 @@ impl<'a> InterfaceInner<'a> {
         ));
 
         for tcp_socket in sockets
-            .iter_mut()
+            .items_mut()
             .filter_map(|i| tcp::Socket::downcast(&mut i.socket))
         {
             if tcp_socket.accepts(self, &ip_repr, &tcp_repr) {
@@ -3196,7 +3142,7 @@ mod test {
         }
     }
 
-    fn create_loopback<'a>() -> Interface<'a, Loopback> {
+    fn create_loopback<'a>() -> (Interface<'a, Loopback>, SocketSet<'a>) {
         #[cfg(feature = "medium-ethernet")]
         return create_loopback_ethernet();
         #[cfg(not(feature = "medium-ethernet"))]
@@ -3205,7 +3151,7 @@ mod test {
 
     #[cfg(all(feature = "medium-ip"))]
     #[allow(unused)]
-    fn create_loopback_ip<'a>() -> Interface<'a, Loopback> {
+    fn create_loopback_ip<'a>() -> (Interface<'a, Loopback>, SocketSet<'a>) {
         // Create a basic device
         let device = Loopback::new(Medium::Ip);
         let ip_addrs = [
@@ -3217,14 +3163,16 @@ mod test {
             IpCidr::new(IpAddress::v6(0xfdbe, 0, 0, 0, 0, 0, 0, 1), 64),
         ];
 
-        let iface_builder = InterfaceBuilder::new(device, vec![]).ip_addrs(ip_addrs);
+        let iface_builder = InterfaceBuilder::new(device).ip_addrs(ip_addrs);
         #[cfg(feature = "proto-igmp")]
         let iface_builder = iface_builder.ipv4_multicast_groups(BTreeMap::new());
-        iface_builder.finalize()
+        let iface = iface_builder.finalize();
+
+        (iface, SocketSet::new(vec![]))
     }
 
     #[cfg(all(feature = "medium-ethernet"))]
-    fn create_loopback_ethernet<'a>() -> Interface<'a, Loopback> {
+    fn create_loopback_ethernet<'a>() -> (Interface<'a, Loopback>, SocketSet<'a>) {
         // Create a basic device
         let device = Loopback::new(Medium::Ethernet);
         let ip_addrs = [
@@ -3237,7 +3185,7 @@ mod test {
         ];
 
         #[cfg(feature = "proto-sixlowpan")]
-        let iface_builder = InterfaceBuilder::new(device, vec![])
+        let iface_builder = InterfaceBuilder::new(device)
             .hardware_addr(EthernetAddress::default().into())
             .neighbor_cache(NeighborCache::new(BTreeMap::new()))
             .sixlowpan_fragments_cache(PacketAssemblerSet::new(vec![], BTreeMap::new()))
@@ -3245,14 +3193,16 @@ mod test {
             .ip_addrs(ip_addrs);
 
         #[cfg(not(feature = "proto-sixlowpan"))]
-        let iface_builder = InterfaceBuilder::new(device, vec![])
+        let iface_builder = InterfaceBuilder::new(device)
             .hardware_addr(EthernetAddress::default().into())
             .neighbor_cache(NeighborCache::new(BTreeMap::new()))
             .ip_addrs(ip_addrs);
 
         #[cfg(feature = "proto-igmp")]
         let iface_builder = iface_builder.ipv4_multicast_groups(BTreeMap::new());
-        iface_builder.finalize()
+        let iface = iface_builder.finalize();
+
+        (iface, SocketSet::new(vec![]))
     }
 
     #[cfg(feature = "proto-igmp")]
@@ -3285,13 +3235,13 @@ mod test {
     #[should_panic(expected = "hardware_addr required option was not set")]
     #[cfg(all(feature = "medium-ethernet"))]
     fn test_builder_initialization_panic() {
-        InterfaceBuilder::new(Loopback::new(Medium::Ethernet), vec![]).finalize();
+        InterfaceBuilder::new(Loopback::new(Medium::Ethernet)).finalize();
     }
 
     #[test]
     #[cfg(feature = "proto-ipv4")]
     fn test_no_icmp_no_unicast_ipv4() {
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         // Unknown Ipv4 Protocol
         //
@@ -3313,13 +3263,13 @@ mod test {
         // Ensure that the unknown protocol frame does not trigger an
         // ICMP error response when the destination address is a
         // broadcast address
-        assert_eq!(iface.inner.process_ipv4(&mut iface.sockets, &frame), None);
+        assert_eq!(iface.inner.process_ipv4(&mut sockets, &frame), None);
     }
 
     #[test]
     #[cfg(feature = "proto-ipv6")]
     fn test_no_icmp_no_unicast_ipv6() {
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         // Unknown Ipv6 Protocol
         //
@@ -3341,14 +3291,14 @@ mod test {
         // Ensure that the unknown protocol frame does not trigger an
         // ICMP error response when the destination address is a
         // broadcast address
-        assert_eq!(iface.inner.process_ipv6(&mut iface.sockets, &frame), None);
+        assert_eq!(iface.inner.process_ipv6(&mut sockets, &frame), None);
     }
 
     #[test]
     #[cfg(feature = "proto-ipv4")]
     fn test_icmp_error_no_payload() {
         static NO_BYTES: [u8; 0] = [];
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         // Unknown Ipv4 Protocol with no payload
         let repr = IpRepr::Ipv4(Ipv4Repr {
@@ -3391,7 +3341,7 @@ mod test {
         // Ensure that the unknown protocol triggers an error response.
         // And we correctly handle no payload.
         assert_eq!(
-            iface.inner.process_ipv4(&mut iface.sockets, &frame),
+            iface.inner.process_ipv4(&mut sockets, &frame),
             Some(expected_repr)
         );
     }
@@ -3399,7 +3349,7 @@ mod test {
     #[test]
     #[cfg(feature = "proto-ipv4")]
     fn test_local_subnet_broadcasts() {
-        let mut iface = create_loopback();
+        let (mut iface, _) = create_loopback();
         iface.update_ip_addrs(|addrs| {
             addrs.iter_mut().next().map(|addr| {
                 *addr = IpCidr::Ipv4(Ipv4Cidr::new(Ipv4Address([192, 168, 1, 23]), 24));
@@ -3456,7 +3406,7 @@ mod test {
         static UDP_PAYLOAD: [u8; 12] = [
             0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x6c, 0x64, 0x21,
         ];
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         let mut udp_bytes_unicast = vec![0u8; 20];
         let mut udp_bytes_broadcast = vec![0u8; 20];
@@ -3515,9 +3465,7 @@ mod test {
         // Ensure that the unknown protocol triggers an error response.
         // And we correctly handle no payload.
         assert_eq!(
-            iface
-                .inner
-                .process_udp(&mut iface.sockets, ip_repr, false, data),
+            iface.inner.process_udp(&mut sockets, ip_repr, false, data),
             Some(expected_repr)
         );
 
@@ -3543,12 +3491,9 @@ mod test {
         // ICMP error response when the destination address is a
         // broadcast address and no socket is bound to the port.
         assert_eq!(
-            iface.inner.process_udp(
-                &mut iface.sockets,
-                ip_repr,
-                false,
-                packet_broadcast.into_inner()
-            ),
+            iface
+                .inner
+                .process_udp(&mut sockets, ip_repr, false, packet_broadcast.into_inner()),
             None
         );
     }
@@ -3560,7 +3505,7 @@ mod test {
 
         static UDP_PAYLOAD: [u8; 5] = [0x48, 0x65, 0x6c, 0x6c, 0x6f];
 
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         let rx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
         let tx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
@@ -3570,7 +3515,7 @@ mod test {
         let mut udp_bytes = vec![0u8; 13];
         let mut packet = UdpPacket::new_unchecked(&mut udp_bytes);
 
-        let socket_handle = iface.add_socket(udp_socket);
+        let socket_handle = sockets.add(udp_socket);
 
         #[cfg(feature = "proto-ipv6")]
         let src_ip = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1);
@@ -3600,7 +3545,7 @@ mod test {
         });
 
         // Bind the socket to port 68
-        let socket = iface.get_socket::<udp::Socket>(socket_handle);
+        let socket = sockets.get::<udp::Socket>(socket_handle);
         assert_eq!(socket.bind(68), Ok(()));
         assert!(!socket.can_recv());
         assert!(socket.can_send());
@@ -3618,13 +3563,13 @@ mod test {
         assert_eq!(
             iface
                 .inner
-                .process_udp(&mut iface.sockets, ip_repr, false, packet.into_inner()),
+                .process_udp(&mut sockets, ip_repr, false, packet.into_inner()),
             None
         );
 
         // Make sure the payload to the UDP packet processed by process_udp is
         // appended to the bound sockets rx_buffer
-        let socket = iface.get_socket::<udp::Socket>(socket_handle);
+        let socket = sockets.get::<udp::Socket>(socket_handle);
         assert!(socket.can_recv());
         assert_eq!(
             socket.recv(),
@@ -3637,7 +3582,7 @@ mod test {
     fn test_handle_ipv4_broadcast() {
         use crate::wire::{Icmpv4Packet, Icmpv4Repr, Ipv4Packet};
 
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         let our_ipv4_addr = iface.ipv4_address().unwrap();
         let src_ipv4_addr = Ipv4Address([127, 0, 0, 2]);
@@ -3689,7 +3634,7 @@ mod test {
         let expected_packet = IpPacket::Icmpv4((expected_ipv4_repr, expected_icmpv4_repr));
 
         assert_eq!(
-            iface.inner.process_ipv4(&mut iface.sockets, &frame),
+            iface.inner.process_ipv4(&mut sockets, &frame),
             Some(expected_packet)
         );
     }
@@ -3709,7 +3654,7 @@ mod test {
         #[cfg(feature = "proto-ipv6")]
         const MAX_PAYLOAD_LEN: usize = 1192;
 
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         #[cfg(all(feature = "proto-ipv4", not(feature = "proto-ipv6")))]
         let src_addr = Ipv4Address([192, 168, 1, 1]);
@@ -3801,14 +3746,14 @@ mod test {
         assert_eq!(
             iface
                 .inner
-                .process_udp(&mut iface.sockets, ip_repr.into(), false, payload),
+                .process_udp(&mut sockets, ip_repr.into(), false, payload),
             Some(IpPacket::Icmpv4((expected_ip_repr, expected_icmp_repr)))
         );
         #[cfg(feature = "proto-ipv6")]
         assert_eq!(
             iface
                 .inner
-                .process_udp(&mut iface.sockets, ip_repr.into(), false, payload),
+                .process_udp(&mut sockets, ip_repr.into(), false, payload),
             Some(IpPacket::Icmpv6((expected_ip_repr, expected_icmp_repr)))
         );
     }
@@ -3816,7 +3761,7 @@ mod test {
     #[test]
     #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))]
     fn test_handle_valid_arp_request() {
-        let mut iface = create_loopback_ethernet();
+        let (mut iface, mut sockets) = create_loopback_ethernet();
 
         let mut eth_bytes = vec![0u8; 42];
 
@@ -3844,7 +3789,7 @@ mod test {
         assert_eq!(
             iface
                 .inner
-                .process_ethernet(&mut iface.sockets, frame.into_inner()),
+                .process_ethernet(&mut sockets, frame.into_inner()),
             Some(EthernetPacket::Arp(ArpRepr::EthernetIpv4 {
                 operation: ArpOperation::Reply,
                 source_hardware_addr: local_hw_addr,
@@ -3868,7 +3813,7 @@ mod test {
     #[test]
     #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv6"))]
     fn test_handle_valid_ndisc_request() {
-        let mut iface = create_loopback_ethernet();
+        let (mut iface, mut sockets) = create_loopback_ethernet();
 
         let mut eth_bytes = vec![0u8; 86];
 
@@ -3919,7 +3864,7 @@ mod test {
         assert_eq!(
             iface
                 .inner
-                .process_ethernet(&mut iface.sockets, frame.into_inner()),
+                .process_ethernet(&mut sockets, frame.into_inner()),
             Some(EthernetPacket::Ip(IpPacket::Icmpv6((
                 ipv6_expected,
                 icmpv6_expected
@@ -3940,7 +3885,7 @@ mod test {
     #[test]
     #[cfg(all(feature = "medium-ethernet", feature = "proto-ipv4"))]
     fn test_handle_other_arp_request() {
-        let mut iface = create_loopback_ethernet();
+        let (mut iface, mut sockets) = create_loopback_ethernet();
 
         let mut eth_bytes = vec![0u8; 42];
 
@@ -3966,7 +3911,7 @@ mod test {
         assert_eq!(
             iface
                 .inner
-                .process_ethernet(&mut iface.sockets, frame.into_inner()),
+                .process_ethernet(&mut sockets, frame.into_inner()),
             None
         );
 
@@ -3988,7 +3933,7 @@ mod test {
         not(feature = "medium-ieee802154")
     ))]
     fn test_arp_flush_after_update_ip() {
-        let mut iface = create_loopback_ethernet();
+        let (mut iface, mut sockets) = create_loopback_ethernet();
 
         let mut eth_bytes = vec![0u8; 42];
 
@@ -4018,7 +3963,7 @@ mod test {
         assert_eq!(
             iface
                 .inner
-                .process_ethernet(&mut iface.sockets, frame.into_inner()),
+                .process_ethernet(&mut sockets, frame.into_inner()),
             Some(EthernetPacket::Arp(ArpRepr::EthernetIpv4 {
                 operation: ArpOperation::Reply,
                 source_hardware_addr: local_hw_addr,
@@ -4055,20 +4000,20 @@ mod test {
     fn test_icmpv4_socket() {
         use crate::wire::Icmpv4Packet;
 
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         let rx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 24]);
         let tx_buffer = icmp::PacketBuffer::new(vec![icmp::PacketMetadata::EMPTY], vec![0; 24]);
 
         let icmpv4_socket = icmp::Socket::new(rx_buffer, tx_buffer);
 
-        let socket_handle = iface.add_socket(icmpv4_socket);
+        let socket_handle = sockets.add(icmpv4_socket);
 
         let ident = 0x1234;
         let seq_no = 0x5432;
         let echo_data = &[0xff; 16];
 
-        let socket = iface.get_socket::<icmp::Socket>(socket_handle);
+        let socket = sockets.get::<icmp::Socket>(socket_handle);
         // Bind to the ID 0x1234
         assert_eq!(socket.bind(icmp::Endpoint::Ident(ident)), Ok(()));
 
@@ -4094,7 +4039,7 @@ mod test {
 
         // Open a socket and ensure the packet is handled due to the listening
         // socket.
-        assert!(!iface.get_socket::<icmp::Socket>(socket_handle).can_recv());
+        assert!(!sockets.get::<icmp::Socket>(socket_handle).can_recv());
 
         // Confirm we still get EchoReply from `smoltcp` even with the ICMP socket listening
         let echo_reply = Icmpv4Repr::EchoReply {
@@ -4108,13 +4053,11 @@ mod test {
             ..ipv4_repr
         };
         assert_eq!(
-            iface
-                .inner
-                .process_icmpv4(&mut iface.sockets, ip_repr, icmp_data),
+            iface.inner.process_icmpv4(&mut sockets, ip_repr, icmp_data),
             Some(IpPacket::Icmpv4((ipv4_reply, echo_reply)))
         );
 
-        let socket = iface.get_socket::<icmp::Socket>(socket_handle);
+        let socket = sockets.get::<icmp::Socket>(socket_handle);
         assert!(socket.can_recv());
         assert_eq!(
             socket.recv(),
@@ -4128,7 +4071,7 @@ mod test {
     #[test]
     #[cfg(feature = "proto-ipv6")]
     fn test_solicited_node_addrs() {
-        let mut iface = create_loopback();
+        let (mut iface, _) = create_loopback();
         let mut new_addrs = vec![
             IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 1, 2, 0, 2), 64),
             IpCidr::new(IpAddress::v6(0xfe80, 0, 0, 0, 3, 4, 0, 0xffff), 64),
@@ -4151,7 +4094,7 @@ mod test {
     #[test]
     #[cfg(feature = "proto-ipv6")]
     fn test_icmpv6_nxthdr_unknown() {
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         let remote_ip_addr = Ipv6Address::new(0xfe80, 0, 0, 0, 0, 0, 0, 1);
 
@@ -4206,7 +4149,7 @@ mod test {
         // Ensure the unknown next header causes a ICMPv6 Parameter Problem
         // error message to be sent to the sender.
         assert_eq!(
-            iface.inner.process_ipv6(&mut iface.sockets, &frame),
+            iface.inner.process_ipv6(&mut sockets, &frame),
             Some(IpPacket::Icmpv6((reply_ipv6_repr, reply_icmp_repr)))
         );
     }
@@ -4248,7 +4191,7 @@ mod test {
             Ipv4Address::new(224, 0, 0, 56),
         ];
 
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         // Join multicast groups
         let timestamp = Instant::now();
@@ -4292,7 +4235,7 @@ mod test {
         // loopback have been processed, including responses to
         // GENERAL_QUERY_BYTES. Therefore `recv_all()` would return 0
         // pkts that could be checked.
-        iface.socket_ingress();
+        iface.socket_ingress(&mut sockets);
 
         // Leave multicast groups
         let timestamp = Instant::now();
@@ -4314,7 +4257,7 @@ mod test {
     fn test_raw_socket_no_reply() {
         use crate::wire::{IpVersion, Ipv4Packet, UdpPacket, UdpRepr};
 
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         let packets = 1;
         let rx_buffer =
@@ -4324,7 +4267,7 @@ mod test {
             vec![0; 48 * packets],
         );
         let raw_socket = raw::Socket::new(IpVersion::Ipv4, IpProtocol::Udp, rx_buffer, tx_buffer);
-        iface.add_socket(raw_socket);
+        sockets.add(raw_socket);
 
         let src_addr = Ipv4Address([127, 0, 0, 2]);
         let dst_addr = Ipv4Address([127, 0, 0, 1]);
@@ -4371,7 +4314,7 @@ mod test {
             Ipv4Packet::new_unchecked(&bytes)
         };
 
-        assert_eq!(iface.inner.process_ipv4(&mut iface.sockets, &frame), None);
+        assert_eq!(iface.inner.process_ipv4(&mut sockets, &frame), None);
     }
 
     #[test]
@@ -4381,15 +4324,15 @@ mod test {
 
         static UDP_PAYLOAD: [u8; 5] = [0x48, 0x65, 0x6c, 0x6c, 0x6f];
 
-        let mut iface = create_loopback();
+        let (mut iface, mut sockets) = create_loopback();
 
         let udp_rx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
         let udp_tx_buffer = udp::PacketBuffer::new(vec![udp::PacketMetadata::EMPTY], vec![0; 15]);
         let udp_socket = udp::Socket::new(udp_rx_buffer, udp_tx_buffer);
-        let udp_socket_handle = iface.add_socket(udp_socket);
+        let udp_socket_handle = sockets.add(udp_socket);
 
         // Bind the socket to port 68
-        let socket = iface.get_socket::<udp::Socket>(udp_socket_handle);
+        let socket = sockets.get::<udp::Socket>(udp_socket_handle);
         assert_eq!(socket.bind(68), Ok(()));
         assert!(!socket.can_recv());
         assert!(socket.can_send());
@@ -4407,7 +4350,7 @@ mod test {
             raw_rx_buffer,
             raw_tx_buffer,
         );
-        iface.add_socket(raw_socket);
+        sockets.add(raw_socket);
 
         let src_addr = Ipv4Address([127, 0, 0, 2]);
         let dst_addr = Ipv4Address([127, 0, 0, 1]);
@@ -4453,10 +4396,10 @@ mod test {
             Ipv4Packet::new_unchecked(&bytes)
         };
 
-        assert_eq!(iface.inner.process_ipv4(&mut iface.sockets, &frame), None);
+        assert_eq!(iface.inner.process_ipv4(&mut sockets, &frame), None);
 
         // Make sure the UDP socket can still receive in presence of a Raw socket that handles UDP
-        let socket = iface.get_socket::<udp::Socket>(udp_socket_handle);
+        let socket = sockets.get::<udp::Socket>(udp_socket_handle);
         assert!(socket.can_recv());
         assert_eq!(
             socket.recv(),

+ 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};

+ 13 - 3
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>>,
 }
 
@@ -114,13 +114,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