Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion proxy/http/HttpSM.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7832,7 +7832,8 @@ HttpSM::set_next_state()
t_state.dns_info.resolved_p = true; // seems dangerous - where's the IP address?
call_transact_and_set_next_state(nullptr);
break;
} else if (t_state.parent_result.result == PARENT_UNDEFINED && t_state.dns_info.resolve_immediate()) {
} else if (t_state.dns_info.resolved_p) {
SMDebug("dns", "Skipping DNS lookup because the address is already set.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, TSHttpTxnServerAddrSet() is called in the CACHE_LOOKUP_COMPLETE hook in the new Au test, which presumably comes after DNS lookup?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. Yahoo's internal plugin relies upon redirecting after CACHE_LOOKUP_COMPLETE in order to work. Fortunately it seems to work. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it looks like CACHE_LOOKUP comes before DNS lookup. Here's the relevant debug logs from the autest that exercises this (note that SM_ACTION_CACHE_LOOKUP comes before SM_ACTION_DNS_LOOKUP):

  147 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpTransact.cc:2106 (DecideCacheLookup)> (http_seq) [0] Will do cache lookup                                  
  148 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpTransact.cc:2149 (DecideCacheLookup)> (http_trans) Next action SM_ACTION_CACHE_LOOKUP; nullptr            
  149 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpSM.cc:7735 (call_transact_and_set_next_state)> (http) [0] State Transition: SM_ACTION_API_POST_REMAP -> SM_ACTION_CACHE_LOOKUP
  150 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpSM.cc:4922 (do_cache_lookup_and_read)> (http_seq) [0] Issuing cache lookup for URL http://non.existent.server.com:61008/pictures/flower.jpe
      g                                                                                                                                                                    
  151 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpCacheSM.cc:100 (state_cache_open_read)> (http_cache) [0] [&HttpCacheSM::state_cache_open_read, CACHE_EVENT_OPEN_READ_FAILED/TS_EVENT_CACHE_
      OPEN_READ_FAILED]                                                                                                                                          
  152 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpSM.cc:2644 (main_handler)> (http) [0] CACHE_EVENT_OPEN_READ_FAILED/TS_EVENT_CACHE_OPEN_READ_FAILED, 1103                         
  153 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpSM.cc:2572 (state_cache_open_read)> (http) [0] [&HttpSM::state_cache_open_read, CACHE_EVENT_OPEN_READ_FAILED/TS_EVENT_CACHE_OPEN_READ_FAILE
      D]                                                                                                                                                      
  154 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpSM.cc:2606 (state_cache_open_read)> (http) [0] cache_open_read - CACHE_EVENT_OPEN_READ_FAILED with ECACHE_NO_DOC (20400)
  155 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpSM.cc:2609 (state_cache_open_read)> (http) [0] open read failed.
  156 [Aug 16 15:52:47.829] [ET_NET 8] DEBUG: <HttpSM.cc:1409 (state_api_callout)> (http) [0] calling plugin on hook TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK at hook 0x3dcf6fe0
  157 [Aug 16 15:52:47.830] [ET_NET 8] DIAG: (test_plugin) Successfully set a transaction's origin to 127.0.0.1:61001                                                                      
  158 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpSM.cc:1298 (state_api_callback)> (http) [0] [&HttpSM::state_api_callback, HTTP_API_CONTINUE/TS_EVENT_HTTP_CONTINUE]
  159 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpSM.cc:1338 (state_api_callout)> (http) [0] [&HttpSM::state_api_callout, HTTP_API_CONTINUE/TS_EVENT_HTTP_CONTINUE]                   
  160 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:2365 (HandleCacheOpenRead)> (http_trans) [0] [HttpTransact::HandleCacheOpenRead]                                     
  161 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:2395 (HandleCacheOpenRead)> (http_trans) [0] CacheOpenRead -- miss             
  162 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:3258 (HandleCacheOpenReadMiss)> (http_trans) [0] --- MISS
  163 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:3259 (HandleCacheOpenReadMiss)> (http_seq) [0] Miss in cache                                                      
  164 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:5194 (get_ka_info_from_config)> (http_trans) [0] server_info->http_version 1.1, check_hostdb 0                          
  165 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:2622 (CallOSDNSLookup)> (http) [0] non.existent.server.com                                                     
  166 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:2636 (CallOSDNSLookup)> (http_trans) Next action SM_ACTION_DNS_LOOKUP; OSDNSLookup
  167 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpSM.cc:7735 (call_transact_and_set_next_state)> (http) [0] State Transition: SM_ACTION_CACHE_LOOKUP -> SM_ACTION_DNS_LOOKUP
  168 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpSM.cc:7836 (set_next_state)> (dns) [0] Skipping DNS lookup because the address is already set.                            
  169 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:1885 (OSDNSLookup)> (http_trans) [0] Entering HttpTransact::OSDNSLookup                                              
  170 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:1928 (OSDNSLookup)> (http_seq) [0] DNS Lookup successful                                                           
  171 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:1966 (OSDNSLookup)> (http_trans) [0] DNS lookup for O.S. successful IP: 127.0.0.1:61001
  172 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpTransact.cc:2045 (OSDNSLookup)> (http_trans) Next action SM_ACTION_API_OS_DNS; HandleCacheOpenReadMiss                          
  173 [Aug 16 15:52:47.830] [ET_NET 8] DEBUG: <HttpSM.cc:7735 (call_transact_and_set_next_state)> (http) [0] State Transition: SM_ACTION_DNS_LOOKUP -> SM_ACTION_API_OS_DNS            

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

call_transact_and_set_next_state(nullptr);
break;
}
Expand Down
19 changes: 10 additions & 9 deletions proxy/http/HttpTransact.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
limitations under the License.
*/

#include "tscore/ink_inet.h"
#include "tscpp/util/ts_bw_format.h"

#include "ts/parentselectdefs.h"
Expand Down Expand Up @@ -1829,8 +1830,8 @@ HttpTransact::PPDNSLookup(State *s)
s->parent_info.dst_addr.network_order_port() = htons(s->parent_result.port);
get_ka_info_from_host_db(s, &s->parent_info, &s->client_info, s->dns_info.active);

char addrbuf[INET6_ADDRSTRLEN];
TxnDebug("http_trans", "DNS lookup for successful IP: %s", ats_ip_ntop(&s->parent_info.dst_addr.sa, addrbuf, sizeof(addrbuf)));
ip_port_text_buffer addrbuf;
TxnDebug("http_trans", "DNS lookup for successful IP: %s", ats_ip_nptop(&s->parent_info.dst_addr.sa, addrbuf, sizeof(addrbuf)));
}

