self.0.nodelay()
}
- /// 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 duration specified will be the time to remain idle before sending a
- /// TCP keepalive probe.
- ///
- /// Some platforms specify this value in seconds, so sub-second
- /// specifications may be omitted.
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
- self.0.set_keepalive(keepalive)
- }
-
- /// Returns whether keepalive messages are enabled on this socket, and if so
- /// the duration of time between them.
- ///
- /// For more information about this option, see [`set_keepalive`][link].
- ///
- /// [link]: #tymethod.set_keepalive
- #[stable(feature = "net2_mutators", since = "1.9.0")]
- pub fn keepalive(&self) -> io::Result<Option<Duration>> {
- self.0.keepalive()
- }
-
/// 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
assert_eq!(false, t!(stream.nodelay()));
}
- #[test]
- fn keepalive() {
- let addr = next_test_ip4();
- let _listener = t!(TcpListener::bind(&addr));
-
- let stream = t!(TcpStream::connect(&("localhost", addr.port())));
- let dur = Duration::new(15410, 0);
-
- assert_eq!(None, t!(stream.keepalive()));
- t!(stream.set_keepalive(Some(dur)));
- assert_eq!(Some(dur), t!(stream.keepalive()));
- t!(stream.set_keepalive(None));
- assert_eq!(None, t!(stream.keepalive()));
- }
-
#[test]
fn ttl() {
let ttl = 100;
use ffi::{CStr, CString};
use fmt;
use io::{self, Error, ErrorKind};
-use libc::{c_int, c_char, c_void};
+use libc::{c_int, c_char, c_void, c_uint};
use mem;
#[allow(deprecated)]
use net::{SocketAddr, Shutdown, IpAddr, Ipv4Addr, Ipv6Addr};
}
#[cfg(target_os = "android")]
-fn to_ipv6mr_interface(value: u32) -> c::c_int {
- value as c::c_int
+fn to_ipv6mr_interface(value: u32) -> c_int {
+ value as c_int
}
#[cfg(not(target_os = "android"))]
-fn to_ipv6mr_interface(value: u32) -> c::c_uint {
- value as c::c_uint
+fn to_ipv6mr_interface(value: u32) -> c_uint {
+ value as c_uint
}
////////////////////////////////////////////////////////////////////////////////
}
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
- setsockopt(&self.inner, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c_int)
+ self.inner.set_nodelay(nodelay)
}
pub fn nodelay(&self) -> io::Result<bool> {
- let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_TCP, c::TCP_NODELAY));
- Ok(raw != 0)
- }
-
- pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
- self.inner.set_keepalive(keepalive)
- }
-
- pub fn keepalive(&self) -> io::Result<Option<Duration>> {
- self.inner.keepalive()
+ self.inner.nodelay()
}
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
#[cfg(not(target_os = "linux"))]
const SOCK_CLOEXEC: c_int = 0;
-#[cfg(any(target_os = "openbsd", taret_os = "freebsd"))]
-use libc::SO_KEEPALIVE as TCP_KEEPALIVE;
-#[cfg(any(target_os = "macos", taret_os = "ios"))]
-use libc::TCP_KEEPALIVE;
-#[cfg(not(any(target_os = "openbsd",
- target_os = "freebsd",
- target_os = "macos",
- target_os = "ios")))]
-use libc::TCP_KEEPIDLE as TCP_KEEPALIVE;
-
pub struct Socket(FileDesc);
pub fn init() {}
Ok(())
}
- pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
- try!(setsockopt(self,
- libc::SOL_SOCKET,
- libc::SO_KEEPALIVE,
- keepalive.is_some() as libc::c_int));
- if let Some(dur) = keepalive {
- let mut raw = dur.as_secs();
- if dur.subsec_nanos() > 0 {
- raw = raw.saturating_add(1);
- }
-
- let raw = if raw > libc::c_int::max_value() as u64 {
- libc::c_int::max_value()
- } else {
- raw as libc::c_int
- };
-
- try!(setsockopt(self, libc::IPPROTO_TCP, TCP_KEEPALIVE, raw));
- }
-
- Ok(())
+ pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+ setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int)
}
- pub fn keepalive(&self) -> io::Result<Option<Duration>> {
- let raw: c_int = try!(getsockopt(self, libc::SOL_SOCKET, libc::SO_KEEPALIVE));
- if raw == 0 {
- return Ok(None);
- }
-
- let raw: c_int = try!(getsockopt(self, libc::IPPROTO_TCP, TCP_KEEPALIVE));
- Ok(Some(Duration::from_secs(raw as u64)))
+ pub fn nodelay(&self) -> io::Result<bool> {
+ let raw: c_int = try!(getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY));
+ Ok(raw != 0)
}
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
#![allow(bad_style)]
#![cfg_attr(test, allow(dead_code))]
-use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort};
+use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort,};
use os::raw::{c_char, c_ulonglong};
use libc::{wchar_t, size_t, c_void};
use ptr;
pub type socklen_t = c_int;
pub type ADDRESS_FAMILY = USHORT;
-pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE =
- Option<unsafe extern "system" fn(dwError: DWORD,
- cbTransferred: DWORD,
- lpOverlapped: LPWSAOVERLAPPED,
- dwFlags: DWORD)>;
-pub type LPWSAOVERLAPPED = *mut OVERLAPPED;
-
pub const TRUE: BOOL = 1;
pub const FALSE: BOOL = 0;
pub const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000;
-pub const SIO_KEEPALIVE_VALS: DWORD = 0x98000004;
pub const FIONBIO: c_ulong = 0x8004667e;
#[repr(C)]
pub const SO_RCVTIMEO: c_int = 0x1006;
pub const SO_SNDTIMEO: c_int = 0x1005;
pub const SO_REUSEADDR: c_int = 0x0004;
+pub const IPPROTO_IP: c_int = 0;
+pub const IPPROTO_TCP: c_int = 6;
+pub const IPPROTO_IPV6: c_int = 41;
+pub const TCP_NODELAY: c_int = 0x0001;
+pub const IP_TTL: c_int = 4;
+pub const IPV6_V6ONLY: c_int = 27;
+pub const SO_ERROR: c_int = 0x1007;
+pub const SO_BROADCAST: c_int = 0x0020;
+pub const IP_MULTICAST_LOOP: c_int = 11;
+pub const IPV6_MULTICAST_LOOP: c_int = 11;
+pub const IP_MULTICAST_TTL: c_int = 10;
+pub const IP_ADD_MEMBERSHIP: c_int = 12;
+pub const IP_DROP_MEMBERSHIP: c_int = 13;
+pub const IPV6_ADD_MEMBERSHIP: c_int = 12;
+pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
+
+#[repr(C)]
+pub struct ip_mreq {
+ pub imr_multiaddr: in_addr,
+ pub imr_interface: in_addr,
+}
+
+#[repr(C)]
+pub struct ipv6_mreq {
+ pub ipv6mr_multiaddr: in6_addr,
+ pub ipv6mr_interface: c_uint,
+}
pub const VOLUME_NAME_DOS: DWORD = 0x0;
pub const MOVEFILE_REPLACE_EXISTING: DWORD = 1;
pub s6_addr: [u8; 16],
}
-#[repr(C)]
-pub struct tcp_keepalive {
- pub onoff: c_ulong,
- pub keepalivetime: c_ulong,
- pub keepaliveinterval: c_ulong,
-}
-
#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
pub enum UNWIND_HISTORY_TABLE {}
lpProtocolInfo: LPWSAPROTOCOL_INFO,
g: GROUP,
dwFlags: DWORD) -> SOCKET;
- pub fn WSAIoctl(s: SOCKET,
- dwIoControlCode: DWORD,
- lpvInBuffer: LPVOID,
- cbInBuffer: DWORD,
- lpvOutBuffer: LPVOID,
- cbOutBuffer: DWORD,
- lpcbBytesReturned: LPDWORD,
- lpOverlapped: LPWSAOVERLAPPED,
- lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE)
- -> c_int;
- pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut u_long) -> c_int;
+ pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int;
pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN;
use cmp;
use io;
-use libc::{c_int, c_void};
+use libc::{c_int, c_void, c_ulong};
use mem;
use net::{SocketAddr, Shutdown};
use num::One;
Ok(())
}
- pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
- let ms = keepalive.map(sys::dur2timeout).unwrap_or(c::INFINITE);
- let ka = c::tcp_keepalive {
- onoff: keepalive.is_some() as c::c_ulong,
- keepalivetime: ms as c::c_ulong,
- keepaliveinterval: ms as c::c_ulong,
- };
- sys::cvt(unsafe {
- c::WSAIoctl(self.0,
- c::SIO_KEEPALIVE_VALS,
- &ka as *const _ as *mut _,
- mem::size_of_val(&ka) as c::DWORD,
- 0 as *mut _,
- 0,
- 0 as *mut _,
- 0 as *mut _,
- None)
- }).map(|_| ())
- }
-
- pub fn keepalive(&self) -> io::Result<Option<Duration>> {
- let mut ka = c::tcp_keepalive {
- onoff: 0,
- keepalivetime: 0,
- keepaliveinterval: 0,
- };
- try!(sys::cvt(unsafe {
- WSAIoctl(self.0,
- c::SIO_KEEPALIVE_VALS,
- 0 as *mut _,
- 0,
- &mut ka as *mut _ as *mut _,
- mem::size_of_val(&ka) as c::DWORD,
- 0 as *mut _,
- 0 as *mut _,
- None)
- }));
-
- if ka.onoff == 0 {
- Ok(None)
+ pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
+ let mut nonblocking = nonblocking as c_ulong;
+ let r = unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) };
+ if r == 0 {
+ Ok(())
} else {
- let secs = ka.keepaliveinterval / 1000;
- let nsec = (ka.keepaliveinterval % 1000) * 1000000;
- Ok(Some(Duration::new(secs as u64, nsec as u32)))
+ Err(io::Error::last_os_error())
}
}
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- let mut nonblocking = nonblocking as c::c_ulong;
- sys::cvt(unsafe {
- c::ioctlsocket(self.0, c::FIONBIO as c::c_int, &mut nonblocking)
- }).map(|_| ())
+ pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
+ net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BYTE)
+ }
+
+ pub fn nodelay(&self) -> io::Result<bool> {
+ let raw: c::BYTE = try!(net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY));
+ Ok(raw != 0)
}
}