This is an automated email from the ASF dual-hosted git repository.
cmcfarlen pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new 492ab3b978 Fix errno assertion failure in
retry_server_connection_not_open (#12657)
492ab3b978 is described below
commit 492ab3b9786547c5c33436890b85c8867a965aa8
Author: Brian Neradt <[email protected]>
AuthorDate: Mon Nov 17 12:22:46 2025 -0600
Fix errno assertion failure in retry_server_connection_not_open (#12657)
This ensures that cause_of_death_errno is properly set with appropriate
error codes (EBADMSG for protocol errors, EPIPE for closed connections)
before retry attempts are made via set_connect_fail() when error states
are detected.
Fixes: #12654
(cherry picked from commit 6195c2be64ff1e966b866ce7cd746025e944da02)
---
src/proxy/http/HttpSM.cc | 17 ++++++++++++++---
src/proxy/http/HttpTransact.cc | 14 ++++++++++++++
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/src/proxy/http/HttpSM.cc b/src/proxy/http/HttpSM.cc
index b00b8aca8b..2cc9db3a1a 100644
--- a/src/proxy/http/HttpSM.cc
+++ b/src/proxy/http/HttpSM.cc
@@ -1122,6 +1122,13 @@ HttpSM::state_raw_http_server_open(int event, void *data)
case VC_EVENT_ERROR:
case VC_EVENT_EOS:
case NET_EVENT_OPEN_FAILED:
+ if (t_state.cause_of_death_errno == -UNKNOWN_INTERNAL_ERROR) {
+ if (event == VC_EVENT_EOS) {
+ t_state.set_connect_fail(EPIPE);
+ } else {
+ t_state.set_connect_fail(EIO);
+ }
+ }
t_state.current.state = HttpTransact::OPEN_RAW_ERROR;
// use this value just to get around other values
t_state.hdr_info.response_error = HttpTransact::STATUS_CODE_SERVER_ERROR;
@@ -2022,9 +2029,7 @@ HttpSM::state_read_server_response_header(int event, void
*data)
if (allow_error == false) {
SMDbg(dbg_ctl_http_seq, "Error parsing server response header");
t_state.current.state = HttpTransact::PARSE_ERROR;
- // We set this to 0 because otherwise
HttpTransact::retry_server_connection_not_open
- // will raise an assertion if the value is the default
UNKNOWN_INTERNAL_ERROR.
- t_state.cause_of_death_errno = 0;
+ t_state.set_connect_fail(EBADMSG);
// If the server closed prematurely on us, use the
// server setup error routine since it will forward
@@ -5155,6 +5160,9 @@ HttpSM::send_origin_throttled_response()
if (t_state.dns_info.looking_up != ResolveInfo::PARENT_PROXY) {
t_state.current.retry_attempts.maximize(t_state.configured_connect_attempts_max_retries());
}
+ if (t_state.cause_of_death_errno == -UNKNOWN_INTERNAL_ERROR) {
+ t_state.set_connect_fail(EUSERS); // Too many users.
+ }
t_state.current.state = HttpTransact::OUTBOUND_CONGESTION;
call_transact_and_set_next_state(HttpTransact::HandleResponse);
}
@@ -5568,6 +5576,9 @@ HttpSM::do_http_server_open(bool raw, bool only_direct)
httpSessionManager.purge_keepalives();
// Eventually may want to have a queue as the origin_max_connection does
to allow for a combination
// of retries and errors. But at this point, we are just going to allow
the error case.
+ if (t_state.cause_of_death_errno == -UNKNOWN_INTERNAL_ERROR) {
+ t_state.set_connect_fail(ENFILE); // Too many open files in system.
+ }
t_state.current.state = HttpTransact::CONNECTION_ERROR;
call_transact_and_set_next_state(HttpTransact::HandleResponse);
return;
diff --git a/src/proxy/http/HttpTransact.cc b/src/proxy/http/HttpTransact.cc
index 1b1acab88a..473245a345 100644
--- a/src/proxy/http/HttpTransact.cc
+++ b/src/proxy/http/HttpTransact.cc
@@ -3749,6 +3749,20 @@ HttpTransact::handle_response_from_server(State *s)
case CONNECTION_CLOSED:
case BAD_INCOMING_RESPONSE:
+ // Ensure cause_of_death_errno is set for all error states if not already
set.
+ // This prevents the assertion failure in retry_server_connection_not_open.
+ if (s->cause_of_death_errno == -UNKNOWN_INTERNAL_ERROR) {
+ if (s->current.state == PARSE_ERROR || s->current.state ==
BAD_INCOMING_RESPONSE) {
+ s->set_connect_fail(EBADMSG);
+ } else if (s->current.state == CONNECTION_CLOSED) {
+ s->set_connect_fail(EPIPE);
+ } else {
+ // Generic fallback for OPEN_RAW_ERROR, CONNECTION_ERROR,
+ // STATE_UNDEFINED, and any other unexpected error states.
+ s->set_connect_fail(EIO);
+ }
+ }
+
if (is_server_negative_cached(s)) {
max_connect_retries =
s->txn_conf->connect_attempts_max_retries_down_server - 1;
} else {