瀏覽代碼

Make interfaces not own the sockets.

whitequark 8 年之前
父節點
當前提交
8f28e99a0c
共有 4 個文件被更改,包括 35 次插入49 次删除
  1. 11 10
      examples/server.rs
  2. 21 36
      src/iface/ethernet.rs
  3. 1 1
      src/lib.rs
  4. 2 2
      src/socket/udp.rs

+ 11 - 10
examples/server.rs

@@ -15,7 +15,7 @@ use smoltcp::phy::{Tracer, FaultInjector, TapInterface};
 use smoltcp::wire::{EthernetFrame, EthernetAddress, IpAddress};
 use smoltcp::wire::PrettyPrinter;
 use smoltcp::iface::{ArpCache, SliceArpCache, EthernetInterface};
-use smoltcp::socket::AsSocket;
+use smoltcp::socket::{AsSocket, SocketSet};
 use smoltcp::socket::{UdpSocket, UdpSocketBuffer, UdpPacketBuffer};
 use smoltcp::socket::{TcpSocket, TcpSocketBuffer};
 
@@ -83,18 +83,19 @@ fn main() {
     let hardware_addr  = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
     let protocol_addrs = [IpAddress::v4(192, 168, 69, 1)];
     let mut iface      = EthernetInterface::new(
-        Box::new(device), hardware_addr, protocol_addrs,
-        Box::new(arp_cache) as Box<ArpCache>, []);
+        Box::new(device), Box::new(arp_cache) as Box<ArpCache>,
+        hardware_addr, protocol_addrs);
 
