diff --git a/examples/benchmark.rs b/examples/benchmark.rs index e4d3e27a..c00f4f77 100644 --- a/examples/benchmark.rs +++ b/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::(tcp1_handle); + let socket = sockets.get::(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::(tcp2_handle); + let socket = sockets.get::(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"); } diff --git a/examples/client.rs b/examples/client.rs index 6fa2dc7f..88a3b01c 100644 --- a/examples/client.rs +++ b/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_handle); - socket.connect(cx, (address, port), 49500).unwrap(); + let socket = sockets.get::(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_handle); + let socket = sockets.get::(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"); } } diff --git a/examples/dhcp_client.rs b/examples/dhcp_client.rs index 72c26115..65abd3d2 100644 --- a/examples/dhcp_client.rs +++ b/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::(dhcp_handle).poll(); + let event = sockets.get::(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"); } } diff --git a/examples/dns.rs b/examples/dns.rs index c3b8cd3a..1456befc 100644 --- a/examples/dns.rs +++ b/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_handle); - let query = socket.start_query(cx, name).unwrap(); + let socket = sockets.get::(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_handle) + match sockets + .get::(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"); } } diff --git a/examples/httpclient.rs b/examples/httpclient.rs index bda9b951..9f7f8006 100644 --- a/examples/httpclient.rs +++ b/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_handle); + let socket = sockets.get::(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"); } } diff --git a/examples/loopback.rs b/examples/loopback.rs index 8fe5150a..2e3f7084 100644 --- a/examples/loopback.rs +++ b/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::(server_handle); + let mut socket = sockets.get::(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::(client_handle); + let mut socket = sockets.get::(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); diff --git a/examples/multicast.rs b/examples/multicast.rs index 6b94b132..c18659b1 100644 --- a/examples/multicast.rs +++ b/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_handle); + let socket = sockets.get::(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_handle); + let socket = sockets.get::(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"); } } diff --git a/examples/ping.rs b/examples/ping.rs index cf240550..411d9ca0 100644 --- a/examples/ping.rs +++ b/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_handle); + let socket = sockets.get::(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"); diff --git a/examples/server.rs b/examples/server.rs index a5db0a49..0565eb33 100644 --- a/examples/server.rs +++ b/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_handle); + let socket = sockets.get::(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::(tcp1_handle); + let socket = sockets.get::(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::(tcp2_handle); + let socket = sockets.get::(tcp2_handle); if !socket.is_open() { socket.listen(6970).unwrap() } @@ -160,7 +161,7 @@ fn main() { } // tcp:6971: sinkhole - let socket = iface.get_socket::(tcp3_handle); + let socket = sockets.get::(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::(tcp4_handle); + let socket = sockets.get::(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"); } } diff --git a/examples/sixlowpan.rs b/examples/sixlowpan.rs index ef33ecfd..b60be2c5 100644 --- a/examples/sixlowpan.rs +++ b/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_handle); + let socket = sockets.get::(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_handle); + let socket = sockets.get::(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_handle); + let socket = sockets.get::(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"); } } diff --git a/examples/sixlowpan_benchmark.rs b/examples/sixlowpan_benchmark.rs index 2fa39366..34a71edc 100644 --- a/examples/sixlowpan_benchmark.rs +++ b/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::(tcp1_handle); + let socket = sockets.get::(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::(tcp2_handle); + let socket = sockets.get::(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"); } diff --git a/src/iface/interface.rs b/src/iface/interface.rs index d4fd3f6a..649522c1 100644 --- a/src/iface/interface.rs +++ b/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` 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, 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(device: DeviceT, sockets: SocketsT) -> Self - where - SocketsT: Into>>, - { + 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>(&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>(&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>( - &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)> { - 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)> { - 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 { + pub fn poll(&mut self, timestamp: Instant, sockets: &mut SocketSet<'_>) -> Result { 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 { + pub fn poll_at(&mut self, timestamp: Instant, sockets: &SocketSet<'_>) -> Option { 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 { - match self.poll_at(timestamp) { + pub fn poll_delay(&mut self, timestamp: Instant, sockets: &SocketSet<'_>) -> Option { + 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::(socket_handle); + let socket = sockets.get::(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::(socket_handle); + let socket = sockets.get::(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::(socket_handle); + let socket = sockets.get::(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::(socket_handle).can_recv()); + assert!(!sockets.get::(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::(socket_handle); + let socket = sockets.get::(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_handle); + let socket = sockets.get::(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_handle); + let socket = sockets.get::(udp_socket_handle); assert!(socket.can_recv()); assert_eq!( socket.recv(), diff --git a/src/iface/mod.rs b/src/iface/mod.rs index 62be2d47..0d7c2e8b 100644 --- a/src/iface/mod.rs +++ b/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}; diff --git a/src/iface/socket_set.rs b/src/iface/socket_set.rs index 72e274a7..92629c39 100644 --- a/src/iface/socket_set.rs +++ b/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)> { + 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)> { + self.items_mut().map(|i| (i.meta.handle, &mut i.socket)) + } + /// Iterate every socket in this set. - pub fn iter(&self) -> impl Iterator> + '_ { + pub(crate) fn items(&self) -> impl Iterator> + '_ { self.sockets.iter().filter_map(|x| x.inner.as_ref()) } /// Iterate every socket in this set. - pub fn iter_mut(&mut self) -> impl Iterator> + '_ { + pub(crate) fn items_mut(&mut self) -> impl Iterator> + '_ { self.sockets.iter_mut().filter_map(|x| x.inner.as_mut()) } } diff --git a/src/lib.rs b/src/lib.rs index b28f434b..f1a3653e 100644 --- a/src/lib.rs +++ b/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