Skip to content

Commit 728d911

Browse files
committed
Fix windows
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.
1 parent 5d6ba17 commit 728d911

File tree

5 files changed

+55
-174
lines changed

5 files changed

+55
-174
lines changed

src/libstd/net/tcp.rs

-43
Original file line numberDiff line numberDiff line change
@@ -203,34 +203,6 @@ impl TcpStream {
203203
self.0.nodelay()
204204
}
205205

206-
/// Sets whether keepalive messages are enabled to be sent on this socket.
207-
///
208-
/// On Unix, this option will set the `SO_KEEPALIVE` as well as the
209-
/// `TCP_KEEPALIVE` or `TCP_KEEPIDLE` option (depending on your platform).
210-
/// On Windows, this will set the `SIO_KEEPALIVE_VALS` option.
211-
///
212-
/// If `None` is specified then keepalive messages are disabled, otherwise
213-
/// the duration specified will be the time to remain idle before sending a
214-
/// TCP keepalive probe.
215-
///
216-
/// Some platforms specify this value in seconds, so sub-second
217-
/// specifications may be omitted.
218-
#[stable(feature = "net2_mutators", since = "1.9.0")]
219-
pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
220-
self.0.set_keepalive(keepalive)
221-
}
222-
223-
/// Returns whether keepalive messages are enabled on this socket, and if so
224-
/// the duration of time between them.
225-
///
226-
/// For more information about this option, see [`set_keepalive`][link].
227-
///
228-
/// [link]: #tymethod.set_keepalive
229-
#[stable(feature = "net2_mutators", since = "1.9.0")]
230-
pub fn keepalive(&self) -> io::Result<Option<Duration>> {
231-
self.0.keepalive()
232-
}
233-
234206
/// Sets the value for the `IP_TTL` option on this socket.
235207
///
236208
/// This value sets the time-to-live field that is used in every packet sent
@@ -1156,21 +1128,6 @@ mod tests {
11561128
assert_eq!(false, t!(stream.nodelay()));
11571129
}
11581130

1159-
#[test]
1160-
fn keepalive() {
1161-
let addr = next_test_ip4();
1162-
let _listener = t!(TcpListener::bind(&addr));
1163-
1164-
let stream = t!(TcpStream::connect(&("localhost", addr.port())));
1165-
let dur = Duration::new(15410, 0);
1166-
1167-
assert_eq!(None, t!(stream.keepalive()));
1168-
t!(stream.set_keepalive(Some(dur)));
1169-
assert_eq!(Some(dur), t!(stream.keepalive()));
1170-
t!(stream.set_keepalive(None));
1171-
assert_eq!(None, t!(stream.keepalive()));
1172-
}
1173-
11741131
#[test]
11751132
fn ttl() {
11761133
let ttl = 100;

src/libstd/sys/common/net.rs

+7-16
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use cmp;
1414
use ffi::{CStr, CString};
1515
use fmt;
1616
use io::{self, Error, ErrorKind};
17-
use libc::{c_int, c_char, c_void};
17+
use libc::{c_int, c_char, c_void, c_uint};
1818
use mem;
1919
#[allow(deprecated)]
2020
use net::{SocketAddr, Shutdown, IpAddr, Ipv4Addr, Ipv6Addr};
@@ -84,13 +84,13 @@ fn sockaddr_to_addr(storage: &c::sockaddr_storage,
8484
}
8585

8686
#[cfg(target_os = "android")]
87-
fn to_ipv6mr_interface(value: u32) -> c::c_int {
88-
value as c::c_int
87+
fn to_ipv6mr_interface(value: u32) -> c_int {
88+
value as c_int
8989
}
9090

9191
#[cfg(not(target_os = "android"))]
92-
fn to_ipv6mr_interface(value: u32) -> c::c_uint {
93-
value as c::c_uint
92+
fn to_ipv6mr_interface(value: u32) -> c_uint {
93+
value as c_uint
9494
}
9595

9696
////////////////////////////////////////////////////////////////////////////////
@@ -239,20 +239,11 @@ impl TcpStream {
239239
}
240240

241241
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
242-
setsockopt(&self.inner, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c_int)
242+
self.inner.set_nodelay(nodelay)
243243
}
244244

245245
pub fn nodelay(&self) -> io::Result<bool> {
246-
let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_TCP, c::TCP_NODELAY));
247-
Ok(raw != 0)
248-
}
249-
250-
pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
251-
self.inner.set_keepalive(keepalive)
252-
}
253-
254-
pub fn keepalive(&self) -> io::Result<Option<Duration>> {
255-
self.inner.keepalive()
246+
self.inner.nodelay()
256247
}
257248

