From a57889a58012a53146de7ba54e234a025a9b30c4 Mon Sep 17 00:00:00 2001 From: Tom Lee Date: Sat, 3 May 2014 01:12:31 -0700 Subject: [PATCH] Easier interface for TCP ::connect and ::bind. Prior to this commit, TcpStream::connect and TcpListener::bind took a single SocketAddr argument. This worked well enough, but the API felt a little too "low level" for most simple use cases. A great example is connecting to rust-lang.org on port 80. Rust users would need to: 1. resolve the IP address of rust-lang.org using io::net::addrinfo::get_host_addresses. 2. check for errors 3. if all went well, use the returned IP address and the port number to construct a SocketAddr 4. pass this SocketAddr to TcpStream::connect. I'm modifying the type signature of TcpStream::connect and TcpListener::bind so that the API is a little easier to use. TcpStream::connect now accepts two arguments: a string describing the host/IP of the host we wish to connect to, and a u16 representing the remote port number. Similarly, TcpListener::bind has been modified to take two arguments: a string describing the local interface address (e.g. "0.0.0.0" or "127.0.0.1") and a u16 port number. Here's how to port your Rust code to use the new TcpStream::connect API: // old ::connect API let addr = SocketAddr{ip: Ipv4Addr{127, 0, 0, 1}, port: 8080}; let stream = TcpStream::connect(addr).unwrap() // new ::connect API (minimal change) let addr = SocketAddr{ip: Ipv4Addr{127, 0, 0, 1}, port: 8080}; let stream = TcpStream::connect(addr.ip.to_str(), addr.port()).unwrap() // new ::connect API (more compact) let stream = TcpStream::connect("127.0.0.1", 8080).unwrap() // new ::connect API (hostname) let stream = TcpStream::connect("rust-lang.org", 80) Similarly, for TcpListener::bind: // old ::bind API let addr = SocketAddr{ip: Ipv4Addr{0, 0, 0, 0}, port: 8080}; let mut acceptor = TcpListener::bind(addr).listen(); // new ::bind API (minimal change) let addr = SocketAddr{ip: Ipv4Addr{0, 0, 0, 0}, port: 8080}; let mut acceptor = TcpListener::bind(addr.ip.to_str(), addr.port()).listen() // new ::bind API (more compact) let mut acceptor = TcpListener::bind("0.0.0.0", 8080).listen() [breaking-change] --- src/compiletest/runtest.rs | 6 +- src/libstd/io/mod.rs | 8 +- src/libstd/io/net/tcp.rs | 346 ++++++++++++++++------ src/test/run-pass/tcp-connect-timeouts.rs | 8 +- src/test/run-pass/tcp-stress.rs | 10 +- 5 files changed, 271 insertions(+), 107 deletions(-) diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index cea440afd9028..e47e7dc33d8e4 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -19,7 +19,6 @@ use util; use std::io::File; use std::io::fs; -use std::io::net::ip::{Ipv4Addr, SocketAddr}; use std::io::net::tcp; use std::io::process::ProcessExit; use std::io::process; @@ -316,10 +315,7 @@ fn run_debuginfo_gdb_test(config: &config, props: &TestProps, testfile: &Path) { //waiting 1 second for gdbserver start timer::sleep(1000); let result = task::try(proc() { - tcp::TcpStream::connect(SocketAddr { - ip: Ipv4Addr(127, 0, 0, 1), - port: 5039, - }).unwrap(); + tcp::TcpStream::connect("127.0.0.1", 5039).unwrap(); }); if result.is_err() { continue; diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 37edab9991598..5ae96e0f4e689 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -83,11 +83,9 @@ Some examples of obvious things you might want to do ```rust,should_fail # #![allow(unused_must_use)] - use std::io::net::ip::SocketAddr; use std::io::net::tcp::TcpStream; - let addr = from_str::("127.0.0.1:8080").unwrap(); - let mut socket = TcpStream::connect(addr).unwrap(); + let mut socket = TcpStream::connect("127.0.0.1", 8080).unwrap(); socket.write(bytes!("GET / HTTP/1.0\n\n")); let response = socket.read_to_end(); ``` @@ -99,11 +97,9 @@ Some examples of obvious things you might want to do # fn foo() { # #![allow(dead_code)] use std::io::{TcpListener, TcpStream}; - use std::io::net::ip::{Ipv4Addr, SocketAddr}; use std::io::{Acceptor, Listener}; - let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 80 }; - let listener = TcpListener::bind(addr); + let listener = TcpListener::bind("127.0.0.1", 80); // bind the listener to the specified address let mut acceptor = listener.listen(); diff --git a/src/libstd/io/net/tcp.rs b/src/libstd/io/net/tcp.rs index a9aa871d926bf..454d9af5eeba2 100644 --- a/src/libstd/io/net/tcp.rs +++ b/src/libstd/io/net/tcp.rs @@ -1,4 +1,4 @@ -// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -19,8 +19,14 @@ use clone::Clone; use io::IoResult; +use iter::Iterator; +use slice::ImmutableVector; +use result::{Ok,Err}; +use io::net::addrinfo::get_host_addresses; use io::net::ip::SocketAddr; +use io::{IoError, ConnectionFailed, InvalidInput}; use io::{Reader, Writer, Listener, Acceptor}; +use from_str::FromStr; use kinds::Send; use option::{None, Some, Option}; use owned::Box; @@ -35,10 +41,8 @@ use rt::rtio::{RtioTcpAcceptor, RtioTcpStream}; /// ```no_run /// # #![allow(unused_must_use)] /// use std::io::net::tcp::TcpStream; -/// use std::io::net::ip::{Ipv4Addr, SocketAddr}; /// -/// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 }; -/// let mut stream = TcpStream::connect(addr); +/// let mut stream = TcpStream::connect("127.0.0.1", 34254); /// /// stream.write([1]); /// let mut buf = [0]; @@ -54,13 +58,32 @@ impl TcpStream { TcpStream { obj: s } } - /// Creates a TCP connection to a remote socket address. + /// Open a TCP connection to a remote host by hostname or IP address. /// - /// If no error is encountered, then `Ok(stream)` is returned. - pub fn connect(addr: SocketAddr) -> IoResult { - LocalIo::maybe_raise(|io| { - io.tcp_connect(addr, None).map(TcpStream::new) - }) + /// `host` can be a hostname or IP address string. If no error is + /// encountered, then `Ok(stream)` is returned. + pub fn connect(host: &str, port: u16) -> IoResult { + let addresses = try!(get_host_addresses(host)); + let mut err = IoError{ + kind: ConnectionFailed, + desc: "no addresses found for hostname", + detail: None + }; + for address in addresses.iter() { + let socket_addr = SocketAddr{ip: *address, port: port}; + let result = LocalIo::maybe_raise(|io| { + io.tcp_connect(socket_addr, None).map(TcpStream::new) + }); + match result { + Ok(stream) => { + return Ok(stream) + } + Err(connect_err) => { + err = connect_err + } + } + } + Err(err) } /// Creates a TCP connection to a remote socket address, timing out after @@ -121,10 +144,8 @@ impl TcpStream { /// # #![allow(unused_must_use)] /// use std::io::timer; /// use std::io::net::tcp::TcpStream; - /// use std::io::net::ip::{Ipv4Addr, SocketAddr}; /// - /// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 34254 }; - /// let mut stream = TcpStream::connect(addr).unwrap(); + /// let mut stream = TcpStream::connect("127.0.0.1", 34254).unwrap(); /// let stream2 = stream.clone(); /// /// spawn(proc() { @@ -251,11 +272,9 @@ impl Writer for TcpStream { /// # fn foo() { /// # #![allow(dead_code)] /// use std::io::{TcpListener, TcpStream}; -/// use std::io::net::ip::{Ipv4Addr, SocketAddr}; /// use std::io::{Acceptor, Listener}; /// -/// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 80 }; -/// let listener = TcpListener::bind(addr); +/// let listener = TcpListener::bind("127.0.0.1", 80); /// /// // bind the listener to the specified address /// let mut acceptor = listener.listen(); @@ -284,17 +303,29 @@ pub struct TcpListener { } impl TcpListener { - /// Creates a new `TcpListener` which will be bound to the specified local - /// socket address. This listener is not ready for accepting connections, + /// Creates a new `TcpListener` which will be bound to the specified IP + /// and port. This listener is not ready for accepting connections, /// `listen` must be called on it before that's possible. /// /// Binding with a port number of 0 will request that the OS assigns a port /// to this listener. The port allocated can be queried via the /// `socket_name` function. - pub fn bind(addr: SocketAddr) -> IoResult { - LocalIo::maybe_raise(|io| { - io.tcp_bind(addr).map(|l| TcpListener { obj: l }) - }) + pub fn bind(addr: &str, port: u16) -> IoResult { + match FromStr::from_str(addr) { + Some(ip) => { + let socket_addr = SocketAddr{ip: ip, port: port}; + LocalIo::maybe_raise(|io| { + io.tcp_bind(socket_addr).map(|l| TcpListener { obj: l }) + }) + } + None => { + Err(IoError{ + kind: InvalidInput, + desc: "invalid IP address specified", + detail: None + }) + } + } } /// Returns the local socket address of this listener. @@ -338,11 +369,9 @@ impl TcpAcceptor { /// ```no_run /// # #![allow(experimental)] /// use std::io::net::tcp::TcpListener; - /// use std::io::net::ip::{SocketAddr, Ipv4Addr}; /// use std::io::{Listener, Acceptor, TimedOut}; /// - /// let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 8482 }; - /// let mut a = TcpListener::bind(addr).listen().unwrap(); + /// let mut a = TcpListener::bind("127.0.0.1", 8482).listen().unwrap(); /// /// // After 100ms have passed, all accepts will fail /// a.set_timeout(Some(100)); @@ -382,27 +411,96 @@ mod test { // FIXME #11530 this fails on android because tests are run as root iotest!(fn bind_error() { - let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 }; - match TcpListener::bind(addr) { + match TcpListener::bind("0.0.0.0", 1) { Ok(..) => fail!(), Err(e) => assert_eq!(e.kind, PermissionDenied), } } #[ignore(cfg(windows))] #[ignore(cfg(target_os = "android"))]) iotest!(fn connect_error() { - let addr = SocketAddr { ip: Ipv4Addr(0, 0, 0, 0), port: 1 }; - match TcpStream::connect(addr) { + match TcpStream::connect("0.0.0.0", 1) { Ok(..) => fail!(), Err(e) => assert_eq!(e.kind, ConnectionRefused), } }) + iotest!(fn listen_ip4_localhost() { + let socket_addr = next_test_ip4(); + let ip_str = socket_addr.ip.to_str(); + let port = socket_addr.port; + let listener = TcpListener::bind(ip_str, port); + let mut acceptor = listener.listen(); + + spawn(proc() { + let mut stream = TcpStream::connect("localhost", port); + stream.write([144]).unwrap(); + }); + + let mut stream = acceptor.accept(); + let mut buf = [0]; + stream.read(buf).unwrap(); + assert!(buf[0] == 144); + }) + + iotest!(fn connect_localhost() { + let addr = next_test_ip4(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); + + spawn(proc() { + let mut stream = TcpStream::connect("localhost", addr.port); + stream.write([64]).unwrap(); + }); + + let mut stream = acceptor.accept(); + let mut buf = [0]; + stream.read(buf).unwrap(); + assert!(buf[0] == 64); + }) + + iotest!(fn connect_ip4_loopback() { + let addr = next_test_ip4(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); + + spawn(proc() { + let mut stream = TcpStream::connect("127.0.0.1", addr.port); + stream.write([44]).unwrap(); + }); + + let mut stream = acceptor.accept(); + let mut buf = [0]; + stream.read(buf).unwrap(); + assert!(buf[0] == 44); + }) + + iotest!(fn connect_ip6_loopback() { + let addr = next_test_ip6(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); + + spawn(proc() { + let mut stream = TcpStream::connect("::1", addr.port); + stream.write([66]).unwrap(); + }); + + let mut stream = acceptor.accept(); + let mut buf = [0]; + stream.read(buf).unwrap(); + assert!(buf[0] == 66); + }) + iotest!(fn smoke_test_ip4() { let addr = next_test_ip4(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let mut stream = TcpStream::connect(addr); + let mut stream = TcpStream::connect(ip_str, port); stream.write([99]).unwrap(); }); @@ -414,10 +512,12 @@ mod test { iotest!(fn smoke_test_ip6() { let addr = next_test_ip6(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let mut stream = TcpStream::connect(addr); + let mut stream = TcpStream::connect(ip_str, port); stream.write([99]).unwrap(); }); @@ -429,10 +529,12 @@ mod test { iotest!(fn read_eof_ip4() { let addr = next_test_ip4(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let _stream = TcpStream::connect(addr); + let _stream = TcpStream::connect(ip_str, port); // Close }); @@ -444,10 +546,12 @@ mod test { iotest!(fn read_eof_ip6() { let addr = next_test_ip6(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let _stream = TcpStream::connect(addr); + let _stream = TcpStream::connect(ip_str, port); // Close }); @@ -459,10 +563,12 @@ mod test { iotest!(fn read_eof_twice_ip4() { let addr = next_test_ip4(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let _stream = TcpStream::connect(addr); + let _stream = TcpStream::connect(ip_str, port); // Close }); @@ -482,10 +588,12 @@ mod test { iotest!(fn read_eof_twice_ip6() { let addr = next_test_ip6(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let _stream = TcpStream::connect(addr); + let _stream = TcpStream::connect(ip_str, port); // Close }); @@ -505,10 +613,12 @@ mod test { iotest!(fn write_close_ip4() { let addr = next_test_ip4(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let _stream = TcpStream::connect(addr); + let _stream = TcpStream::connect(ip_str, port); // Close }); @@ -530,10 +640,12 @@ mod test { iotest!(fn write_close_ip6() { let addr = next_test_ip6(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let _stream = TcpStream::connect(addr); + let _stream = TcpStream::connect(ip_str, port); // Close }); @@ -555,12 +667,14 @@ mod test { iotest!(fn multiple_connect_serial_ip4() { let addr = next_test_ip4(); + let ip_str = addr.ip.to_str(); + let port = addr.port; let max = 10u; - let mut acceptor = TcpListener::bind(addr).listen(); + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { for _ in range(0, max) { - let mut stream = TcpStream::connect(addr); + let mut stream = TcpStream::connect(ip_str, port); stream.write([99]).unwrap(); } }); @@ -574,12 +688,14 @@ mod test { iotest!(fn multiple_connect_serial_ip6() { let addr = next_test_ip6(); + let ip_str = addr.ip.to_str(); + let port = addr.port; let max = 10u; - let mut acceptor = TcpListener::bind(addr).listen(); + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { for _ in range(0, max) { - let mut stream = TcpStream::connect(addr); + let mut stream = TcpStream::connect(ip_str, port); stream.write([99]).unwrap(); } }); @@ -593,8 +709,10 @@ mod test { iotest!(fn multiple_connect_interleaved_greedy_schedule_ip4() { let addr = next_test_ip4(); + let ip_str = addr.ip.to_str(); + let port = addr.port; static MAX: int = 10; - let acceptor = TcpListener::bind(addr).listen(); + let acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { let mut acceptor = acceptor; @@ -613,11 +731,13 @@ mod test { connect(0, addr); fn connect(i: int, addr: SocketAddr) { + let ip_str = addr.ip.to_str(); + let port = addr.port; if i == MAX { return } spawn(proc() { debug!("connecting"); - let mut stream = TcpStream::connect(addr); + let mut stream = TcpStream::connect(ip_str, port); // Connect again before writing connect(i + 1, addr); debug!("writing"); @@ -628,8 +748,10 @@ mod test { iotest!(fn multiple_connect_interleaved_greedy_schedule_ip6() { let addr = next_test_ip6(); + let ip_str = addr.ip.to_str(); + let port = addr.port; static MAX: int = 10; - let acceptor = TcpListener::bind(addr).listen(); + let acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { let mut acceptor = acceptor; @@ -648,11 +770,13 @@ mod test { connect(0, addr); fn connect(i: int, addr: SocketAddr) { + let ip_str = addr.ip.to_str(); + let port = addr.port; if i == MAX { return } spawn(proc() { debug!("connecting"); - let mut stream = TcpStream::connect(addr); + let mut stream = TcpStream::connect(ip_str, port); // Connect again before writing connect(i + 1, addr); debug!("writing"); @@ -664,7 +788,9 @@ mod test { iotest!(fn multiple_connect_interleaved_lazy_schedule_ip4() { static MAX: int = 10; let addr = next_test_ip4(); - let acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { let mut acceptor = acceptor; @@ -683,11 +809,13 @@ mod test { connect(0, addr); fn connect(i: int, addr: SocketAddr) { + let ip_str = addr.ip.to_str(); + let port = addr.port; if i == MAX { return } spawn(proc() { debug!("connecting"); - let mut stream = TcpStream::connect(addr); + let mut stream = TcpStream::connect(ip_str, port); // Connect again before writing connect(i + 1, addr); debug!("writing"); @@ -699,7 +827,9 @@ mod test { iotest!(fn multiple_connect_interleaved_lazy_schedule_ip6() { static MAX: int = 10; let addr = next_test_ip6(); - let acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { let mut acceptor = acceptor; @@ -718,11 +848,13 @@ mod test { connect(0, addr); fn connect(i: int, addr: SocketAddr) { + let ip_str = addr.ip.to_str(); + let port = addr.port; if i == MAX { return } spawn(proc() { debug!("connecting"); - let mut stream = TcpStream::connect(addr); + let mut stream = TcpStream::connect(ip_str, port); // Connect again before writing connect(i + 1, addr); debug!("writing"); @@ -732,7 +864,9 @@ mod test { }) pub fn socket_name(addr: SocketAddr) { - let mut listener = TcpListener::bind(addr).unwrap(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut listener = TcpListener::bind(ip_str, port).unwrap(); // Make sure socket_name gives // us the socket we binded to. @@ -742,13 +876,15 @@ mod test { } pub fn peer_name(addr: SocketAddr) { - let acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { let mut acceptor = acceptor; acceptor.accept().unwrap(); }); - let stream = TcpStream::connect(addr); + let stream = TcpStream::connect(ip_str, port); assert!(stream.is_ok()); let mut stream = stream.unwrap(); @@ -774,9 +910,11 @@ mod test { iotest!(fn partial_read() { let addr = next_test_ip4(); + let port = addr.port; let (tx, rx) = channel(); spawn(proc() { - let mut srv = TcpListener::bind(addr).listen().unwrap(); + let ip_str = addr.ip.to_str(); + let mut srv = TcpListener::bind(ip_str, port).listen().unwrap(); tx.send(()); let mut cl = srv.accept().unwrap(); cl.write([10]).unwrap(); @@ -786,7 +924,8 @@ mod test { }); rx.recv(); - let mut c = TcpStream::connect(addr).unwrap(); + let ip_str = addr.ip.to_str(); + let mut c = TcpStream::connect(ip_str, port).unwrap(); let mut b = [0, ..10]; assert_eq!(c.read(b), Ok(1)); c.write([1]).unwrap(); @@ -795,9 +934,11 @@ mod test { iotest!(fn double_bind() { let addr = next_test_ip4(); - let listener = TcpListener::bind(addr).unwrap().listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let listener = TcpListener::bind(ip_str, port).unwrap().listen(); assert!(listener.is_ok()); - match TcpListener::bind(addr).listen() { + match TcpListener::bind(ip_str, port).listen() { Ok(..) => fail!(), Err(e) => { assert!(e.kind == ConnectionRefused || e.kind == OtherIoError); @@ -807,17 +948,20 @@ mod test { iotest!(fn fast_rebind() { let addr = next_test_ip4(); + let port = addr.port; let (tx, rx) = channel(); spawn(proc() { + let ip_str = addr.ip.to_str(); rx.recv(); - let _stream = TcpStream::connect(addr).unwrap(); + let _stream = TcpStream::connect(ip_str, port).unwrap(); // Close rx.recv(); }); { - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let mut acceptor = TcpListener::bind(ip_str, port).listen(); tx.send(()); { let _stream = acceptor.accept().unwrap(); @@ -826,15 +970,17 @@ mod test { } // Close listener } - let _listener = TcpListener::bind(addr); + let _listener = TcpListener::bind(addr.ip.to_str(), port); }) iotest!(fn tcp_clone_smoke() { let addr = next_test_ip4(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let mut s = TcpStream::connect(addr); + let mut s = TcpStream::connect(ip_str, port); let mut buf = [0, 0]; assert_eq!(s.read(buf), Ok(1)); assert_eq!(buf[0], 1); @@ -860,12 +1006,14 @@ mod test { iotest!(fn tcp_clone_two_read() { let addr = next_test_ip6(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); let (tx1, rx) = channel(); let tx2 = tx1.clone(); spawn(proc() { - let mut s = TcpStream::connect(addr); + let mut s = TcpStream::connect(ip_str, port); s.write([1]).unwrap(); rx.recv(); s.write([2]).unwrap(); @@ -892,10 +1040,12 @@ mod test { iotest!(fn tcp_clone_two_write() { let addr = next_test_ip4(); - let mut acceptor = TcpListener::bind(addr).listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut acceptor = TcpListener::bind(ip_str, port).listen(); spawn(proc() { - let mut s = TcpStream::connect(addr); + let mut s = TcpStream::connect(ip_str, port); let mut buf = [0, 1]; s.read(buf).unwrap(); s.read(buf).unwrap(); @@ -919,7 +1069,9 @@ mod test { use rt::rtio::RtioTcpStream; let addr = next_test_ip4(); - let a = TcpListener::bind(addr).unwrap().listen(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let a = TcpListener::bind(ip_str, port).unwrap().listen(); spawn(proc() { let mut a = a; let mut c = a.accept().unwrap(); @@ -927,7 +1079,7 @@ mod test { c.write([1]).unwrap(); }); - let mut s = TcpStream::connect(addr).unwrap(); + let mut s = TcpStream::connect(ip_str, port).unwrap(); assert!(s.obj.close_write().is_ok()); assert!(s.write([1]).is_err()); assert_eq!(s.read_to_end(), Ok(vec!(1))); @@ -935,7 +1087,9 @@ mod test { iotest!(fn accept_timeout() { let addr = next_test_ip4(); - let mut a = TcpListener::bind(addr).unwrap().listen().unwrap(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut a = TcpListener::bind(ip_str, port).unwrap().listen().unwrap(); a.set_timeout(Some(10)); @@ -954,7 +1108,7 @@ mod test { if !cfg!(target_os = "freebsd") { let (tx, rx) = channel(); spawn(proc() { - tx.send(TcpStream::connect(addr).unwrap()); + tx.send(TcpStream::connect(addr.ip.to_str(), port).unwrap()); }); let l = rx.recv(); for i in range(0, 1001) { @@ -971,14 +1125,16 @@ mod test { // Unset the timeout and make sure that this always blocks. a.set_timeout(None); spawn(proc() { - drop(TcpStream::connect(addr).unwrap()); + drop(TcpStream::connect(addr.ip.to_str(), port).unwrap()); }); a.accept().unwrap(); }) iotest!(fn close_readwrite_smoke() { let addr = next_test_ip4(); - let a = TcpListener::bind(addr).listen().unwrap(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let a = TcpListener::bind(ip_str, port).listen().unwrap(); let (_tx, rx) = channel::<()>(); spawn(proc() { let mut a = a; @@ -987,7 +1143,7 @@ mod test { }); let mut b = [0]; - let mut s = TcpStream::connect(addr).unwrap(); + let mut s = TcpStream::connect(ip_str, port).unwrap(); let mut s2 = s.clone(); // closing should prevent reads/writes @@ -1014,7 +1170,9 @@ mod test { iotest!(fn close_read_wakes_up() { let addr = next_test_ip4(); - let a = TcpListener::bind(addr).listen().unwrap(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let a = TcpListener::bind(ip_str, port).listen().unwrap(); let (_tx, rx) = channel::<()>(); spawn(proc() { let mut a = a; @@ -1022,7 +1180,7 @@ mod test { let _ = rx.recv_opt(); }); - let mut s = TcpStream::connect(addr).unwrap(); + let mut s = TcpStream::connect(ip_str, port).unwrap(); let s2 = s.clone(); let (tx, rx) = channel(); spawn(proc() { @@ -1039,10 +1197,12 @@ mod test { iotest!(fn readwrite_timeouts() { let addr = next_test_ip6(); - let mut a = TcpListener::bind(addr).listen().unwrap(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut a = TcpListener::bind(ip_str, port).listen().unwrap(); let (tx, rx) = channel::<()>(); spawn(proc() { - let mut s = TcpStream::connect(addr).unwrap(); + let mut s = TcpStream::connect(ip_str, port).unwrap(); rx.recv(); assert!(s.write([0]).is_ok()); let _ = rx.recv_opt(); @@ -1071,10 +1231,12 @@ mod test { iotest!(fn read_timeouts() { let addr = next_test_ip6(); - let mut a = TcpListener::bind(addr).listen().unwrap(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut a = TcpListener::bind(ip_str, port).listen().unwrap(); let (tx, rx) = channel::<()>(); spawn(proc() { - let mut s = TcpStream::connect(addr).unwrap(); + let mut s = TcpStream::connect(ip_str, port).unwrap(); rx.recv(); let mut amt = 0; while amt < 100 * 128 * 1024 { @@ -1099,10 +1261,12 @@ mod test { iotest!(fn write_timeouts() { let addr = next_test_ip6(); - let mut a = TcpListener::bind(addr).listen().unwrap(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut a = TcpListener::bind(ip_str, port).listen().unwrap(); let (tx, rx) = channel::<()>(); spawn(proc() { - let mut s = TcpStream::connect(addr).unwrap(); + let mut s = TcpStream::connect(ip_str, port).unwrap(); rx.recv(); assert!(s.write([0]).is_ok()); let _ = rx.recv_opt(); @@ -1126,10 +1290,12 @@ mod test { iotest!(fn timeout_concurrent_read() { let addr = next_test_ip6(); - let mut a = TcpListener::bind(addr).listen().unwrap(); + let ip_str = addr.ip.to_str(); + let port = addr.port; + let mut a = TcpListener::bind(ip_str, port).listen().unwrap(); let (tx, rx) = channel::<()>(); spawn(proc() { - let mut s = TcpStream::connect(addr).unwrap(); + let mut s = TcpStream::connect(ip_str, port).unwrap(); rx.recv(); assert_eq!(s.write([0]), Ok(())); let _ = rx.recv_opt(); diff --git a/src/test/run-pass/tcp-connect-timeouts.rs b/src/test/run-pass/tcp-connect-timeouts.rs index 68db134419a5a..5612c50142caf 100644 --- a/src/test/run-pass/tcp-connect-timeouts.rs +++ b/src/test/run-pass/tcp-connect-timeouts.rs @@ -54,6 +54,8 @@ macro_rules! iotest ( iotest!(fn eventual_timeout() { use native; let addr = next_test_ip4(); + let host = addr.ip.to_str(); + let port = addr.port; // Use a native task to receive connections because it turns out libuv is // really good at accepting connections and will likely run out of file @@ -61,7 +63,7 @@ iotest!(fn eventual_timeout() { let (tx1, rx1) = channel(); let (_tx2, rx2) = channel::<()>(); native::task::spawn(proc() { - let _l = TcpListener::bind(addr).unwrap().listen(); + let _l = TcpListener::bind(host, port).unwrap().listen(); tx1.send(()); let _ = rx2.recv_opt(); }); @@ -80,7 +82,9 @@ iotest!(fn eventual_timeout() { iotest!(fn timeout_success() { let addr = next_test_ip4(); - let _l = TcpListener::bind(addr).unwrap().listen(); + let host = addr.ip.to_str(); + let port = addr.port; + let _l = TcpListener::bind(host, port).unwrap().listen(); assert!(TcpStream::connect_timeout(addr, 1000).is_ok()); }) diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index 0c38abb20fc48..829539ac70954 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -19,7 +19,6 @@ extern crate libc; extern crate green; extern crate rustuv; -use std::io::net::ip::{Ipv4Addr, SocketAddr}; use std::io::net::tcp::{TcpListener, TcpStream}; use std::io::{Acceptor, Listener}; use std::task::TaskBuilder; @@ -38,10 +37,11 @@ fn main() { unsafe { libc::exit(1) } }); - let addr = SocketAddr { ip: Ipv4Addr(127, 0, 0, 1), port: 0 }; + let host = "127.0.0.1"; + let port = 0; let (tx, rx) = channel(); spawn(proc() { - let mut listener = TcpListener::bind(addr).unwrap(); + let mut listener = TcpListener::bind(host, port).unwrap(); tx.send(listener.socket_name().unwrap()); let mut acceptor = listener.listen(); loop { @@ -57,6 +57,8 @@ fn main() { } }); let addr = rx.recv(); + let host = addr.ip.to_str(); + let port = addr.port; let (tx, rx) = channel(); for _ in range(0, 1000) { @@ -64,7 +66,7 @@ fn main() { let mut builder = TaskBuilder::new(); builder.opts.stack_size = Some(32 * 1024); builder.spawn(proc() { - match TcpStream::connect(addr) { + match TcpStream::connect(host, port) { Ok(stream) => { let mut stream = stream; stream.write([1]);