Make interfaces not own the sockets.
parent
83b70b12af
commit
362c954624
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue