List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:August 7 2009 7:53pm
Subject:bzr push into mysql branch (alik:2847 to 2848) Bug#45584
View as plain text  
 2848 Alexander Nozdrin	2009-08-07
      Postfix for Bug#45584.
      
      The problem is that the host name cache key must be
      of char[HOST_ENTRY_KEY_SIZE].

    modified:
      include/violite.h
      sql/hostname.cc
      vio/viosocket.c
 2847 Konstantin Osipov	2009-08-06
      Remove unused defines.

    modified:
      sql/client_settings.h
=== modified file 'include/violite.h'
--- a/include/violite.h	2009-08-05 17:50:09 +0000
+++ b/include/violite.h	2009-08-07 19:53:03 +0000
@@ -89,6 +89,11 @@ ssize_t vio_pending(Vio *vio);
 my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, int addr_length,
                                      char *ip_string, size_t ip_string_size);
 
+int vio_getnameinfo(const struct sockaddr *sa,
+                    char *hostname, size_t hostname_size,
+                    char *port, size_t port_size,
+                    int flags);
+
 #ifdef HAVE_OPENSSL
 #include <openssl/opensslv.h>
 #if OPENSSL_VERSION_NUMBER < 0x0090700f

=== modified file 'sql/hostname.cc'
--- a/sql/hostname.cc	2009-08-05 17:50:09 +0000
+++ b/sql/hostname.cc	2009-08-07 19:53:03 +0000
@@ -68,7 +68,7 @@ public:
 
     This IP address is never used to connect to a socket.
   */
-  char ip_string[HOST_ENTRY_KEY_SIZE];
+  char ip_key[HOST_ENTRY_KEY_SIZE];
 
   /**
     Number of errors during handshake phase from the IP address.
@@ -91,7 +91,7 @@ void hostname_cache_refresh()
 bool hostname_cache_init()
 {
   Host_entry tmp;
-  uint key_offset= (uint) ((char*) (&tmp.ip_string) - (char*) &tmp);
+  uint key_offset= (uint) ((char*) (&tmp.ip_key) - (char*) &tmp);
 
   if (!(hostname_cache= new hash_filo(HOST_CACHE_SIZE,
                                       key_offset, HOST_ENTRY_KEY_SIZE,
@@ -110,14 +110,24 @@ void hostname_cache_free()
   hostname_cache= NULL;
 }
 
-static inline Host_entry *hostname_cache_search(const char *ip_string)
+static void prepare_hostname_cache_key(const char *ip_string,
+                                       char *ip_key)
 {
-  return (Host_entry *) hostname_cache->search((uchar *) ip_string, 0);
+  int ip_string_length= strlen(ip_string);
+  DBUG_ASSERT(ip_string_length < HOST_ENTRY_KEY_SIZE);
+
+  memset(ip_key, 0, HOST_ENTRY_KEY_SIZE);
+  memcpy_fixed(ip_key, ip_string, ip_string_length);
+}
+
+static inline Host_entry *hostname_cache_search(const char *ip_key)
+{
+  return (Host_entry *) hostname_cache->search((uchar *) ip_key, 0);
 }
 
-static bool add_hostname_impl(const char *ip_string, const char *hostname)
+static bool add_hostname_impl(const char *ip_key, const char *hostname)
 {
-  if (hostname_cache_search(ip_string))
+  if (hostname_cache_search(ip_key))
     return FALSE;
 
   size_t hostname_size= hostname ? strlen(hostname) + 1 : 0;
@@ -129,7 +139,7 @@ static bool add_hostname_impl(const char
 
   char *hostname_copy;
 
-  memcpy_fixed(&entry->ip_string, ip_string, HOST_ENTRY_KEY_SIZE);
+  memcpy_fixed(&entry->ip_key, ip_key, HOST_ENTRY_KEY_SIZE);
 
   if (hostname_size)
   {
@@ -137,7 +147,7 @@ static bool add_hostname_impl(const char
     memcpy(hostname_copy, hostname, hostname_size);
 
     DBUG_PRINT("info", ("Adding '%s' -> '%s' to the hostname cache...'",
-                        (const char *) ip_string,
+                        (const char *) ip_key,
                         (const char *) hostname_copy));
   }
   else
@@ -145,7 +155,7 @@ static bool add_hostname_impl(const char
     hostname_copy= NULL;
 
     DBUG_PRINT("info", ("Adding '%s' -> NULL to the hostname cache...'",
-                        (const char *) ip_string));
+                        (const char *) ip_key));
   }
 
   entry->hostname= hostname_copy;
@@ -154,14 +164,14 @@ static bool add_hostname_impl(const char
   return hostname_cache->add(entry);
 }
 
-static bool add_hostname(const char *ip_string, const char *hostname)
+static bool add_hostname(const char *ip_key, const char *hostname)
 {
   if (specialflag & SPECIAL_NO_HOST_CACHE)
     return FALSE;
 
   pthread_mutex_lock(&hostname_cache->lock);
 
-  bool err_status= add_hostname_impl(ip_string, hostname);
+  bool err_status= add_hostname_impl(ip_key, hostname);
 
   pthread_mutex_unlock(&hostname_cache->lock);
 
@@ -173,9 +183,12 @@ void inc_host_errors(const char *ip_stri
   if (!ip_string)
     return;
 
+  char ip_key[HOST_ENTRY_KEY_SIZE];
+  prepare_hostname_cache_key(ip_string, ip_key);
+
   pthread_mutex_lock(&hostname_cache->lock);
 
-  Host_entry *entry= hostname_cache_search(ip_string);
+  Host_entry *entry= hostname_cache_search(ip_key);
 
   if (entry)
     entry->connect_errors++;
@@ -189,9 +202,12 @@ void reset_host_errors(const char *ip_st
   if (!ip_string)
     return;
 
+  char ip_key[HOST_ENTRY_KEY_SIZE];
+  prepare_hostname_cache_key(ip_string, ip_key);
+
   pthread_mutex_lock(&hostname_cache->lock);
 
-  Host_entry *entry= hostname_cache_search(ip_string);
+  Host_entry *entry= hostname_cache_search(ip_key);
 
   if (entry)
     entry->connect_errors= 0;
@@ -275,12 +291,18 @@ bool ip_to_hostname(struct sockaddr_stor
 {
   const struct sockaddr *ip= (const sockaddr *) ip_storage;
   int err_code;
+  bool err_status;
 
   DBUG_ENTER("ip_to_hostname");
   DBUG_PRINT("info", ("IP address: '%s'; family: %d.",
                       (const char *) ip_string,
                       (int) ip->sa_family));
 
+  /* Prepare host name cache key. */
+
+  char ip_key[HOST_ENTRY_KEY_SIZE];
+  prepare_hostname_cache_key(ip_string, ip_key);
+
   /* Check if we have loopback address (127.0.0.1 or ::1). */
 
   if (is_ip_loopback(ip))
