Sync mio TCP and libstd TCP APIs
* Rename `take_socket_error` to `take_error`, tweak return type.
* Add `property` accessors in addition to `set_property`
* Rename `set_keepalive` to `set_keepalive_ms` to make room for `Duration` later
on.
Closes #458
diff --git a/.travis.yml b/.travis.yml
index d69ad85..3c7cbd9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,7 @@
- stable
# The following Rust version represents the oldest supported version of Mio.
# This value should not be changed without prior discussion.
- - 1.8.0
+ - 1.9.0
os:
- linux
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1312c46..94e6357 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,7 @@
* Shift primary API towards `Poll`
* `EventLoop` and types to `deprecated` mod. All contents of the
`deprecated` mod will be removed by Mio 1.0.
-* Increase minimum supported Rust version to 1.8.0
+* Increase minimum supported Rust version to 1.9.0
* Deprecate unix domain socket implementation in favor of using a
version external to Mio. For example: https://github.com/alexcrichton/mio-uds.
* Remove various types now included in `std`
diff --git a/Cargo.toml b/Cargo.toml
index 3d02f64..d28c746 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,7 +21,7 @@
lazycell = "0.4.0"
log = "0.3.1"
slab = "0.3.0"
-net2 = { version = "0.2.19", default-features = false }
+net2 = "0.2.19"
[target.'cfg(unix)'.dependencies]
nix = "0.6.0"
diff --git a/src/net/tcp.rs b/src/net/tcp.rs
index 672747d..90b9dc3 100644
--- a/src/net/tcp.rs
+++ b/src/net/tcp.rs
@@ -71,14 +71,22 @@
})
}
+ /// Returns the socket address of the remote peer of this TCP connection.
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
self.sys.peer_addr()
}
+ /// Returns the socket address of the local half of this TCP connection.
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.sys.local_addr()
}
+ /// Creates a new independently owned handle to the underlying socket.
+ ///
+ /// The returned `TcpStream` is a reference to the same stream that this
+ /// object references. Both handles will read and write the same stream of
+ /// data, and options set on one stream will be propagated to the other
+ /// stream.
pub fn try_clone(&self) -> io::Result<TcpStream> {
self.sys.try_clone().map(|s| {
TcpStream {
@@ -87,20 +95,86 @@
}
})
}
+
+ /// Shuts down the read, write, or both halves of this connection.
+ ///
+ /// This function will cause all pending and future I/O on the specified
+ /// portions to return immediately with an appropriate value (see the
+ /// documentation of `Shutdown`).
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.sys.shutdown(how)
}
+ /// Sets the value of the `TCP_NODELAY` option on this socket.
+ ///
+ /// If set, this option disables the Nagle algorithm. This means that
+ /// segments are always sent as soon as possible, even if there is only a
+ /// small amount of data. When not set, data is buffered until there is a
+ /// sufficient amount to send out, thereby avoiding the frequent sending of
+ /// small packets.
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
self.sys.set_nodelay(nodelay)
}
- pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
- self.sys.set_keepalive(seconds)
+ /// Gets the value of the `TCP_NODELAY` option on this socket.
+ ///
+ /// For more information about this option, see [`set_nodelay`][link].
+ ///
+ /// [link]: #method.set_nodelay
+ pub fn nodelay(&self) -> io::Result<bool> {
+ self.sys.nodelay()
}
- pub fn take_socket_error(&self) -> io::Result<()> {
- self.sys.take_socket_error()
+ /// Sets whether keepalive messages are enabled to be sent on this socket.
+ ///
+ /// On Unix, this option will set the `SO_KEEPALIVE` as well as the
+ /// `TCP_KEEPALIVE` or `TCP_KEEPIDLE` option (depending on your platform).
+ /// On Windows, this will set the `SIO_KEEPALIVE_VALS` option.
+ ///
+ /// If `None` is specified then keepalive messages are disabled, otherwise
+ /// the number of milliseconds specified will be the time to remain idle
+ /// before sending a TCP keepalive probe.
+ ///
+ /// Some platforms specify this value in seconds, so sub-second millisecond
+ /// specifications may be omitted.
+ pub fn set_keepalive_ms(&self, keepalive: Option<u32>) -> io::Result<()> {
+ self.sys.set_keepalive_ms(keepalive)
+ }
+
+ /// Returns whether keepalive messages are enabled on this socket, and if so
+ /// the amount of milliseconds between them.
+ ///
+ /// For more information about this option, see [`set_keepalive_ms`][link].
+ ///
+ /// [link]: #method.set_keepalive_ms
+ pub fn keepalive_ms(&self) -> io::Result<Option<u32>> {
+ self.sys.keepalive_ms()
+ }
+
+ /// Sets the value for the `IP_TTL` option on this socket.
+ ///
+ /// This value sets the time-to-live field that is used in every packet sent
+ /// from this socket.
+ pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+ self.sys.set_ttl(ttl)
+ }
+
+ /// Gets the value of the `IP_TTL` option for this socket.
+ ///
+ /// For more information about this option, see [`set_ttl`][link].
+ ///
+ /// [link]: #method.set_ttl
+ pub fn ttl(&self) -> io::Result<u32> {
+ self.sys.ttl()
+ }
+
+ /// Get the value of the `SO_ERROR` option on this socket.
+ ///
+ /// This will retrieve the stored error in the underlying socket, clearing
+ /// the field in the process. This can be useful for checking errors between
+ /// calls.
+ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+ self.sys.take_error()
}
}
@@ -253,10 +327,16 @@
})
}
+ /// Returns the local socket address of this listener.
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.sys.local_addr()
}
+ /// Creates a new independently owned handle to the underlying socket.
+ ///
+ /// The returned `TcpListener` is a reference to the same socket that this
+ /// object references. Both handles can be used to accept incoming
+ /// connections and options set on one listener will affect the other.
pub fn try_clone(&self) -> io::Result<TcpListener> {
self.sys.try_clone().map(|s| {
TcpListener {
@@ -266,8 +346,51 @@
})
}
- pub fn take_socket_error(&self) -> io::Result<()> {
- self.sys.take_socket_error()
+ /// Sets the value for the `IP_TTL` option on this socket.
+ ///
+ /// This value sets the time-to-live field that is used in every packet sent
+ /// from this socket.
+ pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+ self.sys.set_ttl(ttl)
+ }
+
+ /// Gets the value of the `IP_TTL` option for this socket.
+ ///
+ /// For more information about this option, see [`set_ttl`][link].
+ ///
+ /// [link]: #method.set_ttl
+ pub fn ttl(&self) -> io::Result<u32> {
+ self.sys.ttl()
+ }
+
+ /// Sets the value for the `IPV6_V6ONLY` option on this socket.
+ ///
+ /// If this is set to `true` then the socket is restricted to sending and
+ /// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
+ /// can bind the same port at the same time.
+ ///
+ /// If this is set to `false` then the socket can be used to send and
+ /// receive packets from an IPv4-mapped IPv6 address.
+ pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+ self.sys.set_only_v6(only_v6)
+ }
+
+ /// Gets the value of the `IPV6_V6ONLY` option for this socket.
+ ///
+ /// For more information about this option, see [`set_only_v6`][link].
+ ///
+ /// [link]: #method.set_only_v6
+ pub fn only_v6(&self) -> io::Result<bool> {
+ self.sys.only_v6()
+ }
+
+ /// Get the value of the `SO_ERROR` option on this socket.
+ ///
+ /// This will retrieve the stored error in the underlying socket, clearing
+ /// the field in the process. This can be useful for checking errors between
+ /// calls.
+ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+ self.sys.take_error()
}
}
diff --git a/src/sys/unix/tcp.rs b/src/sys/unix/tcp.rs
index ccac224..b9505b8 100644
--- a/src/sys/unix/tcp.rs
+++ b/src/sys/unix/tcp.rs
@@ -5,9 +5,6 @@
use libc;
use net2::TcpStreamExt;
-#[allow(unused_imports)]
-use net2::TcpListenerExt;
-
use {io, Evented, Ready, Poll, PollOpt, Token};
use sys::unix::eventedfd::EventedFd;
@@ -59,20 +56,31 @@
}
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
- TcpStreamExt::set_nodelay(&self.inner, nodelay)
+ self.inner.set_nodelay(nodelay)
}
- pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
- self.inner.set_keepalive_ms(seconds.map(|s| s * 1000))
+ pub fn nodelay(&self) -> io::Result<bool> {
+ self.inner.nodelay()
}
- pub fn take_socket_error(&self) -> io::Result<()> {
- self.inner.take_error().and_then(|e| {
- match e {
- Some(e) => Err(e),
- None => Ok(())
- }
- })
+ pub fn set_keepalive_ms(&self, millis: Option<u32>) -> io::Result<()> {
+ self.inner.set_keepalive_ms(millis)
+ }
+
+ pub fn keepalive_ms(&self) -> io::Result<Option<u32>> {
+ self.inner.keepalive_ms()
+ }
+
+ pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+ self.inner.set_ttl(ttl)
+ }
+
+ pub fn ttl(&self) -> io::Result<u32> {
+ self.inner.ttl()
+ }
+
+ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+ self.inner.take_error()
}
}
@@ -157,13 +165,24 @@
})
}
- pub fn take_socket_error(&self) -> io::Result<()> {
- self.inner.take_error().and_then(|e| {
- match e {
- Some(e) => Err(e),
- None => Ok(())
- }
- })
+ pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+ self.inner.set_only_v6(only_v6)
+ }
+
+ pub fn only_v6(&self) -> io::Result<bool> {
+ self.inner.only_v6()
+ }
+
+ pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+ self.inner.set_ttl(ttl)
+ }
+
+ pub fn ttl(&self) -> io::Result<u32> {
+ self.inner.ttl()
+ }
+
+ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+ self.inner.take_error()
}
}
diff --git a/src/sys/windows/tcp.rs b/src/sys/windows/tcp.rs
index a30aea9..32c73f0 100644
--- a/src/sys/windows/tcp.rs
+++ b/src/sys/windows/tcp.rs
@@ -7,7 +7,7 @@
use io::would_block;
use miow::iocp::CompletionStatus;
use miow::net::*;
-use net2::{self, TcpBuilder};
+use net2::{TcpBuilder, TcpStreamExt as Net2TcpExt};
use net::tcp::Shutdown;
use winapi::*;
@@ -129,21 +129,31 @@
}
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
- net2::TcpStreamExt::set_nodelay(&self.imp.inner.socket, nodelay)
+ self.imp.inner.socket.set_nodelay(nodelay)
}
- pub fn set_keepalive(&self, seconds: Option<u32>) -> io::Result<()> {
- let dur = seconds.map(|s| s * 1000);
- net2::TcpStreamExt::set_keepalive_ms(&self.imp.inner.socket, dur)
+ pub fn nodelay(&self) -> io::Result<bool> {
+ self.imp.inner.socket.nodelay()
}
- pub fn take_socket_error(&self) -> io::Result<()> {
- net2::TcpStreamExt::take_error(&self.imp.inner.socket).and_then(|e| {
- match e {
- Some(e) => Err(e),
- None => Ok(())
- }
- })
+ pub fn set_keepalive_ms(&self, millis: Option<u32>) -> io::Result<()> {
+ self.imp.inner.socket.set_keepalive_ms(millis)
+ }
+
+ pub fn keepalive_ms(&self) -> io::Result<Option<u32>> {
+ self.imp.inner.socket.keepalive_ms()
+ }
+
+ pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+ self.imp.inner.socket.set_ttl(ttl)
+ }
+
+ pub fn ttl(&self) -> io::Result<u32> {
+ self.imp.inner.socket.ttl()
+ }
+
+ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+ self.imp.inner.socket.take_error()
}
fn inner(&self) -> MutexGuard<StreamInner> {
@@ -507,13 +517,24 @@
})
}
- pub fn take_socket_error(&self) -> io::Result<()> {
- net2::TcpListenerExt::take_error(&self.imp.inner.socket).and_then(|e| {
- match e {
- Some(e) => Err(e),
- None => Ok(())
- }
- })
+ pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
+ self.imp.inner.socket.set_only_v6(only_v6)
+ }
+
+ pub fn only_v6(&self) -> io::Result<bool> {
+ self.imp.inner.socket.only_v6()
+ }
+
+ pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
+ self.imp.inner.socket.set_ttl(ttl)
+ }
+
+ pub fn ttl(&self) -> io::Result<u32> {
+ self.imp.inner.socket.ttl()
+ }
+
+ pub fn take_error(&self) -> io::Result<Option<io::Error>> {
+ self.imp.inner.socket.take_error()
}
fn inner(&self) -> MutexGuard<ListenerInner> {