From 4fa3407d54dfb5ac6def01e910860e09e1483f8c Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Tue, 4 Jul 2017 16:13:40 +0200 Subject: [PATCH 01/10] WIP: Now for the error handling --- Cargo.toml | 9 ++++++- src/lib.rs | 62 ++++++++++++++++++++++++++++++++++++++++++----- src/raw.rs | 4 ++-- src/tokio.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 9 deletions(-) create mode 100644 src/tokio.rs diff --git a/Cargo.toml b/Cargo.toml index 6f61e5be4..926380b9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,9 @@ build = "build.rs" [dependencies] libc = "0.2" clippy = { version = "0.0.134", optional = true } +mio = { version = "*", optional = true } +tokio-core = { version = "*", optional = true } +futures = { version = "*", optional = true } [dev-dependencies] tempdir = "0.3" @@ -29,8 +32,12 @@ pcap-savefile-append = [] # This is disabled by default, because it requires libpcap >= 1.5.0. pcap-fopen-offline-precision = [] +# This feature enables access to the function Capture::stream. +# This is disabled by default, because it depends on a tokio and mio +tokio = ["mio", "tokio-core", "futures"] + # A shortcut to enable all features. -full = ["pcap-savefile-append", "pcap-fopen-offline-precision"] +full = ["pcap-savefile-append", "pcap-fopen-offline-precision", "tokio"] [lib] name = "pcap" diff --git a/src/lib.rs b/src/lib.rs index 7d45e246a..c1047db89 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,6 +51,13 @@ #![cfg_attr(feature = "clippy", allow(redundant_closure_call))] extern crate libc; +#[cfg(feature = "tokio")] +extern crate mio; +#[cfg(feature = "tokio")] +extern crate futures; +#[cfg(feature = "tokio")] +#[macro_use] +extern crate tokio_core; use unique::Unique; @@ -62,7 +69,9 @@ use std::path::Path; use std::slice; use std::ops::Deref; use std::mem; +use std::mem::transmute; use std::fmt; +use std::io; #[cfg(not(windows))] use std::os::unix::io::{RawFd, AsRawFd}; @@ -70,6 +79,8 @@ use self::Error::*; mod raw; mod unique; +#[cfg(feature = "tokio")] +mod tokio; /// An error received from pcap #[derive(Debug, Clone, PartialEq, Eq)] @@ -82,6 +93,7 @@ pub enum Error { NoMorePackets, InsufficientMemory, InvalidInputString, + IoError(std::fmt::Error), #[cfg(not(windows))] InvalidRawFd, } @@ -280,7 +292,7 @@ impl fmt::Debug for PacketHeader { impl PartialEq for PacketHeader { fn eq(&self, rhs: &PacketHeader) -> bool { self.ts.tv_sec == rhs.ts.tv_sec && self.ts.tv_usec == rhs.ts.tv_usec && - self.caplen == rhs.caplen && self.len == rhs.len + self.caplen == rhs.caplen && self.len == rhs.len } } @@ -312,11 +324,14 @@ pub enum Precision { /// Phantom type representing an inactive capture handle. pub enum Inactive {} + /// Phantom type representing an active capture handle. pub enum Active {} + /// Phantom type representing an offline capture handle, from a pcap dump file. /// Implements `Activated` because it behaves nearly the same as a live handle. pub enum Offline {} + /// Phantom type representing a dead capture handle. This can be use to create /// new save files that are not generated from an active capture. /// Implements `Activated` because it behaves nearly the same as a live handle. @@ -325,7 +340,9 @@ pub enum Dead {} pub unsafe trait Activated: State {} unsafe impl Activated for Active {} + unsafe impl Activated for Offline {} + unsafe impl Activated for Dead {} /// `Capture`s can be in different states at different times, and in these states they @@ -335,8 +352,11 @@ unsafe impl Activated for Dead {} pub unsafe trait State {} unsafe impl State for Inactive {} + unsafe impl State for Active {} + unsafe impl State for Offline {} + unsafe impl State for Dead {} /// This is a pcap capture handle which is an abstraction over the `pcap_t` provided by pcap. @@ -370,12 +390,12 @@ unsafe impl State for Dead {} /// println!("received packet! {:?}", packet); /// } /// ``` -pub struct Capture { +pub struct Capture { handle: Unique, _marker: PhantomData, } -impl Capture { +impl Capture { fn new(handle: *mut raw::pcap_t) -> Capture { unsafe { Capture { @@ -537,7 +557,7 @@ impl Capture { } ///# Activated captures include `Capture` and `Capture`. -impl Capture { +impl Capture { /// List the datalink types that this captured device supports. pub fn list_datalinks(&self) -> Result, Error> { unsafe { @@ -637,6 +657,36 @@ impl Capture { } } + #[cfg(feature = "tokio")] + fn next_noblock<'a>(&'a mut self, fd: &mut tokio_core::reactor::PollEvented) -> Result, Error> { + if let futures::Async::NotReady = fd.poll_read() { + return Err(IoError(io::Error::new(io::ErrorKind::WouldBlock, "would block"))) + } else { + return match self.next() { + Ok(p) => Ok(p), + Err(TimeoutExpired) => { + fd.need_read(); + Err(IoError(io::Error::new(io::ErrorKind::WouldBlock, "would block"))) + } + Err(e) => Err(e) + } + } + } + + #[cfg(feature = "tokio")] + pub fn stream(self, handle: &tokio_core::reactor::Handle, codec: C) -> Result, Error> { + unsafe { + with_errbuf(|err| unsafe { + if raw::pcap_setnonblock(*self.handle, 1, err) != 0 { + return Err(Error::new(err)); + } + Ok(self) + }); + let fd = raw::pcap_get_selectable_fd(*self.handle); + tokio::PacketStream::new(self, fd, handle, codec) + } + } + /// Adds a filter to the capture using the given BPF program string. Internally /// this is compiled using `pcap_compile()`. /// @@ -697,7 +747,7 @@ impl AsRawFd for Capture { } } -impl Drop for Capture { +impl Drop for Capture { fn drop(&mut self) { unsafe { raw::pcap_close(*self.handle) } } @@ -747,7 +797,7 @@ fn cstr_to_string(ptr: *const libc::c_char) -> Result, Error> { let string = if ptr.is_null() { None } else { - Some(unsafe {CStr::from_ptr(ptr as _)}.to_str()?.to_owned()) + Some(unsafe { CStr::from_ptr(ptr as _) }.to_str()?.to_owned()) }; Ok(string) } diff --git a/src/raw.rs b/src/raw.rs index 75c43baff..1d67b1cde 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -129,7 +129,7 @@ extern "C" { pub fn pcap_setfilter(arg1: *mut pcap_t, arg2: *mut bpf_program) -> c_int; pub fn pcap_setdirection(arg1: *mut pcap_t, arg2: pcap_direction_t) -> c_int; // pub fn pcap_getnonblock(arg1: *mut pcap_t, arg2: *mut c_char) -> c_int; - // pub fn pcap_setnonblock(arg1: *mut pcap_t, arg2: c_int, arg3: *mut c_char) -> c_int; + pub fn pcap_setnonblock(arg1: *mut pcap_t, arg2: c_int, arg3: *mut c_char) -> c_int; pub fn pcap_sendpacket(arg1: *mut pcap_t, arg2: *const c_uchar, arg3: c_int) -> c_int; // pub fn pcap_statustostr(arg1: c_int) -> *const c_char; // pub fn pcap_strerror(arg1: c_int) -> *const c_char; @@ -170,7 +170,7 @@ extern "C" { // pub fn pcap_lib_version() -> *const c_char; // pub fn bpf_image(arg1: *const bpf_insn, arg2: c_int) -> *mut c_char; // pub fn bpf_dump(arg1: *const bpf_program, arg2: c_int) -> (); - // pub fn pcap_get_selectable_fd(arg1: *mut pcap_t) -> c_int; + pub fn pcap_get_selectable_fd(arg1: *mut pcap_t) -> c_int; } #[cfg(windows)] diff --git a/src/tokio.rs b/src/tokio.rs new file mode 100644 index 000000000..894516b6a --- /dev/null +++ b/src/tokio.rs @@ -0,0 +1,68 @@ +use mio::{Ready, Poll, PollOpt, Token}; +use mio::event::Evented; +use mio::unix::EventedFd; +use std::io; +#[cfg(not(windows))] +use std::os::unix::io::{RawFd, AsRawFd}; +use super::Activated; +use super::Packet; +use super::Error; +use super::State; +use super::Capture; +use tokio_core; +use futures; + +pub struct SelectableFd { + fd: RawFd +} + +impl Evented for SelectableFd { + fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) + -> io::Result<()> + { + EventedFd(&self.fd).register(poll, token, interest, opts) + } + + fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) + -> io::Result<()> + { + EventedFd(&self.fd).reregister(poll, token, interest, opts) + } + + fn deregister(&self, poll: &Poll) -> io::Result<()> { + EventedFd(&self.fd).deregister(poll) + } +} + +pub trait PacketCodec { + type Type; + fn decode<'a>(&mut self, packet: Packet<'a>) -> Result; +} + +pub struct PacketStream { + cap: Capture, + fd: tokio_core::reactor::PollEvented, + codec: C, +} + +impl PacketStream { + pub fn new(cap: Capture, fd: RawFd, handle: &tokio_core::reactor::Handle, codec: C) -> Result, Error> { + Ok(PacketStream { cap: cap, fd: tokio_core::reactor::PollEvented::new(SelectableFd { fd: fd }, handle)?, codec: codec }) + } +} + +impl<'a, T: Activated + ? Sized, C: PacketCodec> futures::Stream for PacketStream { + type Item = C::Type; + type Error = Error; + fn poll(&mut self) -> futures::Poll, Self::Error> { + let p = match self.cap.next_noblock(&mut self.fd) { + Ok(t) => t, + Err(Error::IoError(ref e)) if e.kind() == std::io::ErrorKind::WouldBlock => { + return Ok(futures::Async::NotReady) + } + Err(e) => return Err(e.into()) + }; + let frame = try!(self.codec.decode(p)); + Ok(futures::Async::Ready(Some(frame))) + } +} \ No newline at end of file From 1661e9d57d7bcfda926c0dc25acacb2c522f1034 Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Tue, 4 Jul 2017 17:47:12 +0200 Subject: [PATCH 02/10] Tokio/futures based streaming with simple example --- Cargo.toml | 4 ++++ src/lib.rs | 41 ++++++++++++++++++++++++++++++----------- src/tokio.rs | 6 +++--- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 926380b9c..d5e9ed523 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,3 +61,7 @@ path = "examples/savefile.rs" [[example]] name = "getstatistics" path = "examples/getstatistics.rs" + +[[example]] +name = "streamlisten" +path = "examples/streamlisten.rs" diff --git a/src/lib.rs b/src/lib.rs index c1047db89..00520f4a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,7 +56,6 @@ extern crate mio; #[cfg(feature = "tokio")] extern crate futures; #[cfg(feature = "tokio")] -#[macro_use] extern crate tokio_core; use unique::Unique; @@ -69,8 +68,8 @@ use std::path::Path; use std::slice; use std::ops::Deref; use std::mem; -use std::mem::transmute; use std::fmt; +#[cfg(feature = "tokio")] use std::io; #[cfg(not(windows))] use std::os::unix::io::{RawFd, AsRawFd}; @@ -80,10 +79,10 @@ use self::Error::*; mod raw; mod unique; #[cfg(feature = "tokio")] -mod tokio; +pub mod tokio; /// An error received from pcap -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug)] pub enum Error { MalformedError(std::str::Utf8Error), InvalidString, @@ -91,9 +90,10 @@ pub enum Error { InvalidLinktype, TimeoutExpired, NoMorePackets, + NonNonBlock, InsufficientMemory, InvalidInputString, - IoError(std::fmt::Error), + IoError(std::io::Error), #[cfg(not(windows))] InvalidRawFd, } @@ -115,9 +115,11 @@ impl fmt::Display for Error { PcapError(ref e) => write!(f, "libpcap error: {}", e), InvalidLinktype => write!(f, "invalid or unknown linktype"), TimeoutExpired => write!(f, "timeout expired while reading from a live capture"), + NonNonBlock => write!(f, "must be in non-blocking mode to function"), NoMorePackets => write!(f, "no more packets to read from the file"), InsufficientMemory => write!(f, "insufficient memory"), InvalidInputString => write!(f, "invalid input string (internal null)"), + IoError(ref e) => write!(f, "io error occurred: {}", e), #[cfg(not(windows))] InvalidRawFd => write!(f, "invalid raw file descriptor provided"), } @@ -132,9 +134,11 @@ impl std::error::Error for Error { InvalidString => "libpcap returned a null string", InvalidLinktype => "invalid or unknown linktype", TimeoutExpired => "timeout expired while reading from a live capture", + NonNonBlock => "must be in non-blocking mode to function", NoMorePackets => "no more packets to read from the file", InsufficientMemory => "insufficient memory", InvalidInputString => "invalid input string (internal null)", + IoError(..) => "io error occurred", #[cfg(not(windows))] InvalidRawFd => "invalid raw file descriptor provided", } @@ -160,6 +164,12 @@ impl From for Error { } } +impl From for Error { + fn from(obj: std::io::Error) -> Error { + IoError(obj) + } +} + #[derive(Debug)] /// A network device name and (potentially) pcap's description of it. pub struct Device { @@ -391,6 +401,7 @@ unsafe impl State for Dead {} /// } /// ``` pub struct Capture { + nonblock: bool, handle: Unique, _marker: PhantomData, } @@ -399,6 +410,7 @@ impl Capture { fn new(handle: *mut raw::pcap_t) -> Capture { unsafe { Capture { + nonblock: false, handle: Unique::new(handle), _marker: PhantomData, } @@ -675,13 +687,10 @@ impl Capture { #[cfg(feature = "tokio")] pub fn stream(self, handle: &tokio_core::reactor::Handle, codec: C) -> Result, Error> { + if !self.nonblock { + return Err(NonNonBlock); + } unsafe { - with_errbuf(|err| unsafe { - if raw::pcap_setnonblock(*self.handle, 1, err) != 0 { - return Err(Error::new(err)); - } - Ok(self) - }); let fd = raw::pcap_get_selectable_fd(*self.handle); tokio::PacketStream::new(self, fd, handle, codec) } @@ -720,6 +729,16 @@ impl Capture { raw::pcap_sendpacket(*self.handle, buf.as_ptr() as _, buf.len() as _) == 0 }) } + + pub fn setnonblock(mut self) -> Result, Error> { + with_errbuf(|err| unsafe { + if raw::pcap_setnonblock(*self.handle, 1, err) != 0 { + return Err(Error::new(err)); + } + self.nonblock = true; + Ok(self) + }) + } } impl Capture { diff --git a/src/tokio.rs b/src/tokio.rs index 894516b6a..2cf0b2f8d 100644 --- a/src/tokio.rs +++ b/src/tokio.rs @@ -3,7 +3,7 @@ use mio::event::Evented; use mio::unix::EventedFd; use std::io; #[cfg(not(windows))] -use std::os::unix::io::{RawFd, AsRawFd}; +use std::os::unix::io::RawFd; use super::Activated; use super::Packet; use super::Error; @@ -57,12 +57,12 @@ impl<'a, T: Activated + ? Sized, C: PacketCodec> futures::Stream for PacketStrea fn poll(&mut self) -> futures::Poll, Self::Error> { let p = match self.cap.next_noblock(&mut self.fd) { Ok(t) => t, - Err(Error::IoError(ref e)) if e.kind() == std::io::ErrorKind::WouldBlock => { + Err(Error::IoError(ref e)) if e.kind() == ::std::io::ErrorKind::WouldBlock => { return Ok(futures::Async::NotReady) } Err(e) => return Err(e.into()) }; - let frame = try!(self.codec.decode(p)); + let frame = self.codec.decode(p)?; Ok(futures::Async::Ready(Some(frame))) } } \ No newline at end of file From 7f2ec95446c2ec7e5dc574b051913ea5b91c2c9b Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Tue, 4 Jul 2017 17:48:00 +0200 Subject: [PATCH 03/10] Missing example file --- examples/streamlisten.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 examples/streamlisten.rs diff --git a/examples/streamlisten.rs b/examples/streamlisten.rs new file mode 100644 index 000000000..2e3fb8648 --- /dev/null +++ b/examples/streamlisten.rs @@ -0,0 +1,39 @@ +extern crate pcap; +extern crate futures; +extern crate tokio_core; + +use pcap::{Capture, Packet, Error}; +use pcap::tokio::PacketCodec; +use tokio_core::reactor::Core; +use futures::stream::Stream; + +pub struct SimpleDumpCodec; + +impl PacketCodec for SimpleDumpCodec{ + type Type = String; + + fn decode<'p>(&mut self, packet: Packet<'p>) -> Result { + Ok(format!("{:?}", packet)) + + } +} + +fn ma1n() -> Result<(),Error> { + let mut core = Core::new().unwrap(); + let handle = core.handle(); + let cap = Capture::from_device("en0")?.open()?.setnonblock()?; + let s = cap.stream(&handle, SimpleDumpCodec{})?; + let done = s.for_each(move |s| { + println!("{:?}", s); + Ok(()) + }); + core.run(done).unwrap(); + Ok(()) +} + +fn main() { + match ma1n() { + Ok(()) => (), + Err(e) => println!("{:?}", e), + } +} From 45760598ad5c71c05f3d9b2050975360ce376fa2 Mon Sep 17 00:00:00 2001 From: Roxxik Date: Sat, 15 Jul 2017 01:58:16 +0200 Subject: [PATCH 04/10] Update streamlisten.rs use the default device instead of en0 (for me the default device is enp9s0 for others maybe eth0 or wlan0 or wlp8s0, so let pcap choose) an alternative might be to let the user sepcify a device on the command line, but this is just an example --- examples/streamlisten.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/streamlisten.rs b/examples/streamlisten.rs index 2e3fb8648..ba79799b0 100644 --- a/examples/streamlisten.rs +++ b/examples/streamlisten.rs @@ -2,7 +2,7 @@ extern crate pcap; extern crate futures; extern crate tokio_core; -use pcap::{Capture, Packet, Error}; +use pcap::{Capture, Packet, Error, Device}; use pcap::tokio::PacketCodec; use tokio_core::reactor::Core; use futures::stream::Stream; @@ -21,7 +21,7 @@ impl PacketCodec for SimpleDumpCodec{ fn ma1n() -> Result<(),Error> { let mut core = Core::new().unwrap(); let handle = core.handle(); - let cap = Capture::from_device("en0")?.open()?.setnonblock()?; + let cap = Capture::from_device(Device::lookup()?)?.open()?.setnonblock()?; let s = cap.stream(&handle, SimpleDumpCodec{})?; let done = s.for_each(move |s| { println!("{:?}", s); From a14bafd60a77762d71e64165f71ba54354b4de56 Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Sat, 15 Jul 2017 19:20:03 +0200 Subject: [PATCH 05/10] Add feature=tokio to travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index fbd6b68ce..325273d10 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,6 @@ before_install: brew install homebrew/dupes/libpcap; fi script: - - cargo build -v $FLAGS - - cargo test -v $FLAGS + - cargo build --features tokio -v $FLAGS + - cargo test --features tokio -v $FLAGS - cargo doc --no-deps From 2ff1cb56b4097a15548b17c1226972a94120111e Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Sat, 15 Jul 2017 19:23:55 +0200 Subject: [PATCH 06/10] Try and fix argument issue with Travis --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 325273d10..0513139ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,6 @@ before_install: brew install homebrew/dupes/libpcap; fi script: - - cargo build --features tokio -v $FLAGS - - cargo test --features tokio -v $FLAGS - - cargo doc --no-deps + - cargo build -v $FLAGS --features tokio + - cargo test -v $FLAGS --features tokio + - cargo doc --no-deps --features tokio From d527b719379ea9cda7e03dbeeac02f5702f10c45 Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Sat, 15 Jul 2017 19:29:35 +0200 Subject: [PATCH 07/10] Try and fix argument issue with Travis --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0513139ec..0202c6dc0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,6 @@ before_install: brew install homebrew/dupes/libpcap; fi script: - - cargo build -v $FLAGS --features tokio - - cargo test -v $FLAGS --features tokio - - cargo doc --no-deps --features tokio + - cargo build -v $FLAGS + - cargo test -v $FLAGS + - cargo doc --no-deps From 0f1cf113aaed89ee16866d06f59f1bc7aa7c9f15 Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Sat, 15 Jul 2017 19:32:58 +0200 Subject: [PATCH 08/10] Fix linux test --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0202c6dc0..b333fe8f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,11 +6,11 @@ addons: matrix: include: - {os: linux, rust: stable, - env: FLAGS=""} + env: FLAGS="--features tokio"} - {os: linux, rust: beta, - env: FLAGS=""} + env: FLAGS="--features tokio"} - {os: linux, rust: nightly, - env: FLAGS="--features clippy"} + env: FLAGS="--features clippy tokio"} - {os: osx, rust: stable, env: FLAGS="--features full" PCAP_LIBDIR=/usr/local/opt/libpcap/lib} - {os: osx, rust: beta, From 1244effec409f601de84e732b071fde228d376de Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Sat, 15 Jul 2017 20:37:38 +0200 Subject: [PATCH 09/10] Convert to ErrorKind --- src/lib.rs | 16 +++++++++++----- src/tokio.rs | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 00520f4a5..ca9f7d28c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,7 +82,7 @@ mod unique; pub mod tokio; /// An error received from pcap -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub enum Error { MalformedError(std::str::Utf8Error), InvalidString, @@ -93,7 +93,7 @@ pub enum Error { NonNonBlock, InsufficientMemory, InvalidInputString, - IoError(std::io::Error), + IoError(std::io::ErrorKind), #[cfg(not(windows))] InvalidRawFd, } @@ -119,7 +119,7 @@ impl fmt::Display for Error { NoMorePackets => write!(f, "no more packets to read from the file"), InsufficientMemory => write!(f, "insufficient memory"), InvalidInputString => write!(f, "invalid input string (internal null)"), - IoError(ref e) => write!(f, "io error occurred: {}", e), + IoError(ref e) => write!(f, "io error occurred: {:?}", e), #[cfg(not(windows))] InvalidRawFd => write!(f, "invalid raw file descriptor provided"), } @@ -166,6 +166,12 @@ impl From for Error { impl From for Error { fn from(obj: std::io::Error) -> Error { + IoError(obj.kind()) + } +} + +impl From for Error { + fn from(obj: std::io::ErrorKind) -> Error { IoError(obj) } } @@ -672,13 +678,13 @@ impl Capture { #[cfg(feature = "tokio")] fn next_noblock<'a>(&'a mut self, fd: &mut tokio_core::reactor::PollEvented) -> Result, Error> { if let futures::Async::NotReady = fd.poll_read() { - return Err(IoError(io::Error::new(io::ErrorKind::WouldBlock, "would block"))) + return Err(IoError(io::ErrorKind::WouldBlock)) } else { return match self.next() { Ok(p) => Ok(p), Err(TimeoutExpired) => { fd.need_read(); - Err(IoError(io::Error::new(io::ErrorKind::WouldBlock, "would block"))) + Err(IoError(io::ErrorKind::WouldBlock)) } Err(e) => Err(e) } diff --git a/src/tokio.rs b/src/tokio.rs index 2cf0b2f8d..a18732475 100644 --- a/src/tokio.rs +++ b/src/tokio.rs @@ -57,7 +57,7 @@ impl<'a, T: Activated + ? Sized, C: PacketCodec> futures::Stream for PacketStrea fn poll(&mut self) -> futures::Poll, Self::Error> { let p = match self.cap.next_noblock(&mut self.fd) { Ok(t) => t, - Err(Error::IoError(ref e)) if e.kind() == ::std::io::ErrorKind::WouldBlock => { + Err(Error::IoError(ref e)) if *e == ::std::io::ErrorKind::WouldBlock => { return Ok(futures::Async::NotReady) } Err(e) => return Err(e.into()) From e2aabba5cb2da0768fed31f9b9a8bbb5879d016c Mon Sep 17 00:00:00 2001 From: Stephan Buys Date: Sat, 15 Jul 2017 21:11:31 +0200 Subject: [PATCH 10/10] Clippy on a fix branch and fravis syntax fix --- .travis.yml | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b333fe8f0..856685e45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ matrix: - {os: linux, rust: beta, env: FLAGS="--features tokio"} - {os: linux, rust: nightly, - env: FLAGS="--features clippy tokio"} + env: FLAGS="--features clippy,tokio"} - {os: osx, rust: stable, env: FLAGS="--features full" PCAP_LIBDIR=/usr/local/opt/libpcap/lib} - {os: osx, rust: beta, diff --git a/Cargo.toml b/Cargo.toml index d5e9ed523..b7e311826 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ build = "build.rs" [dependencies] libc = "0.2" -clippy = { version = "0.0.134", optional = true } +clippy = { version = "*", optional = true, git="https://github.com/kraai/rust-clippy", branch="fix-build" } mio = { version = "*", optional = true } tokio-core = { version = "*", optional = true } futures = { version = "*", optional = true }