This is an automated email from the ASF dual-hosted git repository. jrushford pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new 7530f77 Issue #2269: self detection. 7530f77 is described below commit 7530f775f603e055eb8cfab2a4d6fdcf8685d3b4 Author: John J. Rushford <jrushf...@apache.org> AuthorDate: Wed Jul 19 17:58:32 2017 +0000 Issue #2269: self detection. --- iocore/utils/I_Machine.h | 8 +++ iocore/utils/Machine.cc | 129 +++++++++++++++++++++++++++++++++++++++++++---- proxy/ParentSelection.cc | 46 ++++++++++++++++- proxy/ParentSelection.h | 1 + 4 files changed, 173 insertions(+), 11 deletions(-) diff --git a/iocore/utils/I_Machine.h b/iocore/utils/I_Machine.h index d9296c1..ba6adc3 100644 --- a/iocore/utils/I_Machine.h +++ b/iocore/utils/I_Machine.h @@ -33,6 +33,7 @@ #include "ts/ink_inet.h" #include "ts/ink_uuid.h" +#include "ts/ink_hash_table.h" /** The Machine is a simple place holder for the hostname and the ip @@ -79,11 +80,18 @@ struct Machine { ); /// @return The global instance of this class. static self *instance(); + bool is_self(const char *name); + bool is_self(const IpAddr *ipaddr); + void insert_id(char *id); + void insert_id(IpAddr *ipaddr); protected: Machine(char const *hostname, sockaddr const *addr); static self *_instance; ///< Singleton for the class. + + InkHashTable *machine_id_strings; + InkHashTable *machine_id_ipaddrs; }; #endif diff --git a/iocore/utils/Machine.cc b/iocore/utils/Machine.cc index 09bf84c..d6d70e4 100644 --- a/iocore/utils/Machine.cc +++ b/iocore/utils/Machine.cc @@ -31,6 +31,22 @@ #include <ifaddrs.h> #endif +static void +make_to_lower_case(const char *name, char *lower_case_name, int buf_len) +{ + int name_len = strlen(name); + int i; + + if (name_len > (buf_len - 1)) { + name_len = buf_len - 1; + } + + for (i = 0; i < name_len; i++) { + lower_case_name[i] = ParseRules::ink_tolower(name[i]); + } + lower_case_name[i] = '\0'; +} + // Singleton Machine *Machine::_instance = nullptr; @@ -50,9 +66,15 @@ Machine::init(char const *name, sockaddr const *ip) } Machine::Machine(char const *the_hostname, sockaddr const *addr) - : hostname(nullptr), hostname_len(0), ip_string_len(0), ip_hex_string_len(0) + : hostname(nullptr), + hostname_len(0), + ip_string_len(0), + ip_hex_string_len(0), + machine_id_strings(ink_hash_table_create(InkHashTableKeyType_String)), + machine_id_ipaddrs(ink_hash_table_create(InkHashTableKeyType_String)) { char localhost[1024]; + char ip_strbuf[INET6_ADDRSTRLEN]; int status; // return for system calls. ip_string[0] = 0; @@ -148,15 +170,26 @@ Machine::Machine(char const *the_hostname, sockaddr const *addr) continue; // Next! } - if (ats_is_ip4(ifip)) { - if (spot_type > ip4_type) { - ats_ip_copy(&ip4, ifip); - ip4_type = spot_type; + if (ats_is_ip4(ifip) || ats_is_ip6(ifip)) { + ink_zero(ip_strbuf); + ink_zero(localhost); + ats_ip_ntop(ifip, ip_strbuf, sizeof(ip_strbuf)); + insert_id(ip_strbuf); + if (getnameinfo(ifip, ats_ip_size(ifip), localhost, sizeof(localhost) - 1, nullptr, 0, 0) == 0) { + insert_id(localhost); } - } else if (ats_is_ip6(ifip)) { - if (spot_type > ip6_type) { - ats_ip_copy(&ip6, ifip); - ip6_type = spot_type; + IpAddr *ipaddr = new IpAddr(ifip); + insert_id(ipaddr); + if (ats_is_ip4(ifip)) { + if (spot_type > ip4_type) { + ats_ip_copy(&ip4, ifip); + ip4_type = spot_type; + } + } else if (ats_is_ip6(ifip)) { + if (spot_type > ip6_type) { + ats_ip_copy(&ip6, ifip); + ip6_type = spot_type; + } } } } @@ -203,4 +236,82 @@ Machine::Machine(char const *the_hostname, sockaddr const *addr) Machine::~Machine() { ats_free(hostname); + + // release machine_id_strings hash table. + InkHashTableIteratorState ht_iter; + InkHashTableEntry *ht_entry = nullptr; + ht_entry = ink_hash_table_iterator_first(machine_id_strings, &ht_iter); + + while (ht_entry != nullptr) { + char *value = static_cast<char *>(ink_hash_table_entry_value(machine_id_strings, ht_entry)); + ats_free(value); + ht_entry = ink_hash_table_iterator_next(machine_id_strings, &ht_iter); + } + ink_hash_table_destroy(machine_id_strings); + + // release machine_id_ipaddrs hash table. + ht_entry = nullptr; + ht_entry = ink_hash_table_iterator_first(machine_id_ipaddrs, &ht_iter); + while (ht_entry != nullptr) { + IpAddr *ipaddr = static_cast<IpAddr *>(ink_hash_table_entry_value(machine_id_ipaddrs, ht_entry)); + delete ipaddr; + ht_entry = ink_hash_table_iterator_next(machine_id_ipaddrs, &ht_iter); + } + ink_hash_table_destroy(machine_id_ipaddrs); +} + +bool +Machine::is_self(const char *name) +{ + char lower_case_name[TS_MAX_HOST_NAME_LEN + 1] = {0}; + void *value = nullptr; + + if (name == nullptr) { + return false; + } + + make_to_lower_case(name, lower_case_name, sizeof(lower_case_name)); + + return ink_hash_table_lookup(machine_id_strings, lower_case_name, &value) == 1 ? true : false; +} + +bool +Machine::is_self(const IpAddr *ipaddr) +{ + void *value = nullptr; + char string_value[INET6_ADDRSTRLEN + 1] = {0}; + + if (ipaddr == nullptr) { + return false; + } + ipaddr->toString(string_value, sizeof(string_value)); + return ink_hash_table_lookup(machine_id_ipaddrs, string_value, &value) == 1 ? true : false; +} + +void +Machine::insert_id(char *id) +{ + char lower_case_name[TS_MAX_HOST_NAME_LEN + 1] = {0}; + char *value = nullptr; + size_t len = strlen(id); + + if (id != nullptr) { + value = static_cast<char *>(ats_malloc(len)); + make_to_lower_case(id, lower_case_name, sizeof(lower_case_name)); + strncpy(value, lower_case_name, strlen(lower_case_name)); + ink_hash_table_insert(machine_id_strings, lower_case_name, value); + } +} + +void +Machine::insert_id(IpAddr *ipaddr) +{ + int length = INET6_ADDRSTRLEN + 1; + char *string_value = static_cast<char *>(ats_calloc(length, 1)); + + if (ipaddr != nullptr) { + ipaddr->toString(string_value, length); + ink_hash_table_insert(machine_id_strings, string_value, string_value); + ink_hash_table_insert(machine_id_ipaddrs, string_value, ipaddr); + } } diff --git a/proxy/ParentSelection.cc b/proxy/ParentSelection.cc index 5f19141..2d64d24 100644 --- a/proxy/ParentSelection.cc +++ b/proxy/ParentSelection.cc @@ -29,6 +29,7 @@ #include "ProxyConfig.h" #include "HTTP.h" #include "HttpTransact.h" +#include "I_Machine.h" #define MAX_SIMPLE_RETRIES 5 #define MAX_UNAVAILABLE_SERVER_RETRIES 5 @@ -333,6 +334,44 @@ UnavailableServerResponseCodes::UnavailableServerResponseCodes(char *val) std::sort(codes.begin(), codes.end()); } +void +ParentRecord::PreProcessParents(const char *val, const int line_num, char *buf, size_t len) +{ + char *_val = static_cast<char *>(ats_strndup(val, strlen(val))); + char fqdn[TS_MAX_HOST_NAME_LEN] = {0}, *nm, *token, *savePtr; + std::string str; + Machine *machine = Machine::instance(); + + strncpy(_val, val, strlen(val)); + + token = strtok_r(_val, ";", &savePtr); + while (token != nullptr) { + if ((nm = strchr(token, ':')) != nullptr) { + size_t len = (nm - token); + ink_assert(len < sizeof(fqdn)); + memset(fqdn, 0, sizeof(fqdn)); + strncpy(fqdn, token, len); + if (machine->is_self(fqdn)) { + Debug("parent_select", "token: %s, matches this machine. Removing self from parent list at line %d", fqdn, line_num); + token = strtok_r(nullptr, ";", &savePtr); + continue; + } + } else { + if (machine->is_self(token)) { + Debug("parent_select", "token: %s, matches this machine. Removing self from parent list at line %d", token, line_num); + token = strtok_r(nullptr, ";", &savePtr); + continue; + } + } + + str += token; + str += ";"; + token = strtok_r(nullptr, ";", &savePtr); + } + strncpy(buf, str.c_str(), len); + ats_free(_val); +} + // const char* ParentRecord::ProcessParents(char* val, bool isPrimary) // // Reads in the value of a "round-robin" or "order" @@ -524,6 +563,7 @@ ParentRecord::Init(matcher_line *line_info) const char *tmp; char *label; char *val; + char parent_buf[16384] = {0}; bool used = false; ParentRR_t round_robin = P_NO_ROUND_ROBIN; char buf[128]; @@ -557,10 +597,12 @@ ParentRecord::Init(matcher_line *line_info) } used = true; } else if (strcasecmp(label, "parent") == 0 || strcasecmp(label, "primary_parent") == 0) { - errPtr = ProcessParents(val, true); + PreProcessParents(val, line_num, parent_buf, sizeof(parent_buf) - 1); + errPtr = ProcessParents(parent_buf, true); used = true; } else if (strcasecmp(label, "secondary_parent") == 0) { - errPtr = ProcessParents(val, false); + PreProcessParents(val, line_num, parent_buf, sizeof(parent_buf) - 1); + errPtr = ProcessParents(parent_buf, false); used = true; } else if (strcasecmp(label, "go_direct") == 0) { if (strcasecmp(val, "false") == 0) { diff --git a/proxy/ParentSelection.h b/proxy/ParentSelection.h index 62ef8db..57d842e 100644 --- a/proxy/ParentSelection.h +++ b/proxy/ParentSelection.h @@ -134,6 +134,7 @@ public: const char *scheme = nullptr; // private: + void PreProcessParents(const char *val, const int line_num, char *buf, size_t len); const char *ProcessParents(char *val, bool isPrimary); bool ignore_query = false; volatile uint32_t rr_next = 0; -- To stop receiving notification emails like this one, please contact ['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].