SolidWallOfCode commented on a change in pull request #7657:
URL: https://github.com/apache/trafficserver/pull/7657#discussion_r631930016



##########
File path: proxy/http/HttpTransact.cc
##########
@@ -6536,52 +6536,77 @@ HttpTransact::process_quick_http_filter(State *s, int 
method)
 bool
 HttpTransact::will_this_request_self_loop(State *s)
 {
+  // The self-loop detection for this ATS node will allow up to 
max_proxy_cycles
+  // (each time it sees it returns to itself it is one cycle) before declaring 
a self-looping condition detected.
+  // If max_proxy_cycles is > 0 then then next-hop is disabled since --
+  //   * if first cycle then it is alright okay
+  //   * if not first cycle then will be detected by via string checking the 
next time that
+  //     it enters the node
+  int max_proxy_cycles = s->txn_conf->max_proxy_cycles;
+
   ////////////////////////////////////////
   // check if we are about to self loop //
   ////////////////////////////////////////
   if (s->dns_info.lookup_success) {
-    in_port_t dst_port   = s->hdr_info.client_request.url_get()->port_get(); 
// going to this port.
-    in_port_t local_port = s->client_info.dst_addr.host_order_port();        
// already connected proxy port.
-    // It's a loop if connecting to the same port as it already connected to 
the proxy and
-    // it's a proxy address or the same address it already connected to.
-    if (dst_port == local_port && (ats_ip_addr_eq(s->host_db_info.ip(), 
&Machine::instance()->ip.sa) ||
-                                   ats_ip_addr_eq(s->host_db_info.ip(), 
s->client_info.dst_addr))) {
-      switch (s->dns_info.looking_up) {
-      case ORIGIN_SERVER:
-        TxnDebug("http_transact", "host ip and port same as local ip and port 
- bailing");
-        break;
-      case PARENT_PROXY:
-        TxnDebug("http_transact", "parent proxy ip and port same as local ip 
and port - bailing");
-        break;
-      default:
-        TxnDebug("http_transact", "unknown's ip and port same as local ip and 
port - bailing");
-        break;
+    TxnDebug("http_transact", "max_proxy_cycles = %d", max_proxy_cycles);
+    if (max_proxy_cycles == 0) {
+      in_port_t dst_port   = s->hdr_info.client_request.url_get()->port_get(); 
// going to this port.
+      in_port_t local_port = s->client_info.dst_addr.host_order_port();        
// already connected proxy port.
+      // It's a loop if connecting to the same port as it already connected to 
the proxy and
+      // it's a proxy address or the same address it already connected to.
+      TxnDebug("http_transact", "dst_port = %d local_port = %d", dst_port, 
local_port);
+      if (dst_port == local_port && (ats_ip_addr_eq(s->host_db_info.ip(), 
&Machine::instance()->ip.sa) ||
+                                     ats_ip_addr_eq(s->host_db_info.ip(), 
s->client_info.dst_addr))) {
+        switch (s->dns_info.looking_up) {
+        case ORIGIN_SERVER:
+          TxnDebug("http_transact", "host ip and port same as local ip and 
port - bailing");
+          break;
+        case PARENT_PROXY:
+          TxnDebug("http_transact", "parent proxy ip and port same as local ip 
and port - bailing");
+          break;
+        default:
+          TxnDebug("http_transact", "unknown's ip and port same as local ip 
and port - bailing");
+          break;
+        }
+        SET_VIA_STRING(VIA_ERROR_TYPE, VIA_ERROR_LOOP_DETECTED);
+        build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Cycle Detected", 
"request#cycle_detected");
+        return true;
       }
-      SET_VIA_STRING(VIA_ERROR_TYPE, VIA_ERROR_LOOP_DETECTED);
-      build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Cycle Detected", 
"request#cycle_detected");
-      return true;
     }
 
     // Now check for a loop using the Via string.
-    const char *uuid     = Machine::instance()->uuid.getString();
+    int count            = 0;
     MIMEField *via_field = 
s->hdr_info.client_request.field_find(MIME_FIELD_VIA, MIME_LEN_VIA);
+    std::string_view uuid{Machine::instance()->uuid.getString()};
 
     while (via_field) {
       // No need to waste cycles comma separating the via values since we want 
to do a match anywhere in the
       // in the string.  We can just loop over the dup hdr fields
       int via_len;
       const char *via_string = via_field->value_get(&via_len);
 
-      if (via_string && ptr_len_str(via_string, via_len, uuid)) {
-        SET_VIA_STRING(VIA_ERROR_TYPE, VIA_ERROR_LOOP_DETECTED);
-        TxnDebug("http_transact", "Incoming via: %.*s has (%s[%s] (%s))", 
via_len, via_string, s->http_config_param->proxy_hostname,
-                 uuid, s->http_config_param->proxy_request_via_string);
-        build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Multi-Hop Cycle 
Detected", "request#cycle_detected");
-        return true;
+      if ((count <= max_proxy_cycles) && via_string) {
+        std::string_view current{via_field->value_get()};

Review comment:
       You could do
   ```
   std::string_view current{via_string};
   ```
   or alternatively
   ```
   std::string_view current{via_field-value_get()};
   if ( (count <= max_proxy_cycles) && ! current.empty()) {
     // ....
   ```
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to