Implement socket sets.
This commit is contained in:
parent
83bb8c6ae8
commit
234e5ef29e
|
@ -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 }
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue