MCPcopy Create free account
hub / github.com/apache/trafficserver / will_this_request_self_loop

Method will_this_request_self_loop

src/proxy/http/HttpTransact.cc:6579–6657  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

6577}
6578
6579bool
6580HttpTransact::will_this_request_self_loop(State *s)
6581{
6582 // The self-loop detection for this ATS node will allow up to max_proxy_cycles
6583 // (each time it sees it returns to itself it is one cycle) before declaring a self-looping condition detected.
6584 // If max_proxy_cycles is > 0 then next-hop is disabled since --
6585 // * if first cycle then it is alright okay
6586 // * if not first cycle then will be detected by via string checking the next time that
6587 // it enters the node
6588 int max_proxy_cycles = s->txn_conf->max_proxy_cycles;
6589
6590 ////////////////////////////////////////
6591 // check if we are about to self loop //
6592 ////////////////////////////////////////
6593 if (s->dns_info.active) {
6594 TxnDbg(dbg_ctl_http_transact, "max_proxy_cycles = %d", max_proxy_cycles);
6595 if (max_proxy_cycles == 0) {
6596 in_port_t dst_port = s->hdr_info.client_request.url_get()->port_get(); // going to this port.
6597 in_port_t local_port = s->client_info.dst_addr.host_order_port(); // already connected proxy port.
6598 // It's a loop if connecting to the same port as it already connected to the proxy and
6599 // it's a proxy address or the same address it already connected to.
6600 TxnDbg(dbg_ctl_http_transact, "dst_port = %d local_port = %d", dst_port, local_port);
6601 if (dst_port == local_port && ((s->dns_info.active->data.ip == &Machine::instance()->ip.sa) ||
6602 (s->dns_info.active->data.ip == s->client_info.dst_addr))) {
6603 switch (s->dns_info.looking_up) {
6604 case ResolveInfo::ORIGIN_SERVER:
6605 TxnDbg(dbg_ctl_http_transact, "host ip and port same as local ip and port - bailing");
6606 break;
6607 case ResolveInfo::PARENT_PROXY:
6608 TxnDbg(dbg_ctl_http_transact, "parent proxy ip and port same as local ip and port - bailing");
6609 break;
6610 default:
6611 TxnDbg(dbg_ctl_http_transact, "unknown's ip and port same as local ip and port - bailing");
6612 break;
6613 }
6614 SET_VIA_STRING(VIA_ERROR_TYPE, VIA_ERROR_LOOP_DETECTED);
6615 Metrics::Counter::increment(http_rsb.proxy_loop_detected);
6616 build_error_response(s, HTTP_STATUS_BAD_REQUEST, "Cycle Detected", "request#cycle_detected");
6617 return true;
6618 }
6619 }
6620
6621 // Now check for a loop using the Via string.
6622 int count = 0;
6623 MIMEField *via_field = s->hdr_info.client_request.field_find(MIME_FIELD_VIA, MIME_LEN_VIA);
6624 std::string_view uuid{Machine::instance()->uuid.getString()};
6625
6626 while (via_field) {
6627 // No need to waste cycles comma separating the via values since we want to do a match anywhere in the
6628 // in the string. We can just loop over the dup hdr fields
6629 auto via_string{via_field->value_get()};
6630
6631 if ((count <= max_proxy_cycles) && via_string.data()) {
6632 std::string_view current{via_field->value_get()};
6633 std::string_view::size_type offset;
6634 TxnDbg(dbg_ctl_http_transact, "Incoming via: \"%.*s\" --has-- (%s[%s] (%s))", static_cast<int>(via_string.length()),
6635 via_string.data(), s->http_config_param->proxy_hostname, uuid.data(),
6636 s->http_config_param->proxy_request_via_string);

Callers

nothing calls this directly

Calls 11

incrementFunction · 0.85
url_getMethod · 0.80
field_findMethod · 0.80
port_getMethod · 0.45
host_order_portMethod · 0.45
getStringMethod · 0.45
value_getMethod · 0.45
dataMethod · 0.45
lengthMethod · 0.45
findMethod · 0.45
remove_prefixMethod · 0.45

Tested by

no test coverage detected