]> git.lizzy.rs Git - rust.git/commitdiff
Fix windows
authorSteven Fackler <sfackler@gmail.com>
Sun, 28 Feb 2016 05:05:32 +0000 (21:05 -0800)
committerSteven Fackler <sfackler@gmail.com>
Sun, 28 Feb 2016 17:41:33 +0000 (09:41 -0800)
Also back out keepalive support for TCP since the API is perhaps not
actually what we want. You can't read the interval on Windows, and
we should probably separate the functionality of turning keepalive on
and overriding the interval.

src/libstd/net/tcp.rs
src/libstd/sys/common/net.rs
src/libstd/sys/unix/net.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/net.rs

index b8530c98398c85985659a8b6654d3726ad80a091..0073b8f119afa6b72770a1f8aa717daf537c7edd 100644 (file)
@@ -203,34 +203,6 @@ pub fn nodelay(&self) -> io::Result<bool> {
         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
@@ -1156,21 +1128,6 @@ fn nodelay() {
         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;
index 31d3be453725c2f89634d5f31208f0f3f5f34647..c8738fd1ba52475bb86ae8663012b936f95d4a55 100644 (file)
@@ -14,7 +14,7 @@
 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};
@@ -84,13 +84,13 @@ fn sockaddr_to_addr(storage: &c::sockaddr_storage,
 }
 
 #[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
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -239,20 +239,11 @@ pub fn duplicate(&self) -> io::Result<TcpStream> {
     }
 
     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<()> {
index 7a2ac7257afbcf084dc7b0e7691852dc7820619d..8785da51986dbe1192e3aa8046968c03ba093d80 100644 (file)
 #[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() {}
@@ -179,37 +169,13 @@ pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         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<()> {
index cc420763fd787306ad27383865ad1ee6102cf580..472ffdf9e1d93d20a95e942951843bafcc4013bb 100644 (file)
@@ -13,7 +13,7 @@
 #![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)]
@@ -233,6 +225,33 @@ fn clone(&self) -> Self { *self }
 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;
@@ -785,13 +804,6 @@ pub struct in6_addr {
     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 {}
 
@@ -850,17 +862,7 @@ pub fn WSASocketW(af: c_int,
                       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;
index be13657aaf487be1eb4e4af3d80d1795ee46b836..dfa44a651e61ccabea96f1101c3897c3f4a7e96d 100644 (file)
@@ -10,7 +10,7 @@
 
 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;
@@ -186,58 +186,23 @@ pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
         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)
     }
 }