#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 <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 commit into mysql branch (alik:2848) Bug#45584 | Alexander Nozdrin | 7 Aug |