@@ -299,7 +321,7 @@ bool ip_to_hostname(struct sockaddr_stor
   {
     pthread_mutex_lock(&hostname_cache->lock);
 
-    Host_entry *entry= hostname_cache_search(ip_string);
+    Host_entry *entry= hostname_cache_search(ip_key);
 
     if (entry)
     {
@@ -311,7 +333,7 @@ bool ip_to_hostname(struct sockaddr_stor
 
       DBUG_PRINT("info",("IP (%s) has been found in the cache. "
                          "Hostname: '%s'; connect_errors: %d",
-                         (const char *) ip_string,
+                         (const char *) ip_key,
                          (const char *) (*hostname? *hostname : "null"),
                          (int) *connect_errors));
 
@@ -330,10 +352,10 @@ bool ip_to_hostname(struct sockaddr_stor
 
   char hostname_buffer[NI_MAXHOST];
 
-  DBUG_PRINT("info", ("Resolving '%s'...", (const char *) ip_string));
+  DBUG_PRINT("info", ("Resolving '%s'...", (const char *) ip_key));
 
-  err_code= getnameinfo(ip, sizeof (sockaddr_storage),
-                        hostname_buffer, NI_MAXHOST, NULL, 0, NI_NAMEREQD);
+  err_code= vio_getnameinfo(ip, hostname_buffer, NI_MAXHOST, NULL, 0,
+                            NI_NAMEREQD);
 
   if (err_code == EAI_NONAME)
   {
@@ -344,13 +366,13 @@ bool ip_to_hostname(struct sockaddr_stor
 
     DBUG_PRINT("error", ("IP address '%s' could not be resolved: "
                          "no reverse address mapping.",
-                         (const char *) ip_string));
+                         (const char *) ip_key));
 
     sql_print_warning("IP address '%s' could not be resolved: "
                       "no reverse address mapping.",
-                      (const char *) ip_string);
+                      (const char *) ip_key);
 
-    bool err_status= add_hostname(ip_string, NULL);
+    err_status= add_hostname(ip_key, NULL);
 
     *hostname= NULL;
     *connect_errors= 0; /* New IP added to the cache. */
@@ -361,19 +383,19 @@ bool ip_to_hostname(struct sockaddr_stor
   {
     DBUG_PRINT("error", ("IP address '%s' could not be resolved: "
                          "getnameinfo() returned %d.",
-                         (const char *) ip_string,
+                         (const char *) ip_key,
                          (int) err_code));
 
     sql_print_warning("IP address '%s' could not be resolved: "
                       "getnameinfo() returned error (code: %d).",
-                      (const char *) ip_string,
+                      (const char *) ip_key,
                       (int) err_code);
 
     DBUG_RETURN(TRUE);
   }
 
   DBUG_PRINT("info", ("IP '%s' resolved to '%s'.",
-                      (const char *) ip_string,
+                      (const char *) ip_key,
                       (const char *) hostname_buffer));
 
   /*
@@ -396,16 +418,16 @@ bool ip_to_hostname(struct sockaddr_stor
     DBUG_PRINT("error", ("IP address '%s' has been resolved "
                          "to the host name '%s', which resembles "
                          "IPv4-address itself.",
-                         (const char *) ip_string,
+                         (const char *) ip_key,
                          (const char *) hostname_buffer));
 
     sql_print_warning("IP address '%s' has been resolved "
                       "to the host name '%s', which resembles "
                       "IPv4-address itself.",
-                      (const char *) ip_string,
+                      (const char *) ip_key,
                       (const char *) hostname_buffer);
 
-    bool err_status= add_hostname(ip_string, NULL);
+    err_status= add_hostname(ip_key, NULL);
 
     *hostname= NULL;
     *connect_errors= 0; /* New IP added to the cache. */
@@ -437,7 +459,7 @@ bool ip_to_hostname(struct sockaddr_stor
       indefinitely.
     */
 
-    bool err_status= add_hostname(ip_string, NULL);
+    err_status= add_hostname(ip_key, NULL);
 
     *hostname= NULL;
     *connect_errors= 0; /* New IP added to the cache. */
@@ -461,15 +483,14 @@ bool ip_to_hostname(struct sockaddr_stor
     char ip_buffer[HOST_ENTRY_KEY_SIZE];
 
     {
-      bool err_status=
-        vio_get_normalized_ip_string(addr_info->ai_addr, addr_info->ai_addrlen,
-                                     ip_buffer, sizeof (ip_buffer));
+      vio_get_normalized_ip_string(addr_info->ai_addr, addr_info->ai_addrlen,
+                                   ip_buffer, sizeof (ip_buffer));
       DBUG_ASSERT(!err_status);
     }
 
     DBUG_PRINT("info", ("  - '%s'", (const char *) ip_buffer));
 
-    if (strcmp(ip_string, ip_buffer) == 0)
+    if (strcmp(ip_key, ip_buffer) == 0)
     {
       /* Copy host name string to be stored in the cache. */
 
@@ -493,7 +514,7 @@ bool ip_to_hostname(struct sockaddr_stor
   {
     sql_print_information("Hostname '%s' does not resolve to '%s'.",
                           (const char *) hostname_buffer,
-                          (const char *) ip_string);
+                          (const char *) ip_key);
     sql_print_information("Hostname '%s' has the following IP addresses:",
                           (const char *) hostname_buffer);
 
@@ -502,9 +523,8 @@ bool ip_to_hostname(struct sockaddr_stor
     {
       char ip_buffer[HOST_ENTRY_KEY_SIZE];
 
-      bool err_status=
-        vio_get_normalized_ip_string(addr_info->ai_addr, addr_info->ai_addrlen,
-                                     ip_buffer, sizeof (ip_buffer));
+      vio_get_normalized_ip_string(addr_info->ai_addr, addr_info->ai_addrlen,
+                                   ip_buffer, sizeof (ip_buffer));
       DBUG_ASSERT(err_status);
 
       sql_print_information(" - %s\n", (const char *) ip_buffer);
@@ -517,18 +537,16 @@ bool ip_to_hostname(struct sockaddr_stor
 
   /* Add an entry for the IP to the cache. */
 
-  bool err_status;
-
   if (*hostname)
   {
-    err_status= add_hostname(ip_string, *hostname);
+    err_status= add_hostname(ip_key, *hostname);
     *connect_errors= 0;
   }
   else
   {
     DBUG_PRINT("error",("Couldn't verify hostname with getaddrinfo()."));
 
-    err_status= add_hostname(ip_string, NULL);
+    err_status= add_hostname(ip_key, NULL);
     *hostname= NULL;
     *connect_errors= 0;
   }

=== modified file 'vio/viosocket.c'
--- a/vio/viosocket.c	2009-08-05 17:50:09 +0000
+++ b/vio/viosocket.c	2009-08-07 19:53:03 +0000
@@ -417,9 +417,8 @@ my_bool vio_get_normalized_ip_string(con
 
   vio_get_normalized_ip(addr, addr_length, norm_addr, &norm_addr_length);
 
-  err_code= getnameinfo(norm_addr, norm_addr_length,
-                        ip_string, ip_string_size, NULL, 0,
-                        NI_NUMERICHOST);
+  err_code= vio_getnameinfo(norm_addr, ip_string, ip_string_size, NULL, 0,
+                            NI_NUMERICHOST);
 
   if (!err_code)
     return FALSE;
@@ -479,10 +478,10 @@ my_bool vio_peer_addr(Vio *vio, char *ip
 
     /* Get IP address & port number. */
 
-    err_code= getnameinfo((struct sockaddr *) &vio->remote, vio->addrLen,
-                          ip_buffer, ip_buffer_size,
-                          port_buffer, NI_MAXSERV,
-                          NI_NUMERICHOST | NI_NUMERICSERV);
+    err_code= vio_getnameinfo((struct sockaddr *) &vio->remote,
+                              ip_buffer, ip_buffer_size,
+                              port_buffer, NI_MAXSERV,
+                              NI_NUMERICHOST | NI_NUMERICSERV);
 
     if (err_code)
     {
@@ -966,3 +965,36 @@ ssize_t vio_pending(Vio *vio)
 
   return 0;
 }
+
+
+/**
+  This is a wrapper for the system getnameinfo(), because different OS
+  differ in the getnameinfo() implementation. For instance, Solaris 10
+  requires that the 2nd argument (salen) must match the actual size of the
+  struct sockaddr_storage passed to it.
+*/
+
+int vio_getnameinfo(const struct sockaddr *sa,
+                    char *hostname, size_t hostname_size,
+                    char *port, size_t port_size,
+                    int flags)
+{
+  int sa_length= 0;
+
+  switch (sa->sa_family) {
+  case AF_INET:
+    sa_length= sizeof (struct sockaddr_in);
+    break;
+
+#ifdef HAVE_IPV6
+  case AF_INET6:
+    sa_length= sizeof (struct sockaddr_in6);
+    break;
+#endif /* HAVE_IPV6 */
+  }
+
+  return getnameinfo(sa, sa_length,
+                     hostname, hostname_size,
+                     port, port_size,
+                     flags);
+}


Attachment: [text/bzr-bundle] bzr/alik@sun.com-20090807195303-j4fb5m4l1dgdahwo.bundle
Thread
bzr push into mysql branch (alik:2847 to 2848) Bug#45584Alexander Nozdrin7 Aug