-    let udp_handle  = iface.sockets_mut().add(udp_socket);
-    let tcp1_handle = iface.sockets_mut().add(tcp1_socket);
-    let tcp2_handle = iface.sockets_mut().add(tcp2_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 mut tcp_6969_connected = false;
     loop {
         // udp:6969: respond "yo dawg"
         {
-            let socket: &mut UdpSocket = iface.sockets_mut().get_mut(&udp_handle).as_socket();
+            let socket: &mut UdpSocket = sockets.get_mut(&udp_handle).as_socket();
             if socket.endpoint().is_unspecified() {
                 socket.bind(6969)
             }
@@ -123,7 +124,7 @@ fn main() {
 
         // tcp:6969: respond "yo dawg"
         {
-            let socket: &mut TcpSocket = iface.sockets_mut().get_mut(&tcp1_handle).as_socket();
+            let socket: &mut TcpSocket = sockets.get_mut(&tcp1_handle).as_socket();
             if !socket.is_open() {
                 socket.listen(6969).unwrap();
             }
@@ -140,7 +141,7 @@ fn main() {
 
         // tcp:6970: echo with reverse
         {
-            let socket: &mut TcpSocket = iface.sockets_mut().get_mut(&tcp2_handle).as_socket();
+            let socket: &mut TcpSocket = sockets.get_mut(&tcp2_handle).as_socket();
             if !socket.is_open() {
                 socket.listen(6970).unwrap()
             }
@@ -178,7 +179,7 @@ fn main() {
         let timestamp = Instant::now().duration_since(startup_time);
         let timestamp_ms = (timestamp.as_secs() * 1000) +
                            (timestamp.subsec_nanos() / 1000000) as u64;
-        match iface.poll(timestamp_ms) {
+        match iface.poll(&mut sockets, timestamp_ms) {
             Ok(()) => (),
             Err(e) => debug!("poll error: {}", e)
         }

+ 21 - 36
src/iface/ethernet.rs

@@ -8,42 +8,37 @@ use wire::{Ipv4Packet, Ipv4Repr};
 use wire::{Icmpv4Packet, Icmpv4Repr, Icmpv4DstUnreachable};
 use wire::{IpAddress, IpProtocol, IpRepr};
 use wire::{TcpPacket, TcpRepr, TcpControl};
-use socket::{Socket, SocketSet};
-use super::{ArpCache};
+use socket::SocketSet;
+use super::ArpCache;
 
 /// An Ethernet network interface.
 ///
 /// The network interface logically owns a number of other data structures; to avoid
 /// a dependency on heap allocation, it instead owns a `BorrowMut<[T]>`, which can be
 /// a `&mut [T]`, or `Vec<T>` if a heap is available.
-pub struct Interface<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a> {
+pub struct Interface<'a, 'b, 'c, DeviceT: Device + 'a> {
     device:         Managed<'a, DeviceT>,
+    arp_cache:      Managed<'b, ArpCache>,
     hardware_addr:  EthernetAddress,
-    protocol_addrs: ManagedSlice<'b, IpAddress>,
-    arp_cache:      Managed<'c, ArpCache>,
-    sockets:        SocketSet<'d, 'e, 'f>
+    protocol_addrs: ManagedSlice<'c, IpAddress>,
 }
 
-impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
-        Interface<'a, 'b, 'c, 'd, 'e, 'f, DeviceT> {
+impl<'a, 'b, 'c, DeviceT: Device + 'a> Interface<'a, 'b, 'c, DeviceT> {
     /// Create a network interface using the provided network device.
     ///
     /// # Panics
     /// See the restrictions on [set_hardware_addr](#method.set_hardware_addr)
     /// and [set_protocol_addrs](#method.set_protocol_addrs) functions.
-    pub fn new<DeviceMT, ProtocolAddrsMT, ArpCacheMT, SocketsMT>
-              (device: DeviceMT,
-               hardware_addr: EthernetAddress, protocol_addrs: ProtocolAddrsMT,
-               arp_cache: ArpCacheMT, sockets: SocketsMT) ->
-              Interface<'a, 'b, 'c, 'd, 'e, 'f, DeviceT>
+    pub fn new<DeviceMT, ArpCacheMT, ProtocolAddrsMT>
+              (device: DeviceMT, arp_cache: ArpCacheMT,
+               hardware_addr: EthernetAddress, protocol_addrs: ProtocolAddrsMT) ->
+              Interface<'a, 'b, 'c, DeviceT>
             where DeviceMT: Into<Managed<'a, DeviceT>>,
-                  ProtocolAddrsMT: Into<ManagedSlice<'b, IpAddress>>,
-                  ArpCacheMT: Into<Managed<'c, ArpCache>>,
-                  SocketsMT: Into<ManagedSlice<'d, Option<Socket<'e, 'f>>>> {
+                  ArpCacheMT: Into<Managed<'b, ArpCache>>,
+                  ProtocolAddrsMT: Into<ManagedSlice<'c, IpAddress>>, {
         let device = device.into();
-        let protocol_addrs = protocol_addrs.into();
         let arp_cache = arp_cache.into();
-        let sockets = SocketSet::new(sockets);
+        let protocol_addrs = protocol_addrs.into();
 
         Self::check_hardware_addr(&hardware_addr);
         Self::check_protocol_addrs(&protocol_addrs);
@@ -52,7 +47,6 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
             arp_cache:      arp_cache,
             hardware_addr:  hardware_addr,
             protocol_addrs: protocol_addrs,
-            sockets:        sockets
         }
     }
 
@@ -93,7 +87,7 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
     ///
     /// # Panics
     /// This function panics if any of the addresses is not unicast.
-    pub fn update_protocol_addrs<F: FnOnce(&mut ManagedSlice<'b, IpAddress>)>(&mut self, f: F) {
+    pub fn update_protocol_addrs<F: FnOnce(&mut ManagedSlice<'c, IpAddress>)>(&mut self, f: F) {
         f(&mut self.protocol_addrs);
         Self::check_protocol_addrs(&self.protocol_addrs)
     }
@@ -104,20 +98,11 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
         self.protocol_addrs.iter().any(|&probe| probe == addr)
     }
 
-    /// Get the set of sockets owned by the interface.
-    pub fn sockets(&self) -> &SocketSet<'d, 'e, 'f> {
-        &self.sockets
-    }
-
-    /// Get the set of sockets owned by the interface, as mutable.
-    pub fn sockets_mut(&mut self) -> &mut SocketSet<'d, 'e, 'f> {
-        &mut self.sockets
-    }
-
-    /// Receive and process a packet, if available, and then transmit a packet, if necessary.
+    /// Receive and process a packet, if available, and then transmit a packet, if necessary,
+    /// handling the given set of sockets.
     ///
     /// The timestamp is a monotonically increasing number of milliseconds.
-    pub fn poll(&mut self, timestamp: u64) -> Result<(), Error> {
+    pub fn poll(&mut self, sockets: &mut SocketSet, timestamp: u64) -> Result<(), Error> {
         enum Response<'a> {
             Nop,
             Arp(ArpRepr),
@@ -127,7 +112,7 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
 
         // First, transmit any outgoing packets.
         loop {
-            if try!(self.emit(timestamp)) { break }
+            if try!(self.emit(sockets, timestamp)) { break }
         }
 
         // Now, receive any incoming packets.
@@ -217,7 +202,7 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
                     // Try dispatching a packet to a socket.
                     Ipv4Repr { src_addr, dst_addr, protocol } => {
                         let mut handled = false;
-                        for socket in self.sockets.iter_mut() {
+                        for socket in sockets.iter_mut() {
                             let ip_repr = IpRepr::Ipv4(ipv4_repr);
                             match socket.process(timestamp, &ip_repr, ipv4_packet.payload()) {
                                 Ok(()) => {
@@ -360,7 +345,7 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
         }
     }
 
-    fn emit(&mut self, timestamp: u64) -> Result<bool, Error> {
+    fn emit(&mut self, sockets: &mut SocketSet, timestamp: u64) -> Result<bool, Error> {
         // Borrow checker is being overly careful around closures, so we have
         // to hack around that.
         let src_hardware_addr = self.hardware_addr;
@@ -369,7 +354,7 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
         let device = &mut self.device;
 
         let mut nothing_to_transmit = true;
-        for socket in self.sockets.iter_mut() {
+        for socket in sockets.iter_mut() {
             let result = socket.dispatch(timestamp, &mut |repr, payload| {
                 let repr = try!(repr.lower(src_protocol_addrs));
 

+ 1 - 1
src/lib.rs

@@ -27,7 +27,7 @@
 //! Ethernet interface is provided.
 //!
 //! The interface layer handles the control messages, physical addressing and neighbor discovery.
-//! It owns the sockets and routes packets to and from them.
+//! It routes packets to and from sockets.
 //!
 //! # The physical layer
 //! The physical layer APIs are provided in the module [phy](phy/index.html); currently,

+ 2 - 2
src/socket/udp.rs

@@ -113,8 +113,8 @@ pub struct UdpSocket<'a, 'b: 'a> {
 
 impl<'a, 'b> UdpSocket<'a, 'b> {
     /// Create an UDP socket with the given buffers.
-    pub fn new(rx_buffer: SocketBuffer<'a, 'b>, tx_buffer: SocketBuffer<'a, 'b>)
-            -> Socket<'a, 'b> {
+    pub fn new(rx_buffer: SocketBuffer<'a, 'b>,
+               tx_buffer: SocketBuffer<'a, 'b>) -> Socket<'a, 'b> {
         Socket::Udp(UdpSocket {
             endpoint:  IpEndpoint::default(),
             rx_buffer: rx_buffer,