Commit 9303909a authored by Alexander Nozdrin's avatar Alexander Nozdrin

A patch for Bug#12325375: THE SERVER ON WINXP DOES NOT ALLOW CONNECTIONS

IF NO DNS-SERVER AVAILABLE.

The thing is that on Windows XP getnameinfo() returns WSANO_DATA
when hostname-lookup is not available. The problem was that
this error code was treated as serious error and the client
connection got rejected.

The fix is to treat all errors from getnameinfo() as not ciritical,
but add IP-address to the host cache only for EAI_NONAME (or WSANO_DATA).
parent 5ffab995
/* Copyright (C) 2000 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -93,6 +93,8 @@ ssize_t vio_pending(Vio *vio); ...@@ -93,6 +93,8 @@ ssize_t vio_pending(Vio *vio);
my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, int addr_length, my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, int addr_length,
char *ip_string, size_t ip_string_size); char *ip_string, size_t ip_string_size);
my_bool vio_is_no_name_error(int err_code);
int vio_getnameinfo(const struct sockaddr *sa, int vio_getnameinfo(const struct sockaddr *sa,
char *hostname, size_t hostname_size, char *hostname, size_t hostname_size,
char *port, size_t port_size, char *port, size_t port_size,
......
/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -366,41 +366,35 @@ bool ip_to_hostname(struct sockaddr_storage *ip_storage, ...@@ -366,41 +366,35 @@ bool ip_to_hostname(struct sockaddr_storage *ip_storage,
err_code= vio_getnameinfo(ip, hostname_buffer, NI_MAXHOST, NULL, 0, err_code= vio_getnameinfo(ip, hostname_buffer, NI_MAXHOST, NULL, 0,
NI_NAMEREQD); NI_NAMEREQD);
if (err_code == EAI_NONAME) if (err_code)
{ {
/* // NOTE: gai_strerror() returns a string ending by a dot.
There is no reverse address mapping for the IP address. A host name
can not be resolved.
*/
DBUG_PRINT("error", ("IP address '%s' could not be resolved: " DBUG_PRINT("error", ("IP address '%s' could not be resolved: %s",
"no reverse address mapping.", (const char *) ip_key,
(const char *) ip_key)); (const char *) gai_strerror(err_code)));
sql_print_warning("IP address '%s' could not be resolved: " sql_print_warning("IP address '%s' could not be resolved: %s",
"no reverse address mapping.", (const char *) ip_key,
(const char *) ip_key); (const char *) gai_strerror(err_code));
err_status= add_hostname(ip_key, NULL); if (vio_is_no_name_error(err_code))
{
/*
The no-name error means that there is no reverse address mapping
for the IP address. A host name can not be resolved.
*hostname= NULL; If it is not the no-name error, we should not cache the hostname
*connect_errors= 0; /* New IP added to the cache. */ (or rather its absence), because the failure might be transient.
*/
DBUG_RETURN(err_status); add_hostname(ip_key, NULL);
}
else if (err_code)
{
DBUG_PRINT("error", ("IP address '%s' could not be resolved: "
"getnameinfo() returned %d.",
(const char *) ip_key,
(int) err_code));
sql_print_warning("IP address '%s' could not be resolved: " *hostname= NULL;
"getnameinfo() returned error (code: %d).", *connect_errors= 0; /* New IP added to the cache. */
(const char *) ip_key, }
(int) err_code);
DBUG_RETURN(TRUE); DBUG_RETURN(FALSE);
} }
DBUG_PRINT("info", ("IP '%s' resolved to '%s'.", DBUG_PRINT("info", ("IP '%s' resolved to '%s'.",
......
/* Copyright (C) 2000 MySQL AB /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -1059,6 +1059,34 @@ ssize_t vio_pending(Vio *vio) ...@@ -1059,6 +1059,34 @@ ssize_t vio_pending(Vio *vio)
} }
/**
Checks if the error code, returned by vio_getnameinfo(), means it was the
"No-name" error.
Windows-specific note: getnameinfo() returns WSANO_DATA instead of
EAI_NODATA or EAI_NONAME when no reverse mapping is available at the host
(i.e. Windows can't get hostname by IP-address). This error should be
treated as EAI_NONAME.
@return if the error code is actually EAI_NONAME.
@retval true if the error code is EAI_NONAME.
@retval false otherwise.
*/
my_bool vio_is_no_name_error(int err_code)
{
#ifdef _WIN32
return err_code == WSANO_DATA || err_code == EAI_NONAME;
#else
return err_code == EAI_NONAME;
#endif
}
/** /**
This is a wrapper for the system getnameinfo(), because different OS This is a wrapper for the system getnameinfo(), because different OS
differ in the getnameinfo() implementation: differ in the getnameinfo() implementation:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment