Skip to content

Commit b1b6b53

Browse files
authored
inbound: Do not cache gateway services (#549)
When the inbound caches gateway services, it eagerly obtains an outbound service to cache. If the outbound service employs a traffic split, this inbound service is pinned to a specific leaf, and requests will never be routed to the other leaf. This change moves the gateway fallback to be outside all of the inbound caches, so that outbound splits work as intended.
1 parent be50252 commit b1b6b53

File tree

3 files changed

+14
-13
lines changed

3 files changed

+14
-13
lines changed

linkerd/app/core/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ impl HttpError {
405405

406406
pub fn gateway_loop() -> Self {
407407
Self {
408-
message: "gateway loop detcted",
408+
message: "gateway loop detected",
409409
http: http::StatusCode::LOOP_DETECTED,
410410
grpc: Code::Aborted,
411411
reason: Reason::GatewayLoop,

linkerd/app/gateway/src/gateway.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,14 @@ where
6161
} => {
6262
// Check forwarded headers to see if this request has already
6363
// transited through this gateway.
64-
for fwd in request
64+
for forwarded in request
6565
.headers()
6666
.get_all(http::header::FORWARDED)
6767
.into_iter()
6868
.filter_map(|h| h.to_str().ok())
6969
{
70-
if let Some(by) = fwd_by(fwd) {
70+
if let Some(by) = fwd_by(forwarded) {
71+
tracing::info!(%forwarded);
7172
if by == local_identity.as_ref() {
7273
return Box::new(future::err(HttpError::gateway_loop().into()));
7374
}

linkerd/app/inbound/src/lib.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,6 @@ impl Config {
216216
// Normalizes the URI, i.e. if it was originally in
217217
// absolute-form on the outbound side.
218218
.push(normalize_uri::layer())
219-
.push(admit::AdmitLayer::new(prevent_loop))
220-
.push_on_response(svc::layers().box_http_response())
221-
.push_fallback_on_error::<prevent_loop::LoopPrevented, _>(
222-
svc::stack(http_loopback)
223-
.push_on_response(svc::layers().box_http_request())
224-
.into_inner(),
225-
)
226219
.push(http_target_observability)
227220
.check_service::<Target>()
228221
.into_new_service()
@@ -279,13 +272,20 @@ impl Config {
279272
svc::stack(http_profile_cache)
280273
.push_on_response(svc::layers().box_http_response())
281274
.push_make_ready()
282-
// Don't resolve profiles for inbound-targetted requests. They'll be
283-
// resolved on the outbound side if necsesary.
284-
.push(admit::AdmitLayer::new(prevent_loop))
285275
.push_fallback(
286276
http_target_cache
287277
.push_on_response(svc::layers().box_http_response().box_http_request()),
288278
)
279+
// If the traffic is targeted at the inbound port, send it through
280+
// the loopback service (i.e. as a gateway). This is done before
281+
// caching so that the loopback stack can determine whether it
282+
// should cache or not.
283+
.push(admit::AdmitLayer::new(prevent_loop))
284+
.push_fallback_on_error::<prevent_loop::LoopPrevented, _>(
285+
svc::stack(http_loopback)
286+
.push_on_response(svc::layers().box_http_request())
287+
.into_inner(),
288+
)
289289
.check_service::<Target>()
290290
.into_inner()
291291
}

0 commit comments

Comments
 (0)