258249
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {

src/libstd/sys/unix/net.rs

+5-39
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,6 @@ use libc::SOCK_CLOEXEC;
3535
#[cfg(not(target_os = "linux"))]
3636
const SOCK_CLOEXEC: c_int = 0;
3737

38-
#[cfg(any(target_os = "openbsd", taret_os = "freebsd"))]
39-
use libc::SO_KEEPALIVE as TCP_KEEPALIVE;
40-
#[cfg(any(target_os = "macos", taret_os = "ios"))]
41-
use libc::TCP_KEEPALIVE;
42-
#[cfg(not(any(target_os = "openbsd",
43-
target_os = "freebsd",
44-
target_os = "macos",
45-
target_os = "ios")))]
46-
use libc::TCP_KEEPIDLE as TCP_KEEPALIVE;
47-
4838
pub struct Socket(FileDesc);
4939

5040
pub fn init() {}
@@ -179,37 +169,13 @@ impl Socket {
179169
Ok(())
180170
}
181171

182-
pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
183-
try!(setsockopt(self,
184-
libc::SOL_SOCKET,
185-
libc::SO_KEEPALIVE,
186-
keepalive.is_some() as libc::c_int));
187-
if let Some(dur) = keepalive {
188-
let mut raw = dur.as_secs();
189-
if dur.subsec_nanos() > 0 {
190-
raw = raw.saturating_add(1);
191-
}
192-
193-
let raw = if raw > libc::c_int::max_value() as u64 {
194-
libc::c_int::max_value()
195-
} else {
196-
raw as libc::c_int
197-
};
198-
199-
try!(setsockopt(self, libc::IPPROTO_TCP, TCP_KEEPALIVE, raw));
200-
}
201-
202-
Ok(())
172+
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
173+
setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int)
203174
}
204175

205-
pub fn keepalive(&self) -> io::Result<Option<Duration>> {
206-
let raw: c_int = try!(getsockopt(self, libc::SOL_SOCKET, libc::SO_KEEPALIVE));
207-
if raw == 0 {
208-
return Ok(None);
209-
}
210-
211-
let raw: c_int = try!(getsockopt(self, libc::IPPROTO_TCP, TCP_KEEPALIVE));
212-
Ok(Some(Duration::from_secs(raw as u64)))
176+
pub fn nodelay(&self) -> io::Result<bool> {
177+
let raw: c_int = try!(getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY));
178+
Ok(raw != 0)
213179
}
214180

215181
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {

src/libstd/sys/windows/c.rs

+29-27
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#![allow(bad_style)]
1414
#![cfg_attr(test, allow(dead_code))]
1515

16-
use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort};
16+
use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort,};
1717
use os::raw::{c_char, c_ulonglong};
1818
use libc::{wchar_t, size_t, c_void};
1919
use ptr;
@@ -78,13 +78,6 @@ pub type SOCKET = ::os::windows::raw::SOCKET;
7878
pub type socklen_t = c_int;
7979
pub type ADDRESS_FAMILY = USHORT;
8080

81-
pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE =
82-
Option<unsafe extern "system" fn(dwError: DWORD,
83-
cbTransferred: DWORD,
84-
lpOverlapped: LPWSAOVERLAPPED,
85-
dwFlags: DWORD)>;
86-
pub type LPWSAOVERLAPPED = *mut OVERLAPPED;
87-
8881
pub const TRUE: BOOL = 1;
8982
pub const FALSE: BOOL = 0;
9083

@@ -121,7 +114,6 @@ pub const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
121114
pub const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
122115
pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000;
123116

124-
pub const SIO_KEEPALIVE_VALS: DWORD = 0x98000004;
125117
pub const FIONBIO: c_ulong = 0x8004667e;
126118

127119
#[repr(C)]
@@ -233,6 +225,33 @@ pub const SOL_SOCKET: c_int = 0xffff;
233225
pub const SO_RCVTIMEO: c_int = 0x1006;
234226
pub const SO_SNDTIMEO: c_int = 0x1005;
235227
pub const SO_REUSEADDR: c_int = 0x0004;
228+
pub const IPPROTO_IP: c_int = 0;
229+
pub const IPPROTO_TCP: c_int = 6;
230+
pub const IPPROTO_IPV6: c_int = 41;
231+
pub const TCP_NODELAY: c_int = 0x0001;
232+
pub const IP_TTL: c_int = 4;
233+
pub const IPV6_V6ONLY: c_int = 27;
234+
pub const SO_ERROR: c_int = 0x1007;
235+
pub const SO_BROADCAST: c_int = 0x0020;
236+
pub const IP_MULTICAST_LOOP: c_int = 11;
237+
pub const IPV6_MULTICAST_LOOP: c_int = 11;
238+
pub const IP_MULTICAST_TTL: c_int = 10;
239+
pub const IP_ADD_MEMBERSHIP: c_int = 12;
240+
pub const IP_DROP_MEMBERSHIP: c_int = 13;
241+
pub const IPV6_ADD_MEMBERSHIP: c_int = 12;
242+
pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
243+
244+
#[repr(C)]
245+
pub struct ip_mreq {
246+
pub imr_multiaddr: in_addr,
247+
pub imr_interface: in_addr,
248+
}
249+
250+
#[repr(C)]
251+
pub struct ipv6_mreq {
252+
pub ipv6mr_multiaddr: in6_addr,
253+
pub ipv6mr_interface: c_uint,
254+
}
236255

237256
pub const VOLUME_NAME_DOS: DWORD = 0x0;
238257
pub const MOVEFILE_REPLACE_EXISTING: DWORD = 1;
@@ -785,13 +804,6 @@ pub struct in6_addr {
785804
pub s6_addr: [u8; 16],
786805
}
787806

788-
#[repr(C)]
789-
pub struct tcp_keepalive {
790-
pub onoff: c_ulong,
791-
pub keepalivetime: c_ulong,
792-
pub keepaliveinterval: c_ulong,
793-
}
794-
795807
#[cfg(all(target_arch = "x86_64", target_env = "gnu"))]
796808
pub enum UNWIND_HISTORY_TABLE {}
797809

@@ -850,17 +862,7 @@ extern "system" {
850862
lpProtocolInfo: LPWSAPROTOCOL_INFO,
851863
g: GROUP,
852864
dwFlags: DWORD) -> SOCKET;
853-
pub fn WSAIoctl(s: SOCKET,
854-
dwIoControlCode: DWORD,
855-
lpvInBuffer: LPVOID,
856-
cbInBuffer: DWORD,
857-
lpvOutBuffer: LPVOID,
858-
cbOutBuffer: DWORD,
859-
lpcbBytesReturned: LPDWORD,
860-
lpOverlapped: LPWSAOVERLAPPED,
861-
lpCompletionRoutine: LPWSAOVERLAPPED_COMPLETION_ROUTINE)
862-
-> c_int;
863-
pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut u_long) -> c_int;
865+
pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int;
864866
pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
865867
pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
866868
pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN;

src/libstd/sys/windows/net.rs

+14-49
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use cmp;
1212
use io;
13-
use libc::{c_int, c_void};
13+
use libc::{c_int, c_void, c_ulong};
1414
use mem;
1515
use net::{SocketAddr, Shutdown};
1616
use num::One;
@@ -186,58 +186,23 @@ impl Socket {
186186
Ok(())
187187
}
188188

189-
pub fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()> {
190-
let ms = keepalive.map(sys::dur2timeout).unwrap_or(c::INFINITE);
191-
let ka = c::tcp_keepalive {
192-
onoff: keepalive.is_some() as c::c_ulong,
193-
keepalivetime: ms as c::c_ulong,
194-
keepaliveinterval: ms as c::c_ulong,
195-
};
196-
sys::cvt(unsafe {
197-
c::WSAIoctl(self.0,
198-
c::SIO_KEEPALIVE_VALS,
199-
&ka as *const _ as *mut _,
200-
mem::size_of_val(&ka) as c::DWORD,
201-
0 as *mut _,
202-
0,
203-
0 as *mut _,
204-
0 as *mut _,
205-
None)
206-
}).map(|_| ())
207-
}
208-
209-
pub fn keepalive(&self) -> io::Result<Option<Duration>> {
210-
let mut ka = c::tcp_keepalive {
211-
onoff: 0,
212-
keepalivetime: 0,
213-
keepaliveinterval: 0,
214-
};
215-
try!(sys::cvt(unsafe {
216-
WSAIoctl(self.0,
217-
c::SIO_KEEPALIVE_VALS,
218-
0 as *mut _,
219-
0,
220-
&mut ka as *mut _ as *mut _,
221-
mem::size_of_val(&ka) as c::DWORD,
222-
0 as *mut _,
223-
0 as *mut _,
224-
None)
225-
}));
226-
227-
if ka.onoff == 0 {
228-
Ok(None)
189+
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
190+
let mut nonblocking = nonblocking as c_ulong;
191+
let r = unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) };
192+
if r == 0 {
193+
Ok(())
229194
} else {
230-
let secs = ka.keepaliveinterval / 1000;
231-
let nsec = (ka.keepaliveinterval % 1000) * 1000000;
232-
Ok(Some(Duration::new(secs as u64, nsec as u32)))
195+
Err(io::Error::last_os_error())
233196
}
234197
}
235198

236-
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
237-
let mut nonblocking = nonblocking as c::c_ulong;
238-
sys::cvt(unsafe {
239-
c::ioctlsocket(self.0, c::FIONBIO as c::c_int, &mut nonblocking)
240-
}).map(|_| ())
199+
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
200+
net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BYTE)
201+
}
202+
203+
pub fn nodelay(&self) -> io::Result<bool> {
204+
let raw: c::BYTE = try!(net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY));
205+
Ok(raw != 0)
241206
}
242207
}
243208

0 commit comments

Comments
 (0)