Skip to content

Commit ab9d27a

Browse files
committed
ingress: Fall back to normal TCP forwarding
Currently, ingress-mode proxies ONLY support HTTP traffic. This is an unfortunate tradeoff, as ingress may make arbitrary outbound connections (e.g., TLS calls to external services). To avoid requiring that these connections be completely skipped from the proxy, we can fallback to transporting these connections after HTTP detection fails. Ingress-mode proxies DO NOT fully honor port opacity configurations: HTTP detection is always performed before discovery is attempted. Signed-off-by: Oliver Gould <[email protected]>
1 parent 29fc952 commit ab9d27a

File tree

5 files changed

+333
-228
lines changed

5 files changed

+333
-228
lines changed

linkerd/app/core/src/svc.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub use linkerd_stack::{
1010
ExtractParam, Fail, FailFast, Filter, InsertParam, MakeConnection, MapErr, MapTargetLayer,
1111
NewRouter, NewService, Param, Predicate, UnwrapOr,
1212
};
13-
pub use linkerd_stack_tracing::{NewInstrument, NewInstrumentLayer};
13+
pub use linkerd_stack_tracing::{GetSpan, NewInstrument, NewInstrumentLayer};
1414
use std::{
1515
task::{Context, Poll},
1616
time::Duration,
@@ -262,6 +262,14 @@ impl<S> Stack<S> {
262262
self
263263
}
264264

265+
pub fn check_new_accept<T, I>(self) -> Self
266+
where
267+
S: NewService<T>,
268+
S::Service: Service<I, Response = ()>,
269+
{
270+
self
271+
}
272+
265273
/// Validates that this stack serves T-typed targets.
266274
pub fn check_clone_new_service<T, Req>(self) -> Self
267275
where

linkerd/app/outbound/src/discover.rs

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
use crate::{tcp, Outbound};
1+
use crate::Outbound;
22
use linkerd_app_core::{
33
io, profiles,
44
svc::{self, stack::Param},
5-
transport::{self, metrics::SensorIo, OrigDstAddr},
5+
transport::OrigDstAddr,
66
Error,
77
};
8-
use std::convert::TryFrom;
9-
use tracing::{debug, debug_span, info_span};
8+
use tracing::debug;
109

1110
impl<N> Outbound<N> {
1211
/// Discovers the profile for a TCP endpoint.
@@ -23,41 +22,34 @@ impl<N> Outbound<N> {
2322
>
2423
where
2524
T: Param<OrigDstAddr>,
25+
T: Clone + Eq + std::fmt::Debug + std::hash::Hash + Send + Sync + 'static,
2626
I: io::AsyncRead + io::AsyncWrite + io::PeerAddr + std::fmt::Debug + Send + Unpin + 'static,
27-
N: svc::NewService<(Option<profiles::Receiver>, tcp::Accept), Service = NSvc>
28-
+ Clone
29-
+ Send
30-
+ Sync
31-
+ 'static,
32-
NSvc: svc::Service<SensorIo<I>, Response = (), Error = Error> + Send + 'static,
27+
N: svc::NewService<(Option<profiles::Receiver>, T), Service = NSvc>,
28+
N: Clone + Send + Sync + 'static,
29+
NSvc: svc::Service<I, Response = (), Error = Error> + Send + 'static,
3330
NSvc::Future: Send,
3431
P: profiles::GetProfile<profiles::LookupAddr> + Clone + Send + Sync + 'static,
3532
P::Future: Send,
3633
P::Error: Send,
3734
{
38-
self.map_stack(|config, rt, accept| {
35+
self.map_stack(|config, rt, inner| {
3936
let allow = config.allow_discovery.clone();
40-
accept
41-
.push(profiles::discover::layer(
42-
profiles,
43-
move |a: tcp::Accept| {
44-
let OrigDstAddr(addr) = a.orig_dst;
45-
if allow.matches_ip(addr.ip()) {
46-
debug!("Allowing profile lookup");
47-
Ok(profiles::LookupAddr(addr.into()))
48-
} else {
49-
tracing::debug!(
50-
%addr,
51-
networks = %allow.nets(),
52-
"Profile discovery not in configured search networks",
53-
);
54-
Err(profiles::DiscoveryRejected::new(
55-
"not in configured search networks",
56-
))
57-
}
58-
},
59-
))
60-
.instrument(|_: &_| debug_span!("profile"))
37+
inner
38+
.push(profiles::discover::layer(profiles, move |t: T| {
39+
let OrigDstAddr(addr) = t.param();
40+
if allow.matches_ip(addr.ip()) {
41+
debug!("Allowing profile lookup");
42+
return Ok(profiles::LookupAddr(addr.into()));
43+
}
44+
tracing::debug!(
45+
%addr,
46+
networks = %allow.nets(),
47+
"Profile discovery not in configured search networks",
48+
);
49+
Err(profiles::DiscoveryRejected::new(
50+
"not in configured search networks",
51+
))
52+
}))
6153
.push_on_service(
6254
svc::layers()
6355
// If the traffic split is empty/unavailable, eagerly fail
@@ -77,13 +69,7 @@ impl<N> Outbound<N> {
7769
))
7870
.push_spawn_buffer(config.proxy.buffer_capacity),
7971
)
80-
.push(transport::metrics::NewServer::layer(
81-
rt.metrics.proxy.transport.clone(),
82-
))
8372
.push_cache(config.proxy.cache_max_idle_age)
84-
.instrument(|a: &tcp::Accept| info_span!("server", orig_dst = %a.orig_dst))
85-
.push_request_filter(|t: T| tcp::Accept::try_from(t.param()))
86-
.push(rt.metrics.tcp_errors.to_layer())
8773
.push(svc::ArcNewService::layer())
8874
.check_new_service::<T, I>()
8975
})

0 commit comments

Comments
 (0)