You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2012/12/10 18:03:21 UTC
[2/2] TS-1422 TS-1307 : Update HostDB for better IPv6 handling.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/lib/records/I_RecHttp.h
----------------------------------------------------------------------
diff --git a/lib/records/I_RecHttp.h b/lib/records/I_RecHttp.h
index 41da219..248c1dd 100644
--- a/lib/records/I_RecHttp.h
+++ b/lib/records/I_RecHttp.h
@@ -25,6 +25,7 @@
#define _I_REC_HTTP_H
#include <ts/ink_inet.h>
+#include <ts/ink_resolver.h>
#include <ts/Vec.h>
/// Load default inbound IP addresses from the configuration file.
@@ -95,6 +96,7 @@ public:
TRANSPORT_BLIND_TUNNEL, ///< Blind tunnel (no processing).
TRANSPORT_SSL ///< SSL connection.
};
+
int m_fd; ///< Pre-opened file descriptor if present.
TransportType m_type; ///< Type of connection.
int m_port; ///< Port on which to listen.
@@ -109,6 +111,12 @@ public:
IpAddr m_outbound_ip4;
/// Local address for outbound connections (to origin server).
IpAddr m_outbound_ip6;
+ /// Ordered preference for DNS resolution family ( @c FamilyPrefence )
+ /// A value of @c PREFER_NONE indicates that entry and subsequent ones
+ /// are invalid.
+ HostResPreferenceOrder m_host_res_preference;
+ /// Static preference list that is the default value.
+ static HostResPreferenceOrder const DEFAULT_HOST_RES_PREFERENCE;
/// Default constructor.
HttpProxyPort();
@@ -254,8 +262,13 @@ public:
static char const* const OPT_SSL; ///< SSL (experimental)
static char const* const OPT_BLIND_TUNNEL; ///< Blind tunnel.
static char const* const OPT_COMPRESSED; ///< Compressed.
+ static char const* const OPT_HOST_RES; ///< Set DNS family preference.
static Vec<self>& m_global; ///< Global ("default") data.
+
+protected:
+ /// Process @a value for DNS resolution family preferences.
+ void processFamilyPreferences(char const* value);
};
inline bool HttpProxyPort::isSSL() const { return TRANSPORT_SSL == m_type; }
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/lib/records/RecHttp.cc
----------------------------------------------------------------------
diff --git a/lib/records/RecHttp.cc b/lib/records/RecHttp.cc
index 31a6c12..45f1055 100644
--- a/lib/records/RecHttp.cc
+++ b/lib/records/RecHttp.cc
@@ -77,12 +77,14 @@ char const* const HttpProxyPort::OPT_TRANSPARENT_FULL = "tr-full";
char const* const HttpProxyPort::OPT_SSL = "ssl";
char const* const HttpProxyPort::OPT_BLIND_TUNNEL = "blind";
char const* const HttpProxyPort::OPT_COMPRESSED = "compressed";
+char const* const HttpProxyPort::OPT_HOST_RES = "ip-resolve";
// File local constants.
namespace {
-size_t const OPT_FD_PREFIX_LEN = strlen(HttpProxyPort::OPT_FD_PREFIX);
-size_t const OPT_OUTBOUND_IP_PREFIX_LEN = strlen(HttpProxyPort::OPT_OUTBOUND_IP_PREFIX);
-size_t const OPT_INBOUND_IP_PREFIX_LEN = strlen(HttpProxyPort::OPT_INBOUND_IP_PREFIX);
+ size_t const OPT_FD_PREFIX_LEN = strlen(HttpProxyPort::OPT_FD_PREFIX);
+ size_t const OPT_OUTBOUND_IP_PREFIX_LEN = strlen(HttpProxyPort::OPT_OUTBOUND_IP_PREFIX);
+ size_t const OPT_INBOUND_IP_PREFIX_LEN = strlen(HttpProxyPort::OPT_INBOUND_IP_PREFIX);
+ size_t const OPT_HOST_RES_PREFIX_LEN = strlen(HttpProxyPort::OPT_HOST_RES);
}
namespace {
@@ -103,6 +105,7 @@ HttpProxyPort::HttpProxyPort()
, m_inbound_transparent_p(false)
, m_outbound_transparent_p(false)
{
+ memcpy(m_host_res_preference, host_res_default_preference_order, sizeof(m_host_res_preference));
}
bool HttpProxyPort::hasSSL(Group const& ports) {
@@ -232,6 +235,7 @@ bool
HttpProxyPort::processOptions(char const* opts) {
bool zret = false; // no port found yet.
bool af_set_p = false; // AF explicitly specified.
+ bool host_res_set_p = false; // Host resolution order set explicitly.
bool bracket_p = false; // inside brackets during parse.
Vec<char*> values; // Pointers to single option values.
@@ -342,13 +346,19 @@ HttpProxyPort::processOptions(char const* opts) {
Warning("Transparency requested [%s] in port descriptor '%s' but TPROXY was not configured.", item, opts);
# endif
} else if (0 == strcasecmp(OPT_TRANSPARENT_FULL, item)||
- 0 == strcasecmp("=", item)) {
+ 0 == strcasecmp("=", item)) {
# if TS_USE_TPROXY
m_inbound_transparent_p = true;
m_outbound_transparent_p = true;
# else
Warning("Transparency requested [%s] in port descriptor '%s' but TPROXY was not configured.", item, opts);
# endif
+ } else if (0 == strncasecmp(OPT_HOST_RES, item, OPT_HOST_RES_PREFIX_LEN)) {
+ item += OPT_HOST_RES_PREFIX_LEN; // skip prefix
+ if ('-' == *item || '=' == *item) // permit optional '-' or '='
+ ++item;
+ this->processFamilyPreferences(item);
+ host_res_set_p = true;
} else {
Warning("Invalid option '%s' in port configuration '%s'", item, opts);
}
@@ -366,9 +376,30 @@ HttpProxyPort::processOptions(char const* opts) {
m_family = m_inbound_ip.family(); // set according to address.
}
+ // If the port is outbound transparent only CLIENT host resolution is possible.
+ if (m_outbound_transparent_p) {
+ if (host_res_set_p &&
+ (m_host_res_preference[0] != HOST_RES_PREFER_CLIENT ||
+ m_host_res_preference[1] != HOST_RES_PREFER_NONE
+ )) {
+ Warning("Outbound transparent ports require the IP address resolution ordering '%s,%s'. "
+ "This is set automatically and does not need to be set explicitly."
+ , HOST_RES_PREFERENCE_STRING[HOST_RES_PREFER_CLIENT]
+ , HOST_RES_PREFERENCE_STRING[HOST_RES_PREFER_NONE]
+ );
+ }
+ m_host_res_preference[0] = HOST_RES_PREFER_CLIENT;
+ m_host_res_preference[1] = HOST_RES_PREFER_NONE;
+ }
+
return zret;
}
+void
+HttpProxyPort::processFamilyPreferences(char const* value) {
+ parse_host_res_preferences(value, m_host_res_preference);
+}
+
int
HttpProxyPort::print(char* out, size_t n) {
size_t zret = 0; // # of chars printed so far.
@@ -437,5 +468,30 @@ HttpProxyPort::print(char* out, size_t n) {
else if (m_outbound_transparent_p)
zret += snprintf(out+zret, n-zret, ":%s", OPT_TRANSPARENT_OUTBOUND);
+ /* Don't print the IP resolution preferences if the port is outbound
+ * transparent (which means the preference order is forced) or if
+ * the order is the same as the default.
+ */
+ if (!m_outbound_transparent_p &&
+ 0 != memcmp(m_host_res_preference, host_res_default_preference_order, sizeof(m_host_res_preference))) {
+ zret += snprintf(out+zret, n-zret, ":%s=", OPT_HOST_RES);
+ zret += ts_host_res_order_to_string(m_host_res_preference, out+zret, n-zret);
+ }
+
return min(zret,n);
}
+
+void
+ts_host_res_global_init()
+{
+ // Global configuration values.
+ memcpy(host_res_default_preference_order,
+ HOST_RES_DEFAULT_PREFERENCE_ORDER,
+ sizeof(host_res_default_preference_order));
+
+ char* ip_resolve = REC_ConfigReadString("proxy.config.hostdb.ip_resolve");
+ if (ip_resolve) {
+ parse_host_res_preferences(ip_resolve, host_res_default_preference_order);
+ }
+ ats_free(ip_resolve);
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/lib/ts/INK_MD5.h
----------------------------------------------------------------------
diff --git a/lib/ts/INK_MD5.h b/lib/ts/INK_MD5.h
index 000d8a6..92b34ef 100644
--- a/lib/ts/INK_MD5.h
+++ b/lib/ts/INK_MD5.h
@@ -131,16 +131,16 @@ struct INK_MD5
return buf;
}
- uint64_t fold()
+ uint64_t fold() const
{
return (b[0] ^ b[1]);
}
- uint64_t operator[] (int i)
+ uint64_t operator[] (int i) const
{
return b[i];
}
- bool operator==(INK_MD5 & md5)
+ bool operator==(INK_MD5 const& md5)
{
return b[0] == md5.b[0] && b[1] == md5.b[1];
}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/lib/ts/ink_inet.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_inet.h b/lib/ts/ink_inet.h
index 7965496..52c64f1 100644
--- a/lib/ts/ink_inet.h
+++ b/lib/ts/ink_inet.h
@@ -1016,17 +1016,10 @@ struct IpAddr {
explicit IpAddr(IpEndpoint const* addr) { this->assign(&addr->sa); }
/// Assign sockaddr storage.
- self& assign(sockaddr const* addr) {
- _family = addr->sa_family;
- if (ats_is_ip4(addr)) {
- _addr._ip4 = ats_ip4_addr_cast(addr);
- } else if (ats_is_ip6(addr)) {
- _addr._ip6 = ats_ip6_addr_cast(addr);
- } else {
- _family = AF_UNSPEC;
- }
- return *this;
- }
+ self& assign(
+ sockaddr const* addr ///< May be @c NULL
+ );
+
/// Assign from end point.
self& operator = (IpEndpoint const& ip) {
return this->assign(&ip.sa);
@@ -1035,6 +1028,10 @@ struct IpAddr {
self& operator = (
in_addr_t ip ///< Network order IPv4 address.
);
+ /// Assign from IPv6 raw address.
+ self& operator = (
+ in6_addr const& ip
+ );
/** Load from string.
The address is copied to this object if the conversion is successful,
@@ -1107,6 +1104,13 @@ IpAddr::operator = (in_addr_t ip) {
return *this;
}
+inline IpAddr&
+IpAddr::operator = (in6_addr const& ip) {
+ _family = AF_INET6;
+ _addr._ip6 = ip;
+ return *this;
+}
+
inline uint16_t IpAddr::family() const { return _family; }
inline bool
@@ -1116,6 +1120,23 @@ IpAddr::isCompatibleWith(self const& that) {
inline bool IpAddr::isIp4() const { return AF_INET == _family; }
inline bool IpAddr::isIp6() const { return AF_INET6 == _family; }
+ /// Assign sockaddr storage.
+inline IpAddr&
+IpAddr::assign(sockaddr const* addr) {
+ if (addr) {
+ _family = addr->sa_family;
+ if (ats_is_ip4(addr)) {
+ _addr._ip4 = ats_ip4_addr_cast(addr);
+ } else if (ats_is_ip6(addr)) {
+ _addr._ip6 = ats_ip6_addr_cast(addr);
+ } else {
+ _family = AF_UNSPEC;
+ }
+ } else {
+ _family = AF_UNSPEC;
+ }
+ return *this;
+}
// Associated operators.
bool operator == (IpAddr const& lhs, sockaddr const* rhs);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/lib/ts/ink_res_init.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_res_init.cc b/lib/ts/ink_res_init.cc
index f94b240..d52057f 100644
--- a/lib/ts/ink_res_init.cc
+++ b/lib/ts/ink_res_init.cc
@@ -87,11 +87,28 @@
#include "ink_string.h"
#include "ink_resolver.h"
#include "ink_inet.h"
+#include "Tokenizer.h"
#if !defined(isascii) /* XXX - could be a function */
# define isascii(c) (!(c & 0200))
#endif
+HostResPreferenceOrder const HOST_RES_DEFAULT_PREFERENCE_ORDER = {
+ HOST_RES_PREFER_IPV4,
+ HOST_RES_PREFER_IPV6,
+ HOST_RES_PREFER_NONE
+};
+
+HostResPreferenceOrder host_res_default_preference_order;
+
+char const* const HOST_RES_PREFERENCE_STRING[N_HOST_RES_PREFERENCE] = {
+ "only", "client", "ipv4", "ipv6"
+};
+
+char const* const HOST_RES_STYLE_STRING[] = {
+ "invalid", "IPv4", "IPv4 only", "IPv6", "IPv6 only"
+};
+
/*%
* This routine is for closing the socket if a virtual circuit is used and
* the program wants to close it. This provides support for endhostent()
@@ -560,3 +577,70 @@ ink_res_init(
statp->options |= INK_RES_INIT;
return (statp->res_h_errno);
}
+
+void
+parse_host_res_preferences(char const* value, HostResPreferenceOrder order) {
+ Tokenizer tokens(";/|");
+ // preference from the config string.
+ int np = 0; // index in to @a m_host_res_preference
+ bool found[N_HOST_RES_PREFERENCE]; // redundancy check array
+ int n; // # of tokens
+ int i; // index
+
+ n = tokens.Initialize(value);
+
+ for ( i = 0 ; i < N_HOST_RES_PREFERENCE ; ++i )
+ found[i] = false;
+
+ for ( i = 0 ; i < n && np < N_HOST_RES_PREFERENCE_ORDER ; ++i ) {
+ char const* elt = tokens[i];
+ // special case none/only because that terminates the sequence.
+ if (0 == strcasecmp(elt, HOST_RES_PREFERENCE_STRING[HOST_RES_PREFER_NONE])) {
+ found[HOST_RES_PREFER_NONE] = true;
+ order[np] = HOST_RES_PREFER_NONE;
+ break;
+ } else {
+ // scan the other types
+ HostResPreference ep = HOST_RES_PREFER_NONE;
+ for ( int ip = HOST_RES_PREFER_NONE + 1 ; ip < N_HOST_RES_PREFERENCE ; ++ip ) {
+ if (0 == strcasecmp(elt, HOST_RES_PREFERENCE_STRING[ip])) {
+ ep = static_cast<HostResPreference>(ip);
+ break;
+ }
+ }
+ if (HOST_RES_PREFER_NONE != ep && !found[ep]) { // ignore duplicates
+ found[ep] = true;
+ order[np++] = ep;
+ }
+ }
+ }
+
+ if (!found[HOST_RES_PREFER_NONE]) {
+ // If 'only' wasn't explicit, fill in the rest by default.
+ if (!found[HOST_RES_PREFER_IPV4])
+ order[np++] = HOST_RES_PREFER_IPV4;
+ if (!found[HOST_RES_PREFER_IPV6])
+ order[np++] = HOST_RES_PREFER_IPV6;
+ if (np < N_HOST_RES_PREFERENCE)
+ order[np++] = HOST_RES_PREFER_NONE;
+ }
+}
+
+int
+ts_host_res_order_to_string(HostResPreferenceOrder const& order, char* out, int size)
+{
+ int zret = 0;
+ bool first = true;
+ for ( int i = 0 ; i < N_HOST_RES_PREFERENCE_ORDER ; ++i ) {
+ /* Note we use a semi-colon here because this must be compatible
+ * with the -httpport command line option which uses comma to
+ * separate port descriptors so we cannot use that to separate
+ * resolution key words.
+ */
+ zret += snprintf(out+zret, size-zret, "%s%s", !first ? ";" : "", HOST_RES_PREFERENCE_STRING[order[i]]);
+ if (HOST_RES_PREFER_NONE == order[i])
+ break;
+ first = false;
+ }
+ return zret;
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/lib/ts/ink_res_mkquery.cc
----------------------------------------------------------------------
diff --git a/lib/ts/ink_res_mkquery.cc b/lib/ts/ink_res_mkquery.cc
index 366c1d5..e0d5d7a 100644
--- a/lib/ts/ink_res_mkquery.cc
+++ b/lib/ts/ink_res_mkquery.cc
@@ -501,3 +501,38 @@ ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
*dn++ = '\0';
return (dn - dst);
}
+
+HostResStyle
+ats_host_res_from(int family, HostResPreferenceOrder order)
+{
+ bool v4 = false, v6 = false;
+ HostResPreference client = AF_INET6 == family ? HOST_RES_PREFER_IPV6 : HOST_RES_PREFER_IPV4;
+
+ for ( int i = 0 ; i < N_HOST_RES_PREFERENCE_ORDER ; ++i ) {
+ HostResPreference p = order[i];
+ if (HOST_RES_PREFER_CLIENT == p) p = client; // CLIENT -> actual value
+ if (HOST_RES_PREFER_IPV4 == p) {
+ if (v6) return HOST_RES_IPV6;
+ else v4 = true;
+ } else if (HOST_RES_PREFER_IPV6 == p) {
+ if (v4) return HOST_RES_IPV4;
+ else v6 = true;
+ } else {
+ break;
+ }
+ }
+ if (v4) return HOST_RES_IPV4_ONLY;
+ else if (v6) return HOST_RES_IPV6_ONLY;
+ return HOST_RES_NONE;
+}
+
+HostResStyle
+ats_host_res_match(sockaddr const* addr)
+{
+ HostResStyle zret = HOST_RES_NONE;
+ if (ats_is_ip6(addr))
+ zret = HOST_RES_IPV6_ONLY;
+ else if (ats_is_ip4(addr))
+ zret = HOST_RES_IPV4_ONLY;
+ return zret;
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/lib/ts/ink_resolver.h
----------------------------------------------------------------------
diff --git a/lib/ts/ink_resolver.h b/lib/ts/ink_resolver.h
index 3ebcd9f..dd7b037 100644
--- a/lib/ts/ink_resolver.h
+++ b/lib/ts/ink_resolver.h
@@ -102,6 +102,7 @@
/*%
* * Resolver options (keep these in synch with res_debug.c, please)
+ [amc] Most of these are never used. AFAICT it's RECURSE and DEBUG only.
* */
#define INK_RES_INIT 0x00000001 /*%< address initialized */
#define INK_RES_DEBUG 0x00000002 /*%< print debug messages */
@@ -147,6 +148,58 @@
#define INK_NS_TYPE_ELT 0x40 /*%< EDNS0 extended label type */
#define INK_DNS_LABELTYPE_BITSTRING 0x41
+/// IP family preference for DNS resolution.
+/// Used for configuration.
+enum HostResPreference {
+ HOST_RES_PREFER_NONE = 0, ///< Invalid / init value.
+ HOST_RES_PREFER_CLIENT, ///< Prefer family of client connection.
+ HOST_RES_PREFER_IPV4, ///< Prefer IPv4.
+ HOST_RES_PREFER_IPV6 ///< Prefer IPv6
+};
+/// # of preference values.
+static int const N_HOST_RES_PREFERENCE = HOST_RES_PREFER_IPV6+1;
+/// # of entries in a preference ordering.
+static int const N_HOST_RES_PREFERENCE_ORDER = 3;
+/// Storage for preference ordering.
+typedef HostResPreference HostResPreferenceOrder[N_HOST_RES_PREFERENCE_ORDER];
+/// Global, hard wired default value for preference ordering.
+extern HostResPreferenceOrder const HOST_RES_DEFAULT_PREFERENCE_ORDER;
+/// Global (configurable) default.
+extern HostResPreferenceOrder host_res_default_preference_order;
+/// String versions of @c FamilyPreference
+extern char const* const HOST_RES_PREFERENCE_STRING[N_HOST_RES_PREFERENCE];
+
+/// IP family to use in a DNS query for a host address.
+/// Used during DNS query operations.
+enum HostResStyle{
+ HOST_RES_NONE = 0, ///< No preference / unspecified / init value.
+ HOST_RES_IPV4, ///< Use IPv4 if possible.
+ HOST_RES_IPV4_ONLY, ///< Resolve on IPv4 addresses.
+ HOST_RES_IPV6, ///< Use IPv6 if possible.
+ HOST_RES_IPV6_ONLY ///< Resolve only IPv6 addresses.
+};
+
+/// Strings for host resolution styles
+extern char const* const HOST_RES_STYLE_STRING[];
+
+/// Caclulate the effective resolution preferences.
+extern HostResStyle
+ats_host_res_from(
+ int family, ///< Connection family
+ HostResPreferenceOrder ///< Preference ordering.
+ );
+/// Calculate the host resolution style to force a family match to @a addr.
+extern HostResStyle
+ats_host_res_match(sockaddr const* addr);
+
+/** Parse a host resolution configuration string.
+ */
+extern void
+parse_host_res_preferences(
+ char const* value, ///< [in] Configuration string.
+ HostResPreferenceOrder order /// [out] Order to update.
+ );
+
#ifndef NS_GET16
#define NS_GET16(s, cp) do { \
register const u_char *t_cp = (const u_char *)(cp); \
@@ -237,5 +290,19 @@ int ink_res_mkquery(ink_res_state, int, const char *, int, int,
int ink_ns_name_ntop(const u_char *src, char *dst, size_t dstsiz);
+/** Initialize global values for HttpProxyPort / Host Resolution.
+ */
+void ts_host_res_global_init();
+
+/** Generate a string representation of a host resolution preference ordering.
+ @return The length of the string.
+ */
+int
+ts_host_res_order_to_string(
+ HostResPreferenceOrder const& order, ///< order to print
+ char* out, ///< Target buffer for string.
+ int size ///< Size of buffer.
+ );
+
#endif /* _ink_resolver_h_ */
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/mgmt/Main.cc
----------------------------------------------------------------------
diff --git a/mgmt/Main.cc b/mgmt/Main.cc
index 87450dc..1f9c2ab 100644
--- a/mgmt/Main.cc
+++ b/mgmt/Main.cc
@@ -608,6 +608,7 @@ main(int argc, char **argv)
#if TS_HAS_WCCP
Init_Errata_Logging();
#endif
+ ts_host_res_global_init();
lmgmt = new LocalManager(mgmt_path, proxy_on);
RecLocalInitMessage();
lmgmt->initAlarm();
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index ba983b0..c940852 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -1035,6 +1035,8 @@ RecordElement RecordsConfig[] = {
,
{RECT_CONFIG, "proxy.config.dns.dedicated_thread", RECD_INT, "0", RECU_RESTART_TS, RR_NULL, RECC_NULL, "[0-1]", RECA_NULL}
,
+ {RECT_CONFIG, "proxy.config.hostdb.ip_resolve", RECD_STRING, NULL, RECU_RESTART_TS, RR_NULL, RECC_STR, NULL, RECA_NULL}
+ ,
//##############################################################################
//#
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/http/HttpAccept.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpAccept.cc b/proxy/http/HttpAccept.cc
index 6a7d599..9e7dda8 100644
--- a/proxy/http/HttpAccept.cc
+++ b/proxy/http/HttpAccept.cc
@@ -68,6 +68,7 @@ HttpAccept::mainEvent(int event, void *data)
new_session->outbound_ip4 = outbound_ip4;
new_session->outbound_ip6 = outbound_ip6;
new_session->outbound_port = outbound_port;
+ new_session->host_res_style = ats_host_res_from(client_ip->sa_family, host_res_preference);
new_session->acl_method_mask = acl_method_mask;
new_session->new_connection(netvc, backdoor);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/http/HttpAccept.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpAccept.h b/proxy/http/HttpAccept.h
index 51592ad..d8e4160 100644
--- a/proxy/http/HttpAccept.h
+++ b/proxy/http/HttpAccept.h
@@ -61,8 +61,9 @@ namespace detail {
IpAddr outbound_ip4;
/// Local address to bind for outbound connections.
IpAddr outbound_ip6;
- /// Set the outbound IP address.
+ /// Set the outbound IP address to @a ip.
self& setOutboundIp(IpAddr& ip);
+ /// Set the outbound IP address to @a ip.
self& setOutboundIp(IpEndpoint* ip);
/// Local port for outbound connection.
uint16_t outbound_port;
@@ -76,6 +77,10 @@ namespace detail {
bool backdoor;
/// Set backdoor accept.
self& setBackdoor(bool);
+ /// Host address resolution preference order.
+ HostResPreferenceOrder host_res_preference;
+ /// Set the host query preference.
+ self& setHostResPreference(HostResPreferenceOrder const);
};
inline HttpAcceptOptions::HttpAcceptOptions()
@@ -84,6 +89,7 @@ namespace detail {
, f_outbound_transparent(false)
, backdoor(false)
{
+ memcpy(host_res_preference, host_res_default_preference_order, sizeof(host_res_preference));
}
inline HttpAcceptOptions&
@@ -123,6 +129,12 @@ namespace detail {
backdoor = flag;
return *this;
}
+
+ inline HttpAcceptOptions&
+ HttpAcceptOptions::setHostResPreference(HostResPreferenceOrder const order) {
+ memcpy(host_res_preference, order, sizeof(host_res_preference));
+ return *this;
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/http/HttpClientSession.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpClientSession.cc b/proxy/http/HttpClientSession.cc
index b214482..72720d4 100644
--- a/proxy/http/HttpClientSession.cc
+++ b/proxy/http/HttpClientSession.cc
@@ -64,7 +64,10 @@ HttpClientSession::HttpClientSession()
read_buffer(NULL), current_reader(NULL), read_state(HCS_INIT),
ka_vio(NULL), slave_ka_vio(NULL),
cur_hook_id(TS_HTTP_LAST_HOOK), cur_hook(NULL),
- cur_hooks(0), proxy_allocated(false), backdoor_connect(false), hooks_set(0),
+ cur_hooks(0), proxy_allocated(false), backdoor_connect(false),
+ hooks_set(0),
+ outbound_port(0), f_outbound_transparent(false),
+ host_res_style(HOST_RES_IPV4), acl_method_mask(0),
m_active(false), debug_on(false)
{
memset(user_args, 0, sizeof(user_args));
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/http/HttpClientSession.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpClientSession.h b/proxy/http/HttpClientSession.h
index 6978a17..ffaa367 100644
--- a/proxy/http/HttpClientSession.h
+++ b/proxy/http/HttpClientSession.h
@@ -151,6 +151,8 @@ public:
uint16_t outbound_port;
/// Set outbound connection to transparent.
bool f_outbound_transparent;
+ /// DNS resolution preferences.
+ HostResStyle host_res_style;
/// acl method mask - cache IpAllow::match() call
uint32_t acl_method_mask;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/http/HttpProxyServerMain.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpProxyServerMain.cc b/proxy/http/HttpProxyServerMain.cc
index b48e0f2..b69a49d 100644
--- a/proxy/http/HttpProxyServerMain.cc
+++ b/proxy/http/HttpProxyServerMain.cc
@@ -166,6 +166,7 @@ start_HttpProxyPort(const HttpProxyPort& port, unsigned nthreads)
http.f_outbound_transparent = port.m_outbound_transparent_p;
http.transport_type = port.m_type;
+ http.setHostResPreference(port.m_host_res_preference);
if (port.m_inbound_ip.isValid()) {
net.local_ip = port.m_inbound_ip;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index c7deff1..dabaa9b 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -1971,22 +1971,16 @@ lookup:
HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_hostdb_lookup);
+ HostDBProcessor::Options opt;
if (t_state.api_txn_dns_timeout_value != -1) {
+ opt.timeout = t_state.api_txn_dns_timeout_value;
DebugSM("http_timeout", "beginning DNS lookup. allowing %d mseconds for DNS", t_state.api_txn_dns_timeout_value);
}
+ opt.flags = (t_state.cache_info.directives.does_client_permit_dns_storing) ? HostDBProcessor::HOSTDB_DO_NOT_FORCE_DNS : HostDBProcessor::HOSTDB_FORCE_DNS_RELOAD;
+ opt.port = server_port;
+ opt.host_res_style = ua_session->host_res_style;
- Action *dns_lookup_action_handle = hostDBProcessor.getbyname_imm(this,
- (process_hostdb_info_pfn) & HttpSM::
- process_hostdb_info,
- &new_host[0], 0,
- server_port,
- ((t_state.cache_info.directives.
- does_client_permit_dns_storing) ? HostDBProcessor::
- HOSTDB_DO_NOT_FORCE_DNS : HostDBProcessor::
- HOSTDB_FORCE_DNS_RELOAD),
- (t_state.api_txn_dns_timeout_value != -1) ? t_state.
- api_txn_dns_timeout_value : 0);
-
+ Action *dns_lookup_action_handle = hostDBProcessor.getbyname_imm(this, (process_hostdb_info_pfn) & HttpSM::process_hostdb_info, &new_host[0], 0, opt);
if (dns_lookup_action_handle != ACTION_RESULT_DONE) {
ink_assert(!pending_action);
@@ -2001,7 +1995,7 @@ lookup:
void
HttpSM::process_hostdb_info(HostDBInfo * r)
{
- if (r) {
+ if (r && !r->failed()) {
HostDBInfo *rr = NULL;
t_state.dns_info.lookup_success = true;
@@ -3758,9 +3752,11 @@ HttpSM::do_hostdb_lookup()
DebugSM("dns_srv", "Beginning lookup of SRV records for origin %s", d);
HTTP_SM_SET_DEFAULT_HANDLER(&HttpSM::state_srv_lookup);
+ HostDBProcessor::Options opt;
+ if (t_state.api_txn_dns_timeout_value != -1)
+ opt.timeout = t_state.api_txn_dns_timeout_value;
Action *srv_lookup_action_handle =
- hostDBProcessor.getSRVbyname_imm(this, (process_srv_info_pfn) & HttpSM::process_srv_info, d,
- (t_state.api_txn_dns_timeout_value != -1) ? t_state.api_txn_dns_timeout_value : 0);
+ hostDBProcessor.getSRVbyname_imm(this, (process_srv_info_pfn) & HttpSM::process_srv_info, d, 0, opt);
if (srv_lookup_action_handle != ACTION_RESULT_DONE) {
ink_assert(!pending_action);
@@ -3780,18 +3776,16 @@ HttpSM::do_hostdb_lookup()
t_state.api_txn_dns_timeout_value);
}
- Action *dns_lookup_action_handle = hostDBProcessor.getbyname_imm(this,
- (process_hostdb_info_pfn) & HttpSM::
- process_hostdb_info,
- t_state.dns_info.lookup_name, 0,
- server_port,
- ((t_state.cache_info.directives.
- does_client_permit_dns_storing) ?
- HostDBProcessor::
- HOSTDB_DO_NOT_FORCE_DNS : HostDBProcessor::
- HOSTDB_FORCE_DNS_RELOAD),
- (t_state.api_txn_dns_timeout_value != -1) ? t_state.
- api_txn_dns_timeout_value : 0);
+ HostDBProcessor::Options opt;
+ opt.port = server_port;
+ opt.flags = (t_state.cache_info.directives.does_client_permit_dns_storing)
+ ? HostDBProcessor::HOSTDB_DO_NOT_FORCE_DNS
+ : HostDBProcessor::HOSTDB_FORCE_DNS_RELOAD
+ ;
+ opt.timeout = (t_state.api_txn_dns_timeout_value != -1) ? t_state.api_txn_dns_timeout_value : 0;
+ opt.host_res_style = ua_session->host_res_style;
+
+ Action *dns_lookup_action_handle = hostDBProcessor.getbyname_imm(this, (process_hostdb_info_pfn) & HttpSM::process_hostdb_info, t_state.dns_info.lookup_name, 0, opt);
if (dns_lookup_action_handle != ACTION_RESULT_DONE) {
ink_assert(!pending_action);
@@ -4302,8 +4296,8 @@ HttpSM::do_cache_prepare_action(HttpCacheSM * c_sm, CacheHTTPInfo * object_read_
void
HttpSM::do_http_server_open(bool raw)
{
- DebugSM("http_track", "entered inside do_http_server_open");
int ip_family = t_state.current.server->addr.sa.sa_family;
+ DebugSM("http_track", "entered inside do_http_server_open ][%s]", ats_ip_family_name(ip_family));
ink_assert(server_entry == NULL);
@@ -4407,7 +4401,7 @@ HttpSM::do_http_server_open(bool raw)
if (existing_ss) {
// [amc] Is this OK? Should we compare ports? (not done by ats_ip_addr_cmp)
- if (ats_ip_addr_cmp(&existing_ss->server_ip.sa, &t_state.current.server->addr.sa) == 0) {
+ if (ats_ip_addr_eq(&existing_ss->server_ip.sa, &t_state.current.server->addr.sa)) {
ua_session->attach_server_session(NULL);
existing_ss->state = HSS_ACTIVE;
this->attach_server_session(existing_ss);
@@ -6691,15 +6685,19 @@ HttpSM::set_next_state()
&& !t_state.url_remap_success
&& t_state.parent_result.r != PARENT_SPECIFIED
&& t_state.client_info.is_transparent
+ && t_state.dns_info.os_addr_style == HttpTransact::DNSLookupInfo::OS_ADDR_TRY_DEFAULT
&& ats_is_ip(addr = t_state.state_machine->ua_session->get_netvc()->get_local_addr())
) {
- ip_text_buffer ipb;
- /* If the connection is client side transparent and the URL was not
- * remapped/directed to parent proxy, we can use the client destination
- * IP address instead of doing a DNS lookup. This is controlled by the
- * 'use_client_target_addr' configuration parameter.
+ /* If the connection is client side transparent and the URL
+ * was not remapped/directed to parent proxy, we can use the
+ * client destination IP address instead of doing a DNS
+ * lookup. This is controlled by the 'use_client_target_addr'
+ * configuration parameter.
*/
- DebugSM("dns", "[HttpTransact::HandleRequest] Skipping DNS lookup for client supplied target %s.\n", ats_ip_ntop(addr, ipb, sizeof(ipb)));
+ if (is_debug_tag_set("dns")) {
+ ip_text_buffer ipb;
+ DebugSM("dns", "[HttpTransact::HandleRequest] Skipping DNS lookup for client supplied target %s.\n", ats_ip_ntop(addr, ipb, sizeof(ipb)));
+ }
ats_ip_copy(t_state.host_db_info.ip(), addr);
/* Since we won't know the server HTTP version (no hostdb lookup), we assume it matches the
* client request version. Seems to be the most correct thing to do in the transparent use-case.
@@ -6712,6 +6710,9 @@ HttpSM::set_next_state()
t_state.host_db_info.app.http_data.http_version = HostDBApplicationInfo::HTTP_VERSION_11;
t_state.dns_info.lookup_success = true;
+ // cache this result so we don't have to unreliably duplicate the
+ // logic later if the connect fails.
+ t_state.dns_info.os_addr_style = HttpTransact::DNSLookupInfo::OS_ADDR_TRY_CLIENT;
call_transact_and_set_next_state(NULL);
break;
} else if (t_state.parent_result.r == PARENT_UNDEFINED && t_state.dns_info.lookup_success) {
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/http/HttpTransact.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
index ead53e6..a938545 100644
--- a/proxy/http/HttpTransact.cc
+++ b/proxy/http/HttpTransact.cc
@@ -1551,37 +1551,44 @@ HttpTransact::OSDNSLookup(State* s)
case EXPANSION_NOT_ALLOWED:
case EXPANSION_FAILED:
case DNS_ATTEMPTS_EXHAUSTED:
- if (host_name_expansion == EXPANSION_NOT_ALLOWED) {
- // config file doesn't allow automatic expansion of host names
- HTTP_RELEASE_ASSERT(!(s->http_config_param->enable_url_expandomatic));
- DebugTxn("http_seq", "[HttpTransact::OSDNSLookup] DNS Lookup unsuccessful");
- } else if (host_name_expansion == EXPANSION_FAILED) {
- // not able to expand the hostname. dns lookup failed
- DebugTxn("http_seq", "[HttpTransact::OSDNSLookup] DNS Lookup unsuccessful");
- } else if (host_name_expansion == DNS_ATTEMPTS_EXHAUSTED) {
- // retry attempts exhausted --- can't find dns entry for this host name
- HTTP_RELEASE_ASSERT(s->dns_info.attempts >= max_dns_lookups);
- DebugTxn("http_seq", "[HttpTransact::OSDNSLookup] DNS Lookup unsuccessful");
+ if (DNSLookupInfo::OS_ADDR_TRY_HOSTDB == s->dns_info.os_addr_style) {
+ // No HostDB data, just keep on with the CTA.
+ s->dns_info.lookup_success = true;
+ s->dns_info.os_addr_style = DNSLookupInfo::OS_ADDR_USE_CLIENT;
+ DebugTxn("http_seq", "[HttpTransact::OSDNSLookup] DNS lookup unsuccessful reverting to force client target address use");
+ } else {
+ if (host_name_expansion == EXPANSION_NOT_ALLOWED) {
+ // config file doesn't allow automatic expansion of host names
+ HTTP_RELEASE_ASSERT(!(s->http_config_param->enable_url_expandomatic));
+ DebugTxn("http_seq", "[HttpTransact::OSDNSLookup] DNS Lookup unsuccessful");
+ } else if (host_name_expansion == EXPANSION_FAILED) {
+ // not able to expand the hostname. dns lookup failed
+ DebugTxn("http_seq", "[HttpTransact::OSDNSLookup] DNS Lookup unsuccessful");
+ } else if (host_name_expansion == DNS_ATTEMPTS_EXHAUSTED) {
+ // retry attempts exhausted --- can't find dns entry for this host name
+ HTTP_RELEASE_ASSERT(s->dns_info.attempts >= max_dns_lookups);
+ DebugTxn("http_seq", "[HttpTransact::OSDNSLookup] DNS Lookup unsuccessful");
+ }
+ // output the DNS failure error message
+ SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
+ build_error_response(s, HTTP_STATUS_BAD_GATEWAY, "Cannot find server.", "connect#dns_failed",
+ // The following is all one long string
+ //("Unable to locate the server named \"<em>%s</em>\" --- "
+ //"the server does not have a DNS entry. Perhaps there is "
+ //"a misspelling in the server name, or the server no "
+ //"longer exists. Double-check the name and try again."),
+ ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">"
+ "<HTML><HEAD><TITLE>Unknown Host</TITLE></HEAD><BODY BGCOLOR=\"white\" FGCOLOR=\"black\">"
+ "<H1>Unknown Host</H1><HR>"
+ "<FONT FACE=\"Helvetica,Arial\"><B>"
+ "Description: Unable to locate the server named \"<EM>%s (%d)</EM>\" --- "
+ "the server does not have a DNS entry. Perhaps there is a misspelling "
+ "in the server name, or the server no longer exists. Double-check the "
+ "name and try again.</B></FONT><HR></BODY></HTML>")
+ , s->server_info.name, host_name_expansion);
+ // s->cache_info.action = CACHE_DO_NO_ACTION;
+ TRANSACT_RETURN(PROXY_SEND_ERROR_CACHE_NOOP, NULL);
}
- // output the DNS failure error message
- SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
- build_error_response(s, HTTP_STATUS_BAD_GATEWAY, "Cannot find server.", "connect#dns_failed",
- // The following is all one long string
- //("Unable to locate the server named \"<em>%s</em>\" --- "
- //"the server does not have a DNS entry. Perhaps there is "
- //"a misspelling in the server name, or the server no "
- //"longer exists. Double-check the name and try again."),
- ("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">"
- "<HTML><HEAD><TITLE>Unknown Host</TITLE></HEAD><BODY BGCOLOR=\"white\" FGCOLOR=\"black\">"
- "<H1>Unknown Host</H1><HR>"
- "<FONT FACE=\"Helvetica,Arial\"><B>"
- "Description: Unable to locate the server named \"<EM>%s (%d)</EM>\" --- "
- "the server does not have a DNS entry. Perhaps there is a misspelling "
- "in the server name, or the server no longer exists. Double-check the "
- "name and try again.</B></FONT><HR></BODY></HTML>")
- , s->server_info.name, host_name_expansion);
- // s->cache_info.action = CACHE_DO_NO_ACTION;
- TRANSACT_RETURN(PROXY_SEND_ERROR_CACHE_NOOP, NULL);
break;
default:
ink_debug_assert(!("try_to_expand_hostname returned an unsupported code"));
@@ -1593,6 +1600,27 @@ HttpTransact::OSDNSLookup(State* s)
ink_debug_assert(s->dns_info.lookup_success);
DebugTxn("http_seq", "[HttpTransact::OSDNSLookup] DNS Lookup successful");
+ if (DNSLookupInfo::OS_ADDR_TRY_HOSTDB == s->dns_info.os_addr_style) {
+ // We've backed off from a client supplied address and found some
+ // HostDB addresses. We use those if they're different from the CTA.
+ // In all cases we now commit to client or HostDB for our source.
+ if (s->dns_info.round_robin) {
+ HostDBInfo* cta = s->host_db_info.rr()->select_next(&s->current.server->addr.sa);
+ if (cta) {
+ // found another addr, lock in host DB.
+ s->host_db_info = *cta;
+ s->dns_info.os_addr_style = DNSLookupInfo::OS_ADDR_USE_HOSTDB;
+ } else {
+ // nothing else there, continue with CTA.
+ s->dns_info.os_addr_style = DNSLookupInfo::OS_ADDR_USE_CLIENT;
+ }
+ } else if (ats_ip_addr_eq(s->host_db_info.ip(), &s->server_info.addr.sa)) {
+ s->dns_info.os_addr_style = DNSLookupInfo::OS_ADDR_USE_CLIENT;
+ } else {
+ s->dns_info.os_addr_style = DNSLookupInfo::OS_ADDR_USE_HOSTDB;
+ }
+ }
+
// Check to see if can fullfill expect requests based on the cached
// update some state variables with hostdb information that has
// been provided.
@@ -1615,7 +1643,8 @@ HttpTransact::OSDNSLookup(State* s)
// hostname expansion, forward the request to the expanded hostname.
// On the other hand, if the lookup succeeded on a www.<hostname>.com
// expansion, return a 302 response.
- if (s->dns_info.attempts == max_dns_lookups && s->dns_info.looking_up == ORIGIN_SERVER) {
+ // [amc] Also don't redirect if we backed off using HostDB instead of CTA.
+ if (s->dns_info.attempts == max_dns_lookups && s->dns_info.looking_up == ORIGIN_SERVER && DNSLookupInfo::OS_ADDR_USE_CLIENT != s->dns_info.os_addr_style) {
DebugTxn("http_trans", "[OSDNSLookup] DNS name resolution on expansion");
DebugTxn("http_seq", "[OSDNSLookup] DNS name resolution on expansion - returning");
build_redirect_response(s);
@@ -1638,6 +1667,11 @@ HttpTransact::OSDNSLookup(State* s)
HttpTransactHeaders::convert_request(s->current.server->http_version, &s->hdr_info.server_request);
DebugTxn("cdn", "outgoing version -- (post conversion) %d", s->hdr_info.server_request.m_http->m_version);
TRANSACT_RETURN(s->cdn_saved_next_action, NULL);
+ } else if (DNSLookupInfo::OS_ADDR_USE_CLIENT == s->dns_info.os_addr_style ||
+ DNSLookupInfo::OS_ADDR_USE_HOSTDB == s->dns_info.os_addr_style) {
+ // we've come back after already trying the server to get a better address
+ // and finished with all backtracking - return to trying the server.
+ TRANSACT_RETURN(how_to_open_connection(s), HttpTransact::HandleResponse);
} else if (s->dns_info.lookup_name[0] <= '9' &&
s->dns_info.lookup_name[0] >= '0' &&
//(s->state_machine->authAdapter.needs_rev_dns() ||
@@ -3475,12 +3509,12 @@ HttpTransact::handle_response_from_server(State* s)
s->current.server->connect_failure = 1;
handle_server_connection_not_open(s);
break;
- case STATE_UNDEFINED:
- /* fall through */
case OPEN_RAW_ERROR:
/* fall through */
case CONNECTION_ERROR:
/* fall through */
+ case STATE_UNDEFINED:
+ /* fall through */
case INACTIVE_TIMEOUT:
/* fall through */
case PARSE_ERROR:
@@ -3504,7 +3538,19 @@ HttpTransact::handle_response_from_server(State* s)
bool use_srv_records = HttpConfig::m_master.srv_enabled;
- if (use_srv_records) {
+ if (DNSLookupInfo::OS_ADDR_TRY_CLIENT == s->dns_info.os_addr_style) {
+ // attempt was based on client supplied server address. Try again
+ // using HostDB.
+ // Allow DNS attempt
+ s->dns_info.lookup_success = false;
+ // See if we can get data from HostDB for this.
+ s->dns_info.os_addr_style = DNSLookupInfo::OS_ADDR_TRY_HOSTDB;
+ // Force host resolution to have the same family as the client.
+ // Because this is a transparent connection, we can't switch address
+ // families - that is locked in by the client source address.
+ s->state_machine->ua_session->host_res_style = ats_host_res_match(&s->current.server->addr.sa);
+ TRANSACT_RETURN(HttpTransact::DNS_LOOKUP, OSDNSLookup);
+ } else if (use_srv_records) {
delete_srv_entry(s, max_connect_retries);
return;
} else if (s->server_info.dns_round_robin &&
@@ -3542,40 +3588,33 @@ void
HttpTransact::delete_srv_entry(State* s, int max_retries)
{
/* we are using SRV lookups and this host failed -- lets remove it from the HostDB */
- INK_MD5 md5;
+ HostDBMD5 md5;
EThread *thread = this_ethread();
//ProxyMutex *mutex = thread->mutex;
- void *pDS = 0;
-
- int len;
- int port;
- ProxyMutex *bucket_mutex = hostDB.lock_for_bucket((int) (fold_md5(md5) % hostDB.buckets));
+ md5.host_name = s->dns_info.srv_hostname;
+ if (!md5.host_name) {
+ TRANSACT_RETURN(OS_RR_MARK_DOWN, ReDNSRoundRobin);
+ }
+ md5.host_len = strlen(md5.host_name);
+ md5.db_mark = HOSTDB_MARK_SRV;
+ md5.refresh();
- char *hostname = s->dns_info.srv_hostname; /* of the form: _http._tcp.host.foo.bar.com */
+ ProxyMutex *bucket_mutex = hostDB.lock_for_bucket((int) (fold_md5(md5.hash) % hostDB.buckets));
s->current.attempts++;
DebugTxn("http_trans", "[delete_srv_entry] attempts now: %d, max: %d", s->current.attempts, max_retries);
DebugTxn("dns_srv", "[delete_srv_entry] attempts now: %d, max: %d", s->current.attempts, max_retries);
- if (!hostname) {
- TRANSACT_RETURN(OS_RR_MARK_DOWN, ReDNSRoundRobin);
- }
-
- len = strlen(hostname);
- port = 0;
-
- make_md5(md5, hostname, len, port, 0, 1);
-
MUTEX_TRY_LOCK(lock, bucket_mutex, thread);
if (lock) {
- IpEndpoint ip;
- HostDBInfo *r = probe(bucket_mutex, md5, hostname, len, ats_ip4_set(&ip.sa, INADDR_ANY, htons(port)), pDS, false, true);
+// IpEndpoint ip;
+ HostDBInfo *r = probe(bucket_mutex, md5, false);
if (r) {
if (r->is_srv) {
- DebugTxn("dns_srv", "Marking SRV records for %s [Origin: %s] as bad", hostname, s->dns_info.lookup_name);
+ DebugTxn("dns_srv", "Marking SRV records for %s [Origin: %s] as bad", md5.host_name, s->dns_info.lookup_name);
- uint64_t folded_md5 = fold_md5(md5);
+ uint64_t folded_md5 = fold_md5(md5.hash);
HostDBInfo *new_r = NULL;
@@ -3586,7 +3625,7 @@ HttpTransact::delete_srv_entry(State* s, int max_retries)
hostDB.delete_block(r); //delete the original HostDB
new_r = hostDB.insert_block(folded_md5, NULL, 0); //create new entry
- new_r->md5_high = md5[1];
+ new_r->md5_high = md5.hash[1];
SortableQueue<SRV> *q = srv_hosts.getHosts(); //get the Queue of SRV entries
SRV *srv_entry = NULL;
@@ -3658,7 +3697,7 @@ HttpTransact::delete_srv_entry(State* s, int max_retries)
}
} else {
- DebugTxn("dns_srv", "Trying to delete a bad SRV for %s and something was wonky", hostname);
+ DebugTxn("dns_srv", "Trying to delete a bad SRV for %s and something was wonky", md5.host_name);
}
} else {
DebugTxn("dns_srv", "No SRV data to remove. Ruh Roh Shaggy. Maxing out connection attempts...");
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/http/HttpTransact.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.h b/proxy/http/HttpTransact.h
index e70d1b2..cbc20a0 100644
--- a/proxy/http/HttpTransact.h
+++ b/proxy/http/HttpTransact.h
@@ -834,6 +834,25 @@ public:
typedef struct _DNSLookupInfo
{
int attempts;
+ /** Origin server address source selection.
+
+ If config says to use CTA (client target addr) state is
+ OS_ADDR_TRY_CLIENT, otherwise it remains the default. If the
+ connect fails then we switch to a USE. We go to USE_HOSTDB if
+ (1) the HostDB lookup is successful and (2) some address other
+ than the CTA is available to try. Otherwise we keep retrying
+ on the CTA (USE_CLIENT) up to the max retry value. In essence
+ we try to treat the CTA as if it were another RR value in the
+ HostDB record.
+ */
+ enum {
+ OS_ADDR_TRY_DEFAULT, ///< Initial state, use what config says.
+ OS_ADDR_TRY_HOSTDB, ///< Try HostDB data.
+ OS_ADDR_TRY_CLIENT, ///< Try client target addr.
+ OS_ADDR_USE_HOSTDB, ///< Force use of HostDB target address.
+ OS_ADDR_USE_CLIENT ///< Use client target addr, no fallback.
+ } os_addr_style;
+
bool lookup_success;
char *lookup_name;
char srv_hostname[MAXDNAME];
@@ -841,7 +860,7 @@ public:
bool round_robin;
_DNSLookupInfo()
- : attempts(0),
+ : attempts(0), os_addr_style(OS_ADDR_TRY_DEFAULT),
lookup_success(false), lookup_name(NULL), looking_up(UNDEFINED_LOOKUP), round_robin(false)
{
memset(&srv_hostname, 0, sizeof(srv_hostname));
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/043815e7/proxy/logging/LogCollationClientSM.cc
----------------------------------------------------------------------
diff --git a/proxy/logging/LogCollationClientSM.cc b/proxy/logging/LogCollationClientSM.cc
index 7f761a5..3af7bb4 100644
--- a/proxy/logging/LogCollationClientSM.cc
+++ b/proxy/logging/LogCollationClientSM.cc
@@ -302,7 +302,7 @@ LogCollationClientSM::client_dns(int event, HostDBInfo * hostdb_info)
if (m_log_host->m_name == 0) {
return client_done(LOG_COLL_EVENT_SWITCH, NULL);
}
- hostDBProcessor.getbyname_re(this, m_log_host->m_name, 0, HostDBProcessor::HOSTDB_FORCE_DNS_RELOAD);
+ hostDBProcessor.getbyname_re(this, m_log_host->m_name, 0, HostDBProcessor::Options().setFlags(HostDBProcessor::HOSTDB_FORCE_DNS_RELOAD));
return EVENT_CONT;
case EVENT_HOST_DB_LOOKUP: