Skip to content

Commit

Permalink
Return remote peer address in TcpListener::accept
Browse files Browse the repository at this point in the history
This brings the API more in line with the `std::net::TcpListener`'s signature by
returning a pair of both the accepted connection and the remote socket address
if successful.

Closes tokio-rs#258
  • Loading branch information
alexcrichton committed Sep 16, 2015
1 parent 2c3435c commit 15b0599
Show file tree
Hide file tree
Showing 9 changed files with 21 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* `EventLoopConfig` is now a builder instead of having public struct fields. It
is also no longer `Copy`. (#259)
* `TcpSocket` is no longer exported in the public API (#262)
* `TcpListener` now returns the remote peer address from `accept` as well (#275)

# 0.4.1 (July 21)

Expand Down
9 changes: 5 additions & 4 deletions src/net/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,10 @@ impl TcpListener {
/// Accepts a new `TcpStream`.
///
/// Returns a `Ok(None)` when the socket `WOULDBLOCK`, this means the stream
/// will be ready at a later point.
pub fn accept(&self) -> io::Result<Option<TcpStream>> {
self.sys.accept().map(|o| o.map(|s| TcpStream { sys: s }))
/// will be ready at a later point. If an accepted stream is returned, the
/// address of the peer is returned along with it
pub fn accept(&self) -> io::Result<Option<(TcpStream, SocketAddr)>> {
self.sys.accept().map(|o| o.map(|(s, a)| (TcpStream { sys: s }, a)))
}

pub fn local_addr(&self) -> io::Result<SocketAddr> {
Expand Down Expand Up @@ -234,7 +235,7 @@ impl TryAccept for TcpListener {
type Output = TcpStream;

fn accept(&self) -> io::Result<Option<TcpStream>> {
TcpListener::accept(self)
TcpListener::accept(self).map(|a| a.map(|(s, _)| s))
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/sys/unix/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ impl TcpListener {
self.inner.try_clone().map(|s| TcpListener { inner: s })
}

pub fn accept(&self) -> io::Result<Option<TcpStream>> {
self.inner.accept().and_then(|(s, _)| {
pub fn accept(&self) -> io::Result<Option<(TcpStream, SocketAddr)>> {
self.inner.accept().and_then(|(s, a)| {
try!(set_nonblock(&s));
Ok(Some(TcpStream { inner: s }))
Ok(Some((TcpStream { inner: s }, a)))
}).or_else(io::to_non_block)
}
}
Expand Down
11 changes: 7 additions & 4 deletions src/sys/windows/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ struct ListenerInner {
socket: net::TcpListener,
family: Family,
iocp: Registration,
accept: State<net::TcpStream, net::TcpStream>,
accept: State<net::TcpStream, (net::TcpStream, SocketAddr)>,
accept_buf: AcceptAddrsBuf,
}

Expand Down Expand Up @@ -435,15 +435,15 @@ impl TcpListener {
}
}

pub fn accept(&self) -> io::Result<Option<TcpStream>> {
pub fn accept(&self) -> io::Result<Option<(TcpStream, SocketAddr)>> {
let mut me = self.inner();
let ret = match mem::replace(&mut me.accept, State::Empty) {
State::Empty => return Ok(None),
State::Pending(t) => {
me.accept = State::Pending(t);
return Ok(None)
}
State::Ready(s) => Ok(Some(TcpStream::new(s, None))),
State::Ready((s, a)) => Ok(Some((TcpStream::new(s, None), a))),
State::Error(e) => Err(e),
};
self.imp.schedule_accept(&mut me);
Expand Down Expand Up @@ -517,7 +517,10 @@ fn accept_done(status: &CompletionStatus, dst: &mut Vec<IoEvent>) {
_ => unreachable!(),
};
trace!("finished an accept");
me.accept = State::Ready(socket);
me.accept = match me.accept_buf.parse(&me.socket) {
Ok(buf) => State::Ready((socket, buf.remote().unwrap())),
Err(e) => State::Error(e),
};
me2.push(&mut me, EventSet::readable(), dst);
}

Expand Down
2 changes: 1 addition & 1 deletion test/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ fn connect_then_close() {
fn ready(&mut self, event_loop: &mut EventLoop<Self>, token: Token,
_events: EventSet) {
if token == Token(1) {
let s = self.listener.accept().unwrap().unwrap();
let s = self.listener.accept().unwrap().unwrap().0;
event_loop.register(&s, Token(3), EventSet::all(),
PollOpt::edge()).unwrap();
drop(s);
Expand Down
2 changes: 1 addition & 1 deletion test/test_battery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl EchoServer {
fn accept(&mut self, event_loop: &mut EventLoop<Echo>) -> io::Result<()> {
debug!("server accepting socket");

let sock = self.sock.accept().unwrap().unwrap();
let sock = self.sock.accept().unwrap().unwrap().0;
let conn = EchoConn::new(sock,);
let tok = self.conns.insert(conn)
.ok().expect("could not add connection to slab");
Expand Down
2 changes: 1 addition & 1 deletion test/test_echo_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl EchoServer {
fn accept(&mut self, event_loop: &mut EventLoop<Echo>) -> io::Result<()> {
debug!("server accepting socket");

let sock = self.sock.accept().unwrap().unwrap();
let sock = self.sock.accept().unwrap().unwrap().0;
let conn = EchoConn::new(sock,);
let tok = self.conns.insert(conn)
.ok().expect("could not add connection to slab");
Expand Down
2 changes: 1 addition & 1 deletion test/test_register_deregister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl TestHandler {
fn handle_read(&mut self, event_loop: &mut EventLoop<TestHandler>, token: Token, _: EventSet) {
match token {
SERVER => {
let mut sock = self.server.accept().unwrap().unwrap();
let mut sock = self.server.accept().unwrap().unwrap().0;
sock.try_write_buf(&mut SliceBuf::wrap("foobar".as_bytes())).unwrap();
}
CLIENT => {
Expand Down
2 changes: 1 addition & 1 deletion test/test_timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl TestHandler {
match tok {
SERVER => {
debug!("server connection ready for accept");
let conn = self.srv.accept().unwrap().unwrap();
let conn = self.srv.accept().unwrap().unwrap().0;
event_loop.register(&conn, CONN, EventSet::all(),
PollOpt::edge()).unwrap();
event_loop.timeout_ms(conn, 200).unwrap();
Expand Down

0 comments on commit 15b0599

Please sign in to comment.