Skip to content

Commit 8e261d1

Browse files
committed
Auto merge of #31945 - sfackler:net2, r=alexcrichton
I have these tagged as stable in 1.9, so this shouldn't merge until the 1.8 beta's cut.
2 parents e91f889 + e4aa513 commit 8e261d1

File tree

6 files changed

+733
-4
lines changed

6 files changed

+733
-4
lines changed

src/libstd/net/tcp.rs

+195
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,89 @@ impl TcpStream {
180180
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
181181
self.0.write_timeout()
182182
}
183+
184+
/// Sets the value of the `TCP_NODELAY` option on this socket.
185+
///
186+
/// If set, this option disables the Nagle algorithm. This means that
187+
/// segments are always sent as soon as possible, even if there is only a
188+
/// small amount of data. When not set, data is buffered until there is a
189+
/// sufficient amount to send out, thereby avoiding the frequent sending of
190+
/// small packets.
191+
#[stable(feature = "net2_mutators", since = "1.9.0")]
192+
pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
193+
self.0.set_nodelay(nodelay)
194+
}
195+
196+
/// Gets the value of the `TCP_NODELAY` option on this socket.
197+
///
198+
/// For more information about this option, see [`set_nodelay`][link].
199+
///
200+
/// [link]: #tymethod.set_nodelay
201+
#[stable(feature = "net2_mutators", since = "1.9.0")]
202+
pub fn nodelay(&self) -> io::Result<bool> {
203+
self.0.nodelay()
204+
}
205+
206+
/// Sets the value for the `IP_TTL` option on this socket.
207+
///
208+
/// This value sets the time-to-live field that is used in every packet sent
209+
/// from this socket.
210+
#[stable(feature = "net2_mutators", since = "1.9.0")]
211+
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
212+
self.0.set_ttl(ttl)
213+
}
214+
215+
/// Gets the value of the `IP_TTL` option for this socket.
216+
///
217+
/// For more information about this option, see [`set_ttl`][link].
218+
///
219+
/// [link]: #tymethod.set_ttl
220+
#[stable(feature = "net2_mutators", since = "1.9.0")]
221+
pub fn ttl(&self) -> io::Result<u32> {
222+
self.0.ttl()
223+
}
224+
225+
/// Sets the value for the `IPV6_V6ONLY` option on this socket.
226+
///
227+
/// If this is set to `true` then the socket is restricted to sending and
228+
/// receiving IPv6 packets only. If this is the case, an IPv4 and an IPv6
229+
/// application can each bind the same port at the same time.
230+
///
231+
/// If this is set to `false` then the socket can be used to send and
232+
/// receive packets from an IPv4-mapped IPv6 address.
233+
#[stable(feature = "net2_mutators", since = "1.9.0")]
234+
pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
235+
self.0.set_only_v6(only_v6)
236+
}
237+
238+
/// Gets the value of the `IPV6_V6ONLY` option for this socket.
239+
///
240+
/// For more information about this option, see [`set_only_v6`][link].
241+
///
242+
/// [link]: #tymethod.set_only_v6
243+
#[stable(feature = "net2_mutators", since = "1.9.0")]
244+
pub fn only_v6(&self) -> io::Result<bool> {
245+
self.0.only_v6()
246+
}
247+
248+
/// Get the value of the `SO_ERROR` option on this socket.
249+
///
250+
/// This will retrieve the stored error in the underlying socket, clearing
251+
/// the field in the process. This can be useful for checking errors between
252+
/// calls.
253+
#[stable(feature = "net2_mutators", since = "1.9.0")]
254+
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
255+
self.0.take_error()
256+
}
257+
258+
/// Moves this TCP stream into or out of nonblocking mode.
259+
///
260+
/// On Unix this corresponds to calling fcntl, and on Windows this
261+
/// corresponds to calling ioctlsocket.
262+
#[stable(feature = "net2_mutators", since = "1.9.0")]
263+
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
264+
self.0.set_nonblocking(nonblocking)
265+
}
183266
}
184267

