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 {

Reply via email to