瀏覽代碼

Implement socket sets.

whitequark 8 年之前
父節點
當前提交
019d03d758
共有 5 個文件被更改,包括 153 次插入11 次删除
  1. 1 1
      Cargo.toml
  2. 8 5
      examples/server.rs
  3. 10 5
      src/iface/ethernet.rs
  4. 4 0
      src/socket/mod.rs
  5. 130 0
      src/socket/set.rs

+ 1 - 1
Cargo.toml

@@ -12,7 +12,7 @@ license = "0BSD"
 
 [dependencies]
 byteorder = { version = "1.0", default-features = false }
-managed = { version = "0.2", default-features = false }
+managed = { version = "0.2.1", default-features = false }
 log = { version = "0.3", default-features = false, optional = true }
 libc = { version = "0.2.18", optional = true }
 

+ 8 - 5
examples/server.rs

@@ -84,16 +84,19 @@ fn main() {
 
     let hardware_addr  = EthernetAddress([0x02, 0x00, 0x00, 0x00, 0x00, 0x01]);
     let protocol_addrs = [IpAddress::v4(192, 168, 69, 1)];
-    let sockets        = vec![udp_socket, tcp1_socket, tcp2_socket];
     let mut iface      = EthernetInterface::new(
         Box::new(device), hardware_addr, protocol_addrs,
-        Box::new(arp_cache) as Box<ArpCache>, sockets);
+        Box::new(arp_cache) as Box<ArpCache>, []);
+
+    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 tcp_6969_connected = false;
     loop {
         // udp:6969: respond "yo dawg"
         {
-            let socket: &mut UdpSocket = iface.sockets()[0].as_socket();
+            let socket: &mut UdpSocket = iface.sockets_mut().get_mut(&udp_handle).as_socket();
             let client = match socket.recv() {
                 Ok((endpoint, data)) => {
                     debug!("udp:6969 recv data: {:?} from {}",
@@ -118,7 +121,7 @@ fn main() {
 
         // tcp:6969: respond "yo dawg"
         {
-            let socket: &mut TcpSocket = iface.sockets()[1].as_socket();
+            let socket: &mut TcpSocket = iface.sockets_mut().get_mut(&tcp1_handle).as_socket();
             if !socket.is_open() {
                 socket.listen(6969).unwrap();
             }
@@ -135,7 +138,7 @@ fn main() {
 
         // tcp:6970: echo with reverse
         {
-            let socket: &mut TcpSocket = iface.sockets()[2].as_socket();
+            let socket: &mut TcpSocket = iface.sockets_mut().get_mut(&tcp2_handle).as_socket();
             if !socket.is_open() {
                 socket.listen(6970).unwrap()
             }

+ 10 - 5
src/iface/ethernet.rs

@@ -8,7 +8,7 @@ use wire::{Ipv4Packet, Ipv4Repr};
 use wire::{Icmpv4Packet, Icmpv4Repr, Icmpv4DstUnreachable};
 use wire::{IpAddress, IpProtocol, IpRepr};
 use wire::{TcpPacket, TcpRepr, TcpControl};
-use socket::Socket;
+use socket::{Socket, SocketSet};
 use super::{ArpCache};
 
 /// An Ethernet network interface.
@@ -21,7 +21,7 @@ pub struct Interface<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
     hardware_addr:  EthernetAddress,
     protocol_addrs: ManagedSlice<'b, IpAddress>,
     arp_cache:      Managed<'c, ArpCache>,
-    sockets:        ManagedSlice<'d, Socket<'e, 'f>>
+    sockets:        SocketSet<'d, 'e, 'f>
 }
 
 impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
@@ -39,11 +39,11 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
             where DeviceMT: Into<Managed<'a, DeviceT>>,
                   ProtocolAddrsMT: Into<ManagedSlice<'b, IpAddress>>,
                   ArpCacheMT: Into<Managed<'c, ArpCache>>,
-                  SocketsMT: Into<ManagedSlice<'d, Socket<'e, 'f>>> {
+                  SocketsMT: Into<ManagedSlice<'d, Option<Socket<'e, 'f>>>> {
         let device = device.into();
         let protocol_addrs = protocol_addrs.into();
         let arp_cache = arp_cache.into();
-        let sockets = sockets.into();
+        let sockets = SocketSet::new(sockets);
 
         Self::check_hardware_addr(&hardware_addr);
         Self::check_protocol_addrs(&protocol_addrs);
@@ -105,7 +105,12 @@ impl<'a, 'b, 'c, 'd, 'e: 'd, 'f: 'e + 'd, DeviceT: Device + 'a>
     }
 
     /// Get the set of sockets owned by the interface.
-    pub fn sockets(&mut self) -> &mut ManagedSlice<'d, Socket<'e, 'f>> {
+    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
     }
 

+ 4 - 0
src/socket/mod.rs

@@ -15,6 +15,7 @@ use wire::IpRepr;
 
 mod udp;
 mod tcp;
+mod set;
 
 pub use self::udp::PacketBuffer as UdpPacketBuffer;
 pub use self::udp::SocketBuffer as UdpSocketBuffer;
@@ -24,6 +25,9 @@ pub use self::tcp::SocketBuffer as TcpSocketBuffer;
 pub use self::tcp::State as TcpState;
 pub use self::tcp::TcpSocket;
 
+pub use self::set::{Set as SocketSet, Handle as SocketHandle};
+pub use self::set::{Iter as SocketSetIter, IterMut as SocketSetIterMut};
+
 /// A network socket.
 ///
 /// This enumeration abstracts the various types of sockets based on the IP protocol.

+ 130 - 0
src/socket/set.rs

@@ -0,0 +1,130 @@
+use managed::ManagedSlice;
+use core::slice;
+
+use super::Socket;
+
+/// A handle, identifying a socket in a set.
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Handle {
+    index: usize
+}
+
+/// An extensible set of sockets, with stable numeric identifiers.
+pub struct Set<'a, 'b: 'a, 'c: 'a + 'b> {
+    sockets: ManagedSlice<'a, Option<Socket<'b, 'c>>>
+}
+
+impl<'a, 'b: 'a, 'c: 'a + 'b> Set<'a, 'b, 'c> {
+    /// Create a socket set using the provided storage.
+    pub fn new<SocketsT>(sockets: SocketsT) -> Set<'a, 'b, 'c>
+            where SocketsT: Into<ManagedSlice<'a, Option<Socket<'b, 'c>>>> {
+        let sockets = sockets.into();
+        Set {
+            sockets: sockets
+        }
+    }
+
+    /// Add a socket to the set, and return its handle.
+    ///
+    /// # Panics
+    /// This function panics if the storage is fixed-size (not a `Vec`) and is full.
+    pub fn add(&mut self, socket: Socket<'b, 'c>) -> Handle {
+        for (index, slot) in self.sockets.iter_mut().enumerate() {
+            if slot.is_none() {
+                *slot = Some(socket);
+                return Handle { index: index }
+            }
+        }
+
+        match self.sockets {
+            ManagedSlice::Borrowed(_) => {
+                panic!("adding a socket to a full SocketSet")
+            }
+            ManagedSlice::Owned(ref mut sockets) => {
+                sockets.push(Some(socket));
+                Handle { index: sockets.len() - 1 }
+            }
+        }
+    }
+
+    /// Get a socket from the set by its handle.
+    ///
+    /// # Panics
+    /// This function may panic if the handle does not belong to this socket set.
+    pub fn get(&self, handle: &Handle) -> &Socket<'b, 'c> {
+        self.sockets[handle.index]
+            .as_ref()
+            .expect("handle does not contain a valid socket index")
+    }
+
+    /// Get a socket from the set by its handle, as mutable.
+    ///
+    /// # Panics
+    /// This function may panic if the handle does not belong to this socket set.
+    pub fn get_mut(&mut self, handle: &Handle) -> &mut Socket<'b, 'c> {
+        self.sockets[handle.index]
+            .as_mut()
+            .expect("handle does not contain a valid socket index")
+    }
+
+    /// 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(&mut self, handle: Handle) {
+        assert!(self.sockets[handle.index].is_some());
+        self.sockets[handle.index] = None
+    }
+
+    /// Iterate every socket in this set.
+    pub fn iter<'d>(&'d self) -> Iter<'d, 'b, 'c> {
+        Iter { lower: self.sockets.iter() }
+    }
+
+    /// Iterate every socket in this set, as mutable.
+    pub fn iter_mut<'d>(&'d mut self) -> IterMut<'d, 'b, 'c> {
+        IterMut { lower: self.sockets.iter_mut() }
+    }
+}
+
+/// Immutable socket set iterator.
+///
+/// This struct is created by the [iter](struct.SocketSet.html#method.iter)
+/// on [socket sets](struct.SocketSet.html).
+pub struct Iter<'a, 'b: 'a, 'c: 'a + 'b> {
+    lower: slice::Iter<'a, Option<Socket<'b, 'c>>>
+}
+
+impl<'a, 'b: 'a, 'c: 'a + 'b> Iterator for Iter<'a, 'b, 'c> {
+    type Item = &'a Socket<'b, 'c>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        while let Some(socket_opt) = self.lower.next() {
+            if let Some(socket) = socket_opt.as_ref() {
+                return Some(socket)
+            }
+        }
+        None
+    }
+}
+
+/// Mutable socket set iterator.
+///
+/// This struct is created by the [iter_mut](struct.SocketSet.html#method.iter_mut)
+/// on [socket sets](struct.SocketSet.html).
+pub struct IterMut<'a, 'b: 'a, 'c: 'a + 'b> {
+    lower: slice::IterMut<'a, Option<Socket<'b, 'c>>>
+}
+
+impl<'a, 'b: 'a, 'c: 'a + 'b> Iterator for IterMut<'a, 'b, 'c> {
+    type Item = &'a mut Socket<'b, 'c>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        while let Some(socket_opt) = self.lower.next() {
+            if let Some(socket) = socket_opt.as_mut() {
+                return Some(socket)
+            }
+        }
+        None
+    }
+}