185268
#[stable(feature = "rust1", since = "1.0.0")]
@@ -278,6 +361,67 @@ impl TcpListener {
278361
pub fn incoming(&self) -> Incoming {
279362
Incoming { listener: self }
280363
}
364+
365+
/// Sets the value for the `IP_TTL` option on this socket.
366+
///
367+
/// This value sets the time-to-live field that is used in every packet sent
368+
/// from this socket.
369+
#[stable(feature = "net2_mutators", since = "1.9.0")]
370+
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
371+
self.0.set_ttl(ttl)
372+
}
373+
374+
/// Gets the value of the `IP_TTL` option for this socket.
375+
///
376+
/// For more information about this option, see [`set_ttl`][link].
377+
///
378+
/// [link]: #tymethod.set_ttl
379+
#[stable(feature = "net2_mutators", since = "1.9.0")]
380+
pub fn ttl(&self) -> io::Result<u32> {
381+
self.0.ttl()
382+
}
383+
384+
/// Sets the value for the `IPV6_V6ONLY` option on this socket.
385+
///
386+
/// If this is set to `true` then the socket is restricted to sending and
387+
/// receiving IPv6 packets only. In this case two IPv4 and IPv6 applications
388+
/// can bind the same port at the same time.
389+
///
390+
/// If this is set to `false` then the socket can be used to send and
391+
/// receive packets from an IPv4-mapped IPv6 address.
392+
#[stable(feature = "net2_mutators", since = "1.9.0")]
393+
pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
394+
self.0.set_only_v6(only_v6)
395+
}
396+
397+
/// Gets the value of the `IPV6_V6ONLY` option for this socket.
398+
///
399+
/// For more information about this option, see [`set_only_v6`][link].
400+
///
401+
/// [link]: #tymethod.set_only_v6
402+
#[stable(feature = "net2_mutators", since = "1.9.0")]
403+
pub fn only_v6(&self) -> io::Result<bool> {
404+
self.0.only_v6()
405+
}
406+
407+
/// Get the value of the `SO_ERROR` option on this socket.
408+
///
409+
/// This will retrieve the stored error in the underlying socket, clearing
410+
/// the field in the process. This can be useful for checking errors between
411+
/// calls.
412+
#[stable(feature = "net2_mutators", since = "1.9.0")]
413+
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
414+
self.0.take_error()
415+
}
416+
417+
/// Moves this TCP stream into or out of nonblocking mode.
418+
///
419+
/// On Unix this corresponds to calling fcntl, and on Windows this
420+
/// corresponds to calling ioctlsocket.
421+
#[stable(feature = "net2_mutators", since = "1.9.0")]
422+
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
423+
self.0.set_nonblocking(nonblocking)
424+
}
281425
}
282426

283427
#[stable(feature = "rust1", since = "1.0.0")]
@@ -969,4 +1113,55 @@ mod tests {
9691113
assert!(start.elapsed() > Duration::from_millis(400));
9701114
drop(listener);
9711115
}
1116+
1117+
#[test]
1118+
fn nodelay() {
1119+
let addr = next_test_ip4();
1120+
let _listener = t!(TcpListener::bind(&addr));
1121+
1122+
let stream = t!(TcpStream::connect(&("localhost", addr.port())));
1123+
1124+
assert_eq!(false, t!(stream.nodelay()));
1125+
t!(stream.set_nodelay(true));
1126+
assert_eq!(true, t!(stream.nodelay()));
1127+
t!(stream.set_nodelay(false));
1128+
assert_eq!(false, t!(stream.nodelay()));
1129+
}
1130+
1131+
#[test]
1132+
fn ttl() {
1133+
let ttl = 100;
1134+
1135+
let addr = next_test_ip4();
1136+
let listener = t!(TcpListener::bind(&addr));
1137+
1138+
t!(listener.set_ttl(ttl));
1139+
assert_eq!(ttl, t!(listener.ttl()));
1140+
1141+
let stream = t!(TcpStream::connect(&("localhost", addr.port())));
1142+
1143+
t!(stream.set_ttl(ttl));
1144+
assert_eq!(ttl, t!(stream.ttl()));
1145+
}
1146+
1147+
#[test]
1148+
fn set_nonblocking() {
1149+
let addr = next_test_ip4();
1150+
let listener = t!(TcpListener::bind(&addr));
1151+
1152+
t!(listener.set_nonblocking(true));
1153+
t!(listener.set_nonblocking(false));
1154+
1155+
let mut stream = t!(TcpStream::connect(&("localhost", addr.port())));
1156+
1157+
t!(stream.set_nonblocking(false));
1158+
t!(stream.set_nonblocking(true));
1159+
1160+
let mut buf = [0];
1161+
match stream.read(&mut buf) {
1162+
Ok(_) => panic!("expected error"),
1163+
Err(ref e) if e.kind() == ErrorKind::WouldBlock => {}
1164+
Err(e) => panic!("unexpected error {}", e),
1165+
}
1166+
}
9721167
}

0 commit comments

Comments
 (0)