Skip to content

Commit d6b4059

Browse files
committed
l7policy: pass connection close to downstream response
Pass connection close from upstream response to downstream response when upstream and downstream connections have the same 5-tuple. This helps avoid connection freeze due to 5-tuple conflict. Signed-off-by: Jarno Rajahalme <[email protected]>
1 parent e5a8dbb commit d6b4059

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

cilium/l7policy.cc

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "source/common/common/assert.h"
2727
#include "source/common/common/logger.h"
2828
#include "source/common/common/utility.h"
29+
#include "source/common/http/headers.h"
2930
#include "source/extensions/filters/http/common/factory_base.h"
3031

3132
#include "absl/status/statusor.h"
@@ -299,8 +300,10 @@ void AccessFilter::onStreamComplete() {
299300
}
300301

301302
Http::FilterHeadersStatus AccessFilter::encodeHeaders(Http::ResponseHeaderMap& headers, bool) {
303+
const auto& stream_info = callbacks_->streamInfo();
304+
302305
// Skip enforcement or logging on shadows
303-
if (callbacks_->streamInfo().isShadow()) {
306+
if (stream_info.isShadow()) {
304307
return Http::FilterHeadersStatus::Continue;
305308
}
306309

@@ -312,6 +315,33 @@ Http::FilterHeadersStatus AccessFilter::encodeHeaders(Http::ResponseHeaderMap& h
312315
return Http::FilterHeadersStatus::Continue;
313316
}
314317

318+
// Propagate connection: close from upstream to downstream (if original source is preserved)
319+
if (callbacks_->connection().has_value() && stream_info.upstreamInfo().has_value() &&
320+
stream_info.hasResponseFlag(StreamInfo::UpstreamConnectionTermination)) {
321+
// check if upstream and downstream connections have the same source and destination
322+
// addresses, respectively
323+
const auto& conn = callbacks_->connection().ref();
324+
const auto& upstream_info = stream_info.upstreamInfo().ref();
325+
326+
if (upstream_info.upstreamRemoteAddress() == conn.connectionInfoProvider().localAddress() &&
327+
upstream_info.upstreamLocalAddress() == conn.connectionInfoProvider().remoteAddress()) {
328+
ENVOY_CONN_LOG(debug,
329+
"Upstream connection with same 5-tuple closed, passing connection close to "
330+
"downstream response",
331+
conn);
332+
333+
headers.setReferenceConnection(Http::Headers::get().ConnectionValues.Close);
334+
} else {
335+
ENVOY_CONN_LOG(debug,
336+
"Upstream connection closed, but it has different 5-tuple, downstream "
337+
"connection not closed (src: {}/{}, dst: {}/{})",
338+
conn, conn.connectionInfoProvider().remoteAddress()->asStringView(),
339+
upstream_info.upstreamLocalAddress()->asStringView(),
340+
conn.connectionInfoProvider().localAddress()->asStringView(),
341+
upstream_info.upstreamRemoteAddress()->asStringView());
342+
}
343+
}
344+
315345
if (log_entry_ == nullptr) {
316346
return Http::FilterHeadersStatus::Continue;
317347
}

0 commit comments

Comments
 (0)