Reimplement {RawSocket,TapInterface}::receive correctly.
parent
7039ec8b04
commit
c2994b9757
|
@ -1,6 +1,8 @@
|
|||
extern crate smoltcp;
|
||||
|
||||
use std::env;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use smoltcp::phy::wait as phy_wait;
|
||||
use smoltcp::phy::{Device, RxToken, RawSocket};
|
||||
use smoltcp::wire::{PrettyPrinter, EthernetFrame};
|
||||
|
||||
|
@ -8,6 +10,7 @@ fn main() {
|
|||
let ifname = env::args().nth(1).unwrap();
|
||||
let mut socket = RawSocket::new(ifname.as_ref()).unwrap();
|
||||
loop {
|
||||
phy_wait(socket.as_raw_fd(), None).unwrap();
|
||||
let (rx_token, _) = socket.receive().unwrap();
|
||||
rx_token.consume(/*timestamp = */ 0, |buffer| {
|
||||
print!("{}", PrettyPrinter::<EthernetFrame<&[u8]>>::new("", &buffer));
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::cell::RefCell;
|
||||
use std::vec::Vec;
|
||||
use std::rc::Rc;
|
||||
use std::io;
|
||||
use std::os::unix::io::{RawFd, AsRawFd};
|
||||
|
@ -47,9 +48,20 @@ impl<'a> Device<'a> for RawSocket {
|
|||
}
|
||||
|
||||
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
|
||||
let rx = RxToken { lower: self.lower.clone(), mtu: self.mtu };
|
||||
let tx = TxToken { lower: self.lower.clone() };
|
||||
Some((rx, tx))
|
||||
let mut lower = self.lower.borrow_mut();
|
||||
let mut buffer = vec![0; self.mtu];
|
||||
match lower.recv(&mut buffer[..]) {
|
||||
Ok(size) => {
|
||||
buffer.resize(size, 0);
|
||||
let rx = RxToken { buffer };
|
||||
let tx = TxToken { lower: self.lower.clone() };
|
||||
Some((rx, tx))
|
||||
}
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
|
||||
None
|
||||
}
|
||||
Err(err) => panic!("{}", err)
|
||||
}
|
||||
}
|
||||
|
||||
fn transmit(&'a mut self) -> Option<Self::TxToken> {
|
||||
|
@ -61,17 +73,12 @@ impl<'a> Device<'a> for RawSocket {
|
|||
|
||||
#[doc(hidden)]
|
||||
pub struct RxToken {
|
||||
lower: Rc<RefCell<sys::RawSocketDesc>>,
|
||||
mtu: usize,
|
||||
buffer: Vec<u8>
|
||||
}
|
||||
|
||||
impl phy::RxToken for RxToken {
|
||||
fn consume<R, F: FnOnce(&[u8]) -> Result<R>>(self, _timestamp: u64, f: F) -> Result<R> {
|
||||
let mut lower = self.lower.borrow_mut();
|
||||
let mut buffer = vec![0; self.mtu];
|
||||
let size = lower.recv(&mut buffer[..]).unwrap();
|
||||
buffer.resize(size, 0);
|
||||
f(&mut buffer)
|
||||
f(&self.buffer[..])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use std::cell::RefCell;
|
||||
use std::vec::Vec;
|
||||
use std::rc::Rc;
|
||||
use std::io;
|
||||
use std::os::unix::io::{RawFd, AsRawFd};
|
||||
|
||||
use {Error, Result};
|
||||
use Result;
|
||||
use phy::{self, sys, DeviceCapabilities, Device};
|
||||
|
||||
/// A virtual Ethernet interface.
|
||||
|
@ -48,9 +49,20 @@ impl<'a> Device<'a> for TapInterface {
|
|||
}
|
||||
|
||||
fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
|
||||
let rx = RxToken { lower: self.lower.clone(), mtu: self.mtu };
|
||||
let tx = TxToken { lower: self.lower.clone(), };
|
||||
Some((rx, tx))
|
||||
let mut lower = self.lower.borrow_mut();
|
||||
let mut buffer = vec![0; self.mtu];
|
||||
match lower.recv(&mut buffer[..]) {
|
||||
Ok(size) => {
|
||||
buffer.resize(size, 0);
|
||||
let rx = RxToken { buffer };
|
||||
let tx = TxToken { lower: self.lower.clone() };
|
||||
Some((rx, tx))
|
||||
}
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
|
||||
None
|
||||
}
|
||||
Err(err) => panic!("{}", err)
|
||||
}
|
||||
}
|
||||
|
||||
fn transmit(&'a mut self) -> Option<Self::TxToken> {
|
||||
|
@ -62,26 +74,14 @@ impl<'a> Device<'a> for TapInterface {
|
|||
|
||||
#[doc(hidden)]
|
||||
pub struct RxToken {
|
||||
lower: Rc<RefCell<sys::TapInterfaceDesc>>,
|
||||
mtu: usize,
|
||||
buffer: Vec<u8>
|
||||
}
|
||||
|
||||
impl phy::RxToken for RxToken {
|
||||
fn consume<R, F>(self, _timestamp: u64, f: F) -> Result<R>
|
||||
where F: FnOnce(&[u8]) -> Result<R>
|
||||
{
|
||||
let mut lower = self.lower.borrow_mut();
|
||||
let mut buffer = vec![0; self.mtu];
|
||||
match lower.recv(&mut buffer[..]) {
|
||||
Ok(size) => {
|
||||
buffer.resize(size, 0);
|
||||
f(&buffer)
|
||||
}
|
||||
Err(ref err) if err.kind() == io::ErrorKind::WouldBlock => {
|
||||
Err(Error::Exhausted)
|
||||
}
|
||||
Err(err) => panic!("{}", err)
|
||||
}
|
||||
f(&self.buffer[..])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue