mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Fix for Bug#52923 (Inadequate documentation of "Can't get hostname for your address" error).
The thing is that on some platforms (e.g. Mac OS X) sockaddr_in / sockaddr_in6 contain a non-standard field (sin_len / sin6_len), that must be set. The problem was that only standard fields were set, thus getnameinfo() returned EAI_SYSTEM instead of EAI_NONAME. The fix is to introduce configure-time checks (for GNU auto-tools and CMake) for those additional fields and to set them if they are available.
This commit is contained in:
parent
534b3a520b
commit
75e552d509
4 changed files with 89 additions and 3 deletions
|
@ -282,6 +282,8 @@
|
|||
#cmakedefine HAVE_NETINET_IN6_H 1
|
||||
#cmakedefine HAVE_IPV6 1
|
||||
#cmakedefine ss_family @ss_family@
|
||||
#cmakedefine HAVE_SOCKADDR_IN_SIN_LEN 1
|
||||
#cmakedefine HAVE_SOCKADDR_IN6_SIN6_LEN 1
|
||||
#cmakedefine HAVE_TIMESPEC_TS_SEC 1
|
||||
#cmakedefine STRUCT_DIRENT_HAS_D_INO 1
|
||||
#cmakedefine STRUCT_DIRENT_HAS_D_NAMLEN 1
|
||||
|
|
|
@ -1000,6 +1000,21 @@ IF(NOT HAVE_SOCKADDR_STORAGE_SS_FAMILY)
|
|||
SET(ss_family __ss_family)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
#
|
||||
# Check if struct sockaddr_in::sin_len is available.
|
||||
#
|
||||
|
||||
CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in" sin_len
|
||||
"${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN_SIN_LEN)
|
||||
|
||||
#
|
||||
# Check if struct sockaddr_in6::sin6_len is available.
|
||||
#
|
||||
|
||||
CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin6_len
|
||||
"${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN6_SIN6_LEN)
|
||||
|
||||
SET(CMAKE_EXTRA_INCLUDE_FILES)
|
||||
|
||||
CHECK_STRUCT_HAS_MEMBER("struct dirent" d_ino "dirent.h" STRUCT_DIRENT_HAS_D_INO)
|
||||
|
|
61
configure.in
61
configure.in
|
@ -1012,6 +1012,66 @@ else
|
|||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Check if struct sockaddr_in::sin_len is available
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
AC_CACHE_CHECK(
|
||||
[if sockaddr_in::sin_len is available],
|
||||
mysql_cv_have_sockaddr_in_sin_len,
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
],
|
||||
[unsigned int i = sizeof(((struct sockaddr_in *) 0)->sin_len)],
|
||||
mysql_cv_have_sockaddr_in_sin_len=yes,
|
||||
mysql_cv_have_sockaddr_in_sin_len=no))
|
||||
|
||||
if test "$mysql_cv_have_sockaddr_in_sin_len" = "yes"; then
|
||||
AC_DEFINE(
|
||||
[HAVE_SOCKADDR_IN_SIN_LEN],
|
||||
[1],
|
||||
[If sockaddr_in::sin_len is available])
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Check if struct sockaddr_in6::sin6_len is available
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
AC_CACHE_CHECK(
|
||||
[if sockaddr_in6::sin6_len is available],
|
||||
mysql_cv_have_sockaddr_in6_sin6_len,
|
||||
AC_TRY_COMPILE(
|
||||
[
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETINET_IN6_H
|
||||
#include <netinet/in6.h>
|
||||
#endif
|
||||
],
|
||||
[unsigned int i = sizeof(((struct sockaddr_in6 *) 0)->sin6_len)],
|
||||
mysql_cv_have_sockaddr_in6_sin6_len=yes,
|
||||
mysql_cv_have_sockaddr_in6_sin6_len=no))
|
||||
|
||||
if test "$mysql_cv_have_sockaddr_in_sin6_len" = "yes"; then
|
||||
AC_DEFINE(
|
||||
[HAVE_SOCKADDR_IN6_SIN6_LEN],
|
||||
[1],
|
||||
[If sockaddr_in6::sin6_len is available])
|
||||
fi
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Check for TCP wrapper support
|
||||
#--------------------------------------------------------------------
|
||||
|
@ -3121,6 +3181,7 @@ esac
|
|||
|
||||
AC_SUBST([RDTSC_SPARC_ASSEMBLY])
|
||||
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Output results
|
||||
#--------------------------------------------------------------------
|
||||
|
|
|
@ -1057,9 +1057,11 @@ ssize_t vio_pending(Vio *vio)
|
|||
|
||||
/**
|
||||
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.
|
||||
differ in the getnameinfo() implementation:
|
||||
- Solaris 10 requires that the 2nd argument (salen) must match the
|
||||
actual size of the struct sockaddr_storage passed to it;
|
||||
- Mac OS X has sockaddr_in::sin_len and sockaddr_in6::sin6_len and
|
||||
requires them to be filled.
|
||||
*/
|
||||
|
||||
int vio_getnameinfo(const struct sockaddr *sa,
|
||||
|
@ -1072,11 +1074,17 @@ int vio_getnameinfo(const struct sockaddr *sa,
|
|||
switch (sa->sa_family) {
|
||||
case AF_INET:
|
||||
sa_length= sizeof (struct sockaddr_in);
|
||||
#ifdef HAVE_SOCKADDR_IN_SIN_LEN
|
||||
((struct sockaddr_in *) sa)->sin_len= sa_length;
|
||||
#endif /* HAVE_SOCKADDR_IN_SIN_LEN */
|
||||
break;
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
case AF_INET6:
|
||||
sa_length= sizeof (struct sockaddr_in6);
|
||||
# ifdef HAVE_SOCKADDR_IN6_SIN6_LEN
|
||||
((struct sockaddr_in6 *) sa)->sin6_len= sa_length;
|
||||
# endif /* HAVE_SOCKADDR_IN6_SIN6_LEN */
|
||||
break;
|
||||
#endif /* HAVE_IPV6 */
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue