Reimplement {RawSocket,TapInterface}::receive correctly.

v0.7.x
whitequark 2017-11-06 09:38:44 +00:00
parent 7039ec8b04
commit c2994b9757
3 changed files with 38 additions and 28 deletions

View File

@ -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));

View File

@ -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[..])
}
}

View File

@ -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[..])
}
}