diff --git a/doc/developer-guide/api/functions/TSHttpTxnServerAddrGet.en.rst b/doc/developer-guide/api/functions/TSHttpTxnServerAddrGet.en.rst index 102c30ffd1e..800634e8e58 100644 --- a/doc/developer-guide/api/functions/TSHttpTxnServerAddrGet.en.rst +++ b/doc/developer-guide/api/functions/TSHttpTxnServerAddrGet.en.rst @@ -38,3 +38,9 @@ Get the origin server address for transaction :arg:`txnp`. The pointer is valid only for the current callback. Clients that need to keep the value across callbacks must maintain their own storage. + +See Also +======== + +:manpage:`TSAPI(3ts)`, +:manpage:`TSHttpTxnServerAddrSet(3ts)` diff --git a/doc/developer-guide/api/functions/TSHttpTxnServerAddrSet.en.rst b/doc/developer-guide/api/functions/TSHttpTxnServerAddrSet.en.rst index 76790a95a85..0ddd306c03a 100644 --- a/doc/developer-guide/api/functions/TSHttpTxnServerAddrSet.en.rst +++ b/doc/developer-guide/api/functions/TSHttpTxnServerAddrSet.en.rst @@ -35,8 +35,32 @@ Set the origin server address for transaction :arg:`txnp`. This includes the por The address family is also set by the contents of :arg:`addr`. The address data is copied out of :arg:`addr` so there is no dependency on the lifetime of that object. -This hook must be called no later than TS_HTTP_OS_DNS_HOOK. If this is called then DNS resolution -will not be done as the address of the server is already know. +This hook must be called no later than TS_HTTP_OS_DNS_HOOK. If this +is called prior to TS_HTTP_OS_DNS_HOOK, DNS resolution will not be +done as the address of the server is already known. -An error value is returned if :arg:`addr` does not contain a valid IPv4 or IPv6 address with a valid -(non-zero) port. \ No newline at end of file +Return Value +============ + +:data:`TS_ERROR` is returned if :arg:`addr` does not contain a valid +IPv4 or IPv6 address with a valid (non-zero) port. + +Notes +===== + +If |TS| is configured to retry connections to origin servers and +:func:`TSHttpTxnServerAddrGet` has been called, |TS| will return +to TS_HTTP_OS_DNS_HOOK so to let the plugin set a different server +address. Plugins should be prepared for TS_HTTP_OS_DNS_HOOK and any +subsequent hooks to be called multiple times. + +Once a plugin calls :func:`TSHttpTxnServerAddrGet` any prior DNS +resolution results are lost. The plugin should use +:func:`TSHttpTxnServerAddrGet` to preserve any DNS Results that +might need. + +See Also +======== + +:manpage:`TSAPI(3ts)`, +:manpage:`TSHttpTxnServerAddrGet(3ts)` diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc index 5ef04306d91..dd0b6cb47c3 100644 --- a/proxy/http/HttpTransact.cc +++ b/proxy/http/HttpTransact.cc @@ -3771,6 +3771,16 @@ HttpTransact::handle_response_from_server(State *s) retry_server_connection_not_open(s, s->current.state, max_connect_retries); DebugTxn("http_trans", "[handle_response_from_server] Error. Retrying..."); s->next_action = how_to_open_connection(s); + + if (s->api_server_addr_set) { + // If the plugin set a server address, back up to the OS_DNS hook + // to let it try another one. Force OS_ADDR_USE_CLIENT so that + // in OSDNSLoopkup, we back up to how_to_open_connections which + // will tell HttpSM to connect the origin server. + + s->dns_info.os_addr_style = DNSLookupInfo::OS_ADDR_USE_CLIENT; + TRANSACT_RETURN(SM_ACTION_API_OS_DNS, OSDNSLookup); + } return; } } else {