// Since this function can be called several times while retrying
Expand Down Expand Up @@ -1961,9 +1962,9 @@ HttpTransact::OSDNSLookup(State *s)
ats_ip_copy(&s->request_data.dest_ip, &s->server_info.dst_addr);
get_ka_info_from_host_db(s, &s->server_info, &s->client_info, s->dns_info.active);

char addrbuf[INET6_ADDRSTRLEN];
ip_port_text_buffer addrbuf;
TxnDebug("http_trans", "DNS lookup for O.S. successful IP: %s",
ats_ip_ntop(&s->server_info.dst_addr.sa, addrbuf, sizeof(addrbuf)));
ats_ip_nptop(&s->server_info.dst_addr.sa, addrbuf, sizeof(addrbuf)));

if (s->redirect_info.redirect_in_process) {
// If dns lookup was not successful, the code below will handle the error.
Expand All @@ -1989,7 +1990,7 @@ HttpTransact::OSDNSLookup(State *s)
} else {
// Invalid server response, since we can't copy it we are going to reject
TxnDebug("http_trans", "Invalid server response. Rejecting.");
Error("Invalid server response. Rejecting. IP: %s", ats_ip_ntop(&s->server_info.dst_addr.sa, addrbuf, sizeof(addrbuf)));
Error("Invalid server response. Rejecting. IP: %s", ats_ip_nptop(&s->server_info.dst_addr.sa, addrbuf, sizeof(addrbuf)));
}
build_error_response(s, HTTP_STATUS_FORBIDDEN, nullptr, "request#syntax_error");
SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
Expand Down Expand Up @@ -3628,9 +3629,9 @@ HttpTransact::handle_response_from_parent(State *s)
s->state_machine->do_hostdb_update_if_necessary();
}

char addrbuf[INET6_ADDRSTRLEN];
ip_port_text_buffer addrbuf;
TxnDebug("http_trans", "[%d] failed to connect to parent %s", s->current.retry_attempts.get(),
ats_ip_ntop(&s->current.server->dst_addr.sa, addrbuf, sizeof(addrbuf)));
ats_ip_nptop(&s->current.server->dst_addr.sa, addrbuf, sizeof(addrbuf)));

