Skip to content

Commit 308a730

Browse files
authored
inbound: Apply loop detection on the connect stack (#660)
a233e1a altered the accept stack so that both TCP and HTTP stacks are instantiated prior to performing detection on a socket. This will allow us to cache these stacks for each destination. However, this eager binding broke the gateway fallback logic, since the TCP stack's failure invalidated the HTTP stacks' fallback to the gateway. This change moves loop detection onto the TCP connection stack so this eager binding does not fail. Fixes linkerd/linkerd2#4943
1 parent 07a448e commit 308a730

File tree

2 files changed

+18
-6
lines changed

2 files changed

+18
-6
lines changed

linkerd/app/inbound/src/lib.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ impl Config {
6868
P::Future: Unpin + Send,
6969
P::Error: Send,
7070
{
71-
let tcp_connect = self.build_tcp_connect(&metrics);
7271
let prevent_loop = PreventLoop::from(listen_addr.port());
72+
let tcp_connect = self.build_tcp_connect(prevent_loop, &metrics);
7373
let http_router = self.build_http_router(
7474
tcp_connect.clone(),
7575
prevent_loop,
@@ -82,7 +82,6 @@ impl Config {
8282
self.build_server(
8383
listen_addr,
8484
listen,
85-
prevent_loop,
8685
tcp_connect,
8786
http_router,
8887
local_identity,
@@ -95,6 +94,7 @@ impl Config {
9594

9695
pub fn build_tcp_connect(
9796
&self,
97+
prevent_loop: PreventLoop,
9898
metrics: &ProxyMetrics,
9999
) -> impl tower::Service<
100100
TcpEndpoint,
@@ -116,6 +116,7 @@ impl Config {
116116
// Limits the time we wait for a connection to be established.
117117
.push_timeout(self.proxy.connect.timeout)
118118
.push(metrics.transport.layer_connect(TransportLabels))
119+
.push(admit::AdmitLayer::new(prevent_loop))
119120
.into_inner()
120121
}
121122

@@ -279,7 +280,6 @@ impl Config {
279280
self,
280281
listen_addr: std::net::SocketAddr,
281282
listen: impl Stream<Item = std::io::Result<listen::Connection>> + Send + 'static,
282-
prevent_loop: impl Into<PreventLoop>,
283283
tcp_connect: C,
284284
http_router: H,
285285
local_identity: tls::Conditional<identity::Local>,
@@ -371,8 +371,7 @@ impl Config {
371371
// Forwards TCP streams that cannot be decoded as HTTP.
372372
let tcp_forward = svc::stack(tcp_connect)
373373
.push_make_thunk()
374-
.push(svc::layer::mk(tcp::Forward::new))
375-
.push(admit::AdmitLayer::new(prevent_loop.into()));
374+
.push(svc::layer::mk(tcp::Forward::new));
376375

377376
let http = DetectHttp::new(
378377
h2_settings,

linkerd/app/inbound/src/prevent_loop.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::endpoint::{Target, TcpEndpoint};
1+
use super::endpoint::{HttpEndpoint, Target, TcpEndpoint};
22
use futures::future;
33
use linkerd2_app_core::{admit, proxy::http};
44
use std::task::{Context, Poll};
@@ -33,6 +33,19 @@ impl admit::Admit<Target> for PreventLoop {
3333
}
3434
}
3535

36+
impl admit::Admit<HttpEndpoint> for PreventLoop {
37+
type Error = LoopPrevented;
38+
39+
fn admit(&mut self, ep: &HttpEndpoint) -> Result<(), Self::Error> {
40+
tracing::debug!(addr = %ep.port, self.port);
41+
if ep.port == self.port {
42+
return Err(LoopPrevented { port: self.port });
43+
}
44+
45+
Ok(())
46+
}
47+
}
48+
3649
impl admit::Admit<TcpEndpoint> for PreventLoop {
3750
type Error = LoopPrevented;
3851

0 commit comments

Comments
 (0)