Remove panic when failing to get remote address (#107)

The listener *already* got the remote address when it was accepted, but we drop the value by using `TcpListener::incoming`. By the time we call `socket.peer_addr()`, the connection may have been closed, and thus we were panicking.

By removing the panic here, later code should notice that the connection is closed (when a `read` finds EOF), and it should be dropped gracefully.

For the same reasons (that the connection might already be closed), this reduces the `error!` from `get_original_dst` to just a `warn!`, just as `set_nodelay` is a `warn!`. No need to yell in that case.

Closes https://github.com/linkerd/linkerd2/issues/1787

Signed-off-by: Sean McArthur <sean@buoyant.io>
This commit is contained in:
Sean McArthur 2018-10-19 14:44:22 -07:00 committed by GitHub
parent f1210b4947
commit 4625302bd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 11 additions and 9 deletions

View File

@ -77,7 +77,7 @@ mod linux {
); );
if ret != 0 { if ret != 0 {
let e = io::Error::last_os_error(); let e = io::Error::last_os_error();
error!("failed to read SO_ORIGINAL_DST: {:?}", e); warn!("failed to read SO_ORIGINAL_DST: {:?}", e);
return Err(e); return Err(e);
} }

View File

@ -1,7 +1,7 @@
/// Tokio-level (not Tower-level) proxy-specific networking. /// Tokio-level (not Tower-level) proxy-specific networking.
use bytes::{Buf, BytesMut}; use bytes::{Buf, BytesMut};
use futures::{*, future::Either}; use futures::{Async, Future, IntoFuture, Poll, Stream, future::{self, Either}, stream};
use std; use std;
use std::cmp; use std::cmp;
use std::io; use std::io;
@ -186,13 +186,15 @@ impl BoundPort {
// background reactor if `listen_and_fold` is called before we've // background reactor if `listen_and_fold` is called before we've
// initialized the runtime. // initialized the runtime.
TcpListener::from_std(inner, &Handle::current()) TcpListener::from_std(inner, &Handle::current())
}).and_then(move |listener| }).and_then(move |mut listener| {
listener.incoming() let incoming = stream::poll_fn(move || {
.take(connection_limit) let ret = try_ready!(listener.poll_accept());
.and_then(move |socket| { Ok(Async::Ready(Some(ret)))
let remote_addr = socket.peer_addr() });
.expect("couldn't get remote addr!");
incoming
.take(connection_limit)
.and_then(move |(socket, remote_addr)| {
// TODO: On Linux and most other platforms it would be better // TODO: On Linux and most other platforms it would be better
// to set the `TCP_NODELAY` option on the bound socket and // to set the `TCP_NODELAY` option on the bound socket and
// then have the listening sockets inherit it. However, that // then have the listening sockets inherit it. However, that
@ -225,7 +227,7 @@ impl BoundPort {
}) })
.filter_map(|x| x) .filter_map(|x| x)
.fold(initial, f) .fold(initial, f)
) })
.map(|_| ()) .map(|_| ())
} }
} }