From: Alexander Nozdrin Date: August 7 2009 7:53pm Subject: bzr commit into mysql branch (alik:2848) Bug#45584 List-Archive: http://lists.mysql.com/commits/80395 X-Bug: 45584 Message-Id: <20090807195308.982857FC6B@quad> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_fd48lLeHLmqSslyG+WKS3Q)" --Boundary_(ID_fd48lLeHLmqSslyG+WKS3Q) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline #At file:///mnt/raid/alik/MySQL/bzr/bug38247/azalea-bf-bug45584/ based on revid:kostja@stripped 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 === 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 #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); +} --Boundary_(ID_fd48lLeHLmqSslyG+WKS3Q) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/alik@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/alik@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: alik@stripped # target_branch: file:///mnt/raid/alik/MySQL/bzr/bug38247/azalea-bf-\ # bug45584/ # testament_sha1: c0198a5f292912eb59547916725e11eb3670f5d7 # timestamp: 2009-08-07 23:53:08 +0400 # base_revision_id: kostja@stripped # # Begin bundle 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 --Boundary_(ID_fd48lLeHLmqSslyG+WKS3Q)--