You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jr...@apache.org on 2017/08/18 19:51:52 UTC

[trafficserver] branch master updated: Issue #2269: self detection.

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 <jr...@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" <co...@trafficserver.apache.org>'].