Skip to content

Commit f481c66

Browse files
authored
Prevent server errors from panicking the proxy (#943)
The TCP server currently returns an error if an `accept(2)` call fails with an error. This error can cause the proxy to panic. This change handles this error gracefully, emitting a warning. The server task no longer returns a Result-type.
1 parent 4399726 commit f481c66

File tree

6 files changed

+17
-23
lines changed

6 files changed

+17
-23
lines changed

linkerd/app/core/src/serve.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ pub async fn serve<M, A, I>(
1515
listen: impl Stream<Item = std::io::Result<(Addrs, I)>>,
1616
mut new_accept: M,
1717
shutdown: impl Future,
18-
) -> Result<(), Error>
19-
where
18+
) where
2019
I: Send + 'static,
2120
M: svc::NewService<Addrs, Service = A>,
2221
A: tower::Service<io::ScopedIo<I>, Response = ()> + Send + 'static,
@@ -27,10 +26,16 @@ where
2726
futures::pin_mut!(listen);
2827
loop {
2928
match listen.next().await {
30-
None => return Ok(()),
29+
None => return,
3130
Some(conn) => {
3231
// If the listener returned an error, complete the task.
33-
let (addrs, io) = conn?;
32+
let (addrs, io) = match conn {
33+
Ok(conn) => conn,
34+
Err(error) => {
35+
warn!(%error, "Server failed to accept connection");
36+
continue;
37+
}
38+
};
3439

3540
// The local addr should be instrumented from the listener's context.
3641
let span = info_span!(
@@ -79,7 +84,7 @@ where
7984
// This ensures that the accept service's readiness can't block shutdown.
8085
tokio::select! {
8186
res = accept => { res }
82-
_ = shutdown => { Ok(()) }
87+
_ = shutdown => {}
8388
}
8489
}
8590

linkerd/app/inbound/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,7 @@ impl Inbound<()> {
152152
.to_tcp_connect()
153153
.into_server(listen_addr.port(), profiles, gateway);
154154
let shutdown = self.runtime.drain.signaled();
155-
serve::serve(listen, stack, shutdown)
156-
.await
157-
.expect("Inbound server failed");
155+
serve::serve(listen, stack, shutdown).await
158156
};
159157

160158
(listen_addr, serve)

linkerd/app/outbound/src/lib.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,11 @@ impl Outbound<()> {
187187
.into_inner();
188188
let stack = self.to_ingress(profiles, tcp, http);
189189
let shutdown = self.runtime.drain.signaled();
190-
serve::serve(listen, stack, shutdown)
191-
.await
192-
.expect("Outbound server failed");
190+
serve::serve(listen, stack, shutdown).await;
193191
} else {
194192
let stack = self.to_tcp_connect().into_server(resolve, profiles);
195193
let shutdown = self.runtime.drain.signaled();
196-
serve::serve(listen, stack, shutdown)
197-
.await
198-
.expect("Outbound server failed");
194+
serve::serve(listen, stack, shutdown).await;
199195
}
200196
};
201197

linkerd/app/src/admin.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub struct Config {
2525
pub struct Admin {
2626
pub listen_addr: SocketAddr,
2727
pub latch: admin::Latch,
28-
pub serve: Pin<Box<dyn std::future::Future<Output = Result<(), Error>> + Send + 'static>>,
28+
pub serve: Pin<Box<dyn std::future::Future<Output = ()> + Send + 'static>>,
2929
}
3030

3131
#[derive(Debug, Default)]

linkerd/app/src/lib.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use linkerd_channel::into_stream::IntoStream;
2020
use std::{net::SocketAddr, pin::Pin};
2121
use tokio::{sync::mpsc, time::Duration};
2222
use tracing::instrument::Instrument;
23-
use tracing::{debug, error, info, info_span};
23+
use tracing::{debug, info, info_span};
2424

2525
/// Spawns a sidecar proxy.
2626
///
@@ -255,7 +255,6 @@ impl App {
255255
tokio::spawn(
256256
admin
257257
.serve
258-
.map_err(|e| panic!("admin server died: {}", e))
259258
.instrument(info_span!("admin", listen.addr = %admin.listen_addr)),
260259
);
261260

@@ -293,11 +292,7 @@ impl App {
293292
)
294293
.instrument(info_span!("tap_clean")),
295294
);
296-
tokio::spawn(
297-
serve
298-
.map_err(|error| error!(%error, "server died"))
299-
.instrument(info_span!("tap")),
300-
);
295+
tokio::spawn(serve.instrument(info_span!("tap")));
301296
}
302297

303298
if let oc_collector::OcCollector::Enabled(oc) = oc_collector {

linkerd/app/src/tap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub enum Tap {
2323
Enabled {
2424
listen_addr: SocketAddr,
2525
registry: tap::Registry,
26-
serve: Pin<Box<dyn std::future::Future<Output = Result<(), Error>> + Send + 'static>>,
26+
serve: Pin<Box<dyn std::future::Future<Output = ()> + Send + 'static>>,
2727
},
2828
}
2929

0 commit comments

Comments
 (0)