// If the request is not retryable, just give up!
if (!is_request_retryable(s)) {
Expand Down Expand Up @@ -3815,9 +3816,9 @@ HttpTransact::handle_response_from_server(State *s)
void
HttpTransact::error_log_connection_failure(State *s, ServerState_t conn_state)
{
char addrbuf[INET6_ADDRSTRLEN];
ip_port_text_buffer addrbuf;
TxnDebug("http_trans", "[%d] failed to connect [%d] to %s", s->current.retry_attempts.get(), conn_state,
ats_ip_ntop(&s->current.server->dst_addr.sa, addrbuf, sizeof(addrbuf)));
ats_ip_nptop(&s->current.server->dst_addr.sa, addrbuf, sizeof(addrbuf)));

if (s->current.server->had_connect_fail()) {
char *url_str = s->hdr_info.client_request.url_string_get(&s->arena);
Expand Down
1 change: 1 addition & 0 deletions tests/gold_tests/pluginTest/tsapi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
#######################

add_autest_plugin(test_tsapi test_tsapi.cc)
add_autest_plugin(test_TSHttpTxnServerAddrSet test_TSHttpTxnServerAddrSet.cc)
4 changes: 4 additions & 0 deletions tests/gold_tests/pluginTest/tsapi/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@

noinst_LTLIBRARIES += gold_tests/pluginTest/tsapi/test_tsapi.la
gold_tests_pluginTest_tsapi_test_tsapi_la_SOURCES = gold_tests/pluginTest/tsapi/test_tsapi.cc

noinst_LTLIBRARIES += gold_tests/pluginTest/tsapi/test_TSHttpTxnServerAddrSet.la
gold_tests_pluginTest_tsapi_test_TSHttpTxnServerAddrSet_la_SOURCES = \
gold_tests/pluginTest/tsapi/test_TSHttpTxnServerAddrSet.cc
176 changes: 176 additions & 0 deletions tests/gold_tests/pluginTest/tsapi/test_TSHttpTxnServerAddrSet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <ts/ts.h>

#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include <cstdlib>

#include <memory>
#include <string_view>
#include <string>

namespace
{

std::string_view PNAME = "test_plugin";

/** Represents the origin address and port that the user specified to which to
* redirect requests. */
class TargetAddress
{
public:
/** Constructs a TargetAddress object from the given address and port.
*
* @param address The address to which to redirect requests.
* @param port The port to which to redirect requests.
*/
TargetAddress(char const *address, int port) : _address(address), _port(port)
{
_sockaddr.sin_family = AF_INET;
_sockaddr.sin_port = htons(port);
if (inet_pton(AF_INET, address, &_sockaddr.sin_addr) != 1) {
TSError("Invalid address %s", address);
_is_valid = false;
} else {
_is_valid = true;
}
}

/** Returns the address to which to redirect requests.
*
* @return The address to which to redirect requests.
*/
std::string_view
get_address() const
{
return _address;
}

/** Returns the port to which to redirect requests.
*
* @return The port to which to redirect requests.
*/
int
get_port() const
{
return _port;
}

/** Returns whether the address and port are valid.
*
* @return Whether the address and port are valid.
*/
bool
is_valid() const
{
return _is_valid;
}

/** Returns the sockaddr representing the user's specified origin address and
* port.
*
* @return The sockaddr representing the user's specified origin address and
* port.
*/
sockaddr const *
get_sockaddr() const
{
return reinterpret_cast<sockaddr const *>(&_sockaddr);
}

private:
std::string _address;
int _port;
sockaddr_in _sockaddr;
bool _is_valid;
};

/** The user specified origin to which requests are redirected. */
std::unique_ptr<TargetAddress> g_target_address{nullptr};

/** Parse the plugin's command line arguments. */
bool
parse_arguments(int argc, char const *argv[])
{
if (argc != 3) {
TSError("Must provide the address and port for TSHttpTxnServerAddrSet.");
return false;
}
char const *address = argv[1];
int port = atoi(argv[2]);
if (port <= 0 || port >= 65536) {
TSError("Invalid port number %s", argv[2]);
return false;
}
g_target_address = std::make_unique<TargetAddress>(address, port);
if (!g_target_address->is_valid()) {
TSError("Invalid address %s:%d", address, port);
return false;
}

return true;
}

/** The handler which sets the user-specified origin. */
int
set_origin(TSCont cont, TSEvent event, void *edata)
{
if (event != TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE) {
TSError("Unexpected event: %d", event);
return TS_ERROR;
}

TSHttpTxn txnp = (TSHttpTxn)edata;
if (TSHttpTxnServerAddrSet(txnp, g_target_address->get_sockaddr()) != TS_SUCCESS) {
TSError("Failed to set a transaction's origin to %s:%d", g_target_address->get_address().data(), g_target_address->get_port());
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_ERROR);
return TS_ERROR;
}
TSDebug(PNAME.data(), "Successfully set a transaction's origin to %s:%d", g_target_address->get_address().data(),
g_target_address->get_port());
TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE);
return TS_SUCCESS;
}

} // anonymous namespace

void
TSPluginInit(int argc, char const *argv[])
{
TSDebug(PNAME.data(), "Initializing plugin.");

TSPluginRegistrationInfo info;
info.plugin_name = PNAME.data();
info.vendor_name = "Apache Software Foundation";
info.support_email = "dev@trafficserver.apache.org";
TSReleaseAssert(TSPluginRegister(&info) == TS_SUCCESS);

if (!parse_arguments(argc, argv)) {
TSError("Failed to parse arguments.");
return;
}

TSDebug(PNAME.data(), "Redirecting all requests to %s:%s", argv[1], argv[2]);

TSCont contp = TSContCreate(set_origin, nullptr);
TSHttpHookAdd(TS_HTTP_CACHE_LOOKUP_COMPLETE_HOOK, contp);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
meta:
version: '1.0'

sessions:

- transactions:

- client-request:
method: GET
url: /pictures/flower.jpeg
version: '1.1'
headers:
fields:
- [ Host, www.example.com ]
- [ uuid, first-request ]

server-response:
status: 200
reason: OK
headers:
fields:
- [ Date, "Sat, 16 Mar 2019 03:11:36 GMT" ]
- [ Content-Type, image/jpeg ]
- [ Transfer-Encoding, chunked ]
- [ Connection, keep-alive ]
- [ X-Response, redirect-succeeded ]
content:
size: 45

proxy-response:
status: 200
headers:
fields:
- [ X-Response, { value: redirect-succeeded, as: equal } ]
Loading