2003-04-24  Ulrich Drepper  <drepper@redhat.com>

	* include/ifaddrs.h: New file.
	* include/netdb.h: Move definitions of AI_V4MAPPED, AI_ALL, and
	AI_ADDRCONFIG...
	* resolv/netdb.h: ...here.
	* sysdeps/gnu/ifaddrs.c. Use libc_hidden_def where appropriate.
	* sysdeps/unix/sysv/linux/ifaddrs.c: Likewise.
	* sysdeps/posix/getaddrinfo.c: Implement AI_V4MAPPED, AI_ALL, and
	AI_ADDRCONFIG.
This commit is contained in:
Ulrich Drepper 2003-04-24 23:45:17 +00:00
parent ff479b9b9a
commit 925c3c5c71
8 changed files with 582 additions and 105 deletions

View File

@ -1,3 +1,14 @@
2003-04-24 Ulrich Drepper <drepper@redhat.com>
* include/ifaddrs.h: New file.
* include/netdb.h: Move definitions of AI_V4MAPPED, AI_ALL, and
AI_ADDRCONFIG...
* resolv/netdb.h: ...here.
* sysdeps/gnu/ifaddrs.c. Use libc_hidden_def where appropriate.
* sysdeps/unix/sysv/linux/ifaddrs.c: Likewise.
* sysdeps/posix/getaddrinfo.c: Implement AI_V4MAPPED, AI_ALL, and
AI_ADDRCONFIG.
2003-04-24 Roland McGrath <roland@redhat.com>
* elf/dl-reloc.c (_dl_allocate_static_tls): Add internal_function.

8
NEWS
View File

@ -1,4 +1,4 @@
GNU C Library NEWS -- history of user-visible changes. 2003-3-15
GNU C Library NEWS -- history of user-visible changes. 2003-4-24
Copyright (C) 1992-2002,2003 Free Software Foundation, Inc.
See the end for copying conditions.
@ -12,6 +12,12 @@ Version 2.3.3
* ELF thread-local storage support (TLS) now works on PowerPC and PowerPC64;
implemented by Paul Mackerras, Steven Munroe, and Roland McGrath.
* getifaddrs new uses on Linux the netlink interface to get the information.
Implemented by Thorsten Kukuk.
* getaddrinfo now implements AI_V4MAPPED, AI_ALL, and AI_ADDRCONF.
Implemented by Ulrich Drepper.
Version 2.3.2

344
configure vendored
View File

@ -312,7 +312,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi subdirs force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os base_machine sysnames INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF CCVERSION SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO OLD_DEBIAN_INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_initfinit_array libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_Bgroup libc_cv_z_combreloc libc_cv_have_initfini libc_cv_cpp_asm_debuginfo no_whole_archive exceptions LIBGD EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir use_ldconfig ldd_rewrite_script gnu_ld gnu_as elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES linux_doors mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS with_fp with_cvs enable_check_abi oldest_abi subdirs force_install all_warnings build build_cpu build_vendor build_os host host_cpu host_vendor host_os base_machine sysnames INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LN_S CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC OBJEXT BUILD_CC cross_compiling CPP CXX CXXFLAGS ac_ct_CXX AR OBJDUMP RANLIB ac_ct_RANLIB MIG AS LD PWD_P MAKE MSGFMT MAKEINFO SED AUTOCONF CCVERSION SYSINCLUDES libc_cv_gcc_static_libgcc BASH libc_cv_have_bash2 KSH libc_cv_have_ksh AWK PERL INSTALL_INFO OLD_DEBIAN_INSTALL_INFO BISON VERSIONING libc_cv_asm_protected_directive libc_cv_initfinit_array libc_cv_z_nodelete libc_cv_z_nodlopen libc_cv_z_initfirst libc_cv_Bgroup libc_cv_z_combreloc libc_cv_have_initfini libc_cv_cpp_asm_debuginfo no_whole_archive exceptions LIBGD EGREP sizeof_long_double libc_cv_gcc_unwind_find_fde uname_sysname uname_release uname_version old_glibc_headers libc_cv_slibdir libc_cv_localedir libc_cv_sysconfdir libc_cv_rootsbindir use_ldconfig ldd_rewrite_script gnu_ld gnu_as elf xcoff static shared pic_default profile omitfp bounded static_nss nopic_initfini DEFINES linux_doors mach_interface_list VERSION RELEASE LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@ -773,6 +773,14 @@ ac_env_CPP_set=${CPP+set}
ac_env_CPP_value=$CPP
ac_cv_env_CPP_set=${CPP+set}
ac_cv_env_CPP_value=$CPP
ac_env_CXX_set=${CXX+set}
ac_env_CXX_value=$CXX
ac_cv_env_CXX_set=${CXX+set}
ac_cv_env_CXX_value=$CXX
ac_env_CXXFLAGS_set=${CXXFLAGS+set}
ac_env_CXXFLAGS_value=$CXXFLAGS
ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
ac_cv_env_CXXFLAGS_value=$CXXFLAGS
#
# Report the --help message.
@ -901,6 +909,8 @@ Some influential environment variables:
CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
headers in a nonstandard directory <include dir>
CPP C preprocessor
CXX C++ compiler command
CXXFLAGS C++ compiler flags
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
@ -3200,6 +3210,327 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
# We need the C++ compiler only for testing.
ac_ext=cc
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
if test -n "$ac_tool_prefix"; then
for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CXX+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CXX"; then
ac_cv_prog_CXX="$CXX" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
CXX=$ac_cv_prog_CXX
if test -n "$CXX"; then
echo "$as_me:$LINENO: result: $CXX" >&5
echo "${ECHO_T}$CXX" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
test -n "$CXX" && break
done
fi
if test -z "$CXX"; then
ac_ct_CXX=$CXX
for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$ac_ct_CXX"; then
ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CXX="$ac_prog"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
if test -n "$ac_ct_CXX"; then
echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
echo "${ECHO_T}$ac_ct_CXX" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
test -n "$ac_ct_CXX" && break
done
test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
CXX=$ac_ct_CXX
fi
# Provide some information about the compiler.
echo "$as_me:$LINENO:" \
"checking for C++ compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
(eval $ac_compiler --version </dev/null >&5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
(eval $ac_compiler -v </dev/null >&5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
(eval $ac_compiler -V </dev/null >&5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5
echo $ECHO_N "checking whether we are using the GNU C++ compiler... $ECHO_C" >&6
if test "${ac_cv_cxx_compiler_gnu+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
#ifndef __GNUC__
choke me
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_compiler_gnu=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_compiler_gnu=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
fi
echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
GXX=`test $ac_compiler_gnu = yes && echo yes`
ac_test_CXXFLAGS=${CXXFLAGS+set}
ac_save_CXXFLAGS=$CXXFLAGS
CXXFLAGS="-g"
echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
if test "${ac_cv_prog_cxx_g+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_prog_cxx_g=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_prog_cxx_g=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
if test "$ac_test_CXXFLAGS" = set; then
CXXFLAGS=$ac_save_CXXFLAGS
elif test $ac_cv_prog_cxx_g = yes; then
if test "$GXX" = yes; then
CXXFLAGS="-g -O2"
else
CXXFLAGS="-g"
fi
else
if test "$GXX" = yes; then
CXXFLAGS="-O2"
else
CXXFLAGS=
fi
fi
for ac_declaration in \
''\
'#include <stdlib.h>' \
'extern "C" void std::exit (int) throw (); using std::exit;' \
'extern "C" void std::exit (int); using std::exit;' \
'extern "C" void exit (int) throw ();' \
'extern "C" void exit (int);' \
'void exit (int);'
do
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdlib.h>
$ac_declaration
int
main ()
{
exit (42);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
:
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
continue
fi
rm -f conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_declaration
int
main ()
{
exit (42);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
break
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest.$ac_ext
done
rm -f conftest*
if test -n "$ac_declaration"; then
echo '#ifdef __cplusplus' >>confdefs.h
echo $ac_declaration >>confdefs.h
echo '#endif' >>confdefs.h
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
# Was a --with-binutils option given?
if test -n "$path_binutils"; then
# Make absolute; ensure a single trailing slash.
@ -5203,7 +5534,7 @@ if test "${libc_cv_asm_underscores+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.$ac_ext <<EOF
#line 5206 "configure"
#line 5537 "configure"
#include "confdefs.h"
void underscore_test(void) {
return; }
@ -5529,7 +5860,7 @@ if test "${libc_cv_gcc_dwarf2_unwind_info+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.c <<EOF
#line 5532 "configure"
#line 5863 "configure"
static char *__EH_FRAME_BEGIN__;
_start ()
{
@ -5625,7 +5956,7 @@ if test "${libc_cv_gcc_builtin_expect+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.c <<EOF
#line 5628 "configure"
#line 5959 "configure"
int foo (int a)
{
a = __builtin_expect (a, 10);
@ -5693,7 +6024,7 @@ if test "${libc_cv_gcc_subtract_local_labels+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat > conftest.c <<EOF
#line 5696 "configure"
#line 6027 "configure"
int foo (int a)
{
static const int ar[] = { &&l1 - &&l1, &&l2 - &&l1 };
@ -7336,6 +7667,9 @@ s,@OBJEXT@,$OBJEXT,;t t
s,@BUILD_CC@,$BUILD_CC,;t t
s,@cross_compiling@,$cross_compiling,;t t
s,@CPP@,$CPP,;t t
s,@CXX@,$CXX,;t t
s,@CXXFLAGS@,$CXXFLAGS,;t t
s,@ac_ct_CXX@,$ac_ct_CXX,;t t
s,@AR@,$AR,;t t
s,@OBJDUMP@,$OBJDUMP,;t t
s,@RANLIB@,$RANLIB,;t t

View File

@ -181,13 +181,9 @@ extern int ruserpass (const char *host, const char **aname,
libc_hidden_proto (ruserpass)
/* The following declarations and definitions have been removed from
the public header since we don't want people to use them. */
/* The following definition has been removed from the public header
since we don't want people to use them. */
#define AI_V4MAPPED 0x0008 /* IPv4-mapped addresses are acceptable. */
#define AI_ALL 0x0010 /* Return both IPv4 and IPv6 addresses. */
#define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose
returned address type. */
#define AI_DEFAULT (AI_V4MAPPED | AI_ADDRCONFIG)
#include <inet/netgroup.h>

View File

@ -569,6 +569,10 @@ struct gaicb
# define AI_PASSIVE 0x0001 /* Socket address is intended for `bind'. */
# define AI_CANONNAME 0x0002 /* Request for canonical name. */
# define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */
# define AI_V4MAPPED 0x0008 /* IPv4 mapped addresses are acceptable. */
# define AI_ALL 0x0010 /* Return IPv4 mapped and IPv6 addresses. */
# define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose
returned address type.. */
/* Error values for `getaddrinfo' function. */
# define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */

View File

@ -1,5 +1,5 @@
/* getifaddrs -- get names and addresses of all network interfaces
Copyright (C) 2002 Free Software Foundation, Inc.
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -151,9 +151,13 @@ getifaddrs (struct ifaddrs **ifap)
return 0;
}
#ifndef getifaddrs
libc_hidden_def (getifaddrs)
#endif
void
freeifaddrs (struct ifaddrs *ifa)
{
free (ifa);
}
libc_hidden_def (freeifaddrs)

View File

@ -37,6 +37,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assert.h>
#include <errno.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
@ -111,12 +112,17 @@ struct gaih
const struct addrinfo *req, struct addrinfo **pai);
};
#if PF_UNSPEC == 0
static const struct addrinfo default_hints;
#else
static const struct addrinfo default_hints =
{ 0, PF_UNSPEC, 0, 0, 0, NULL, NULL, NULL };
#endif
{
.ai_flags = AI_DEFAULT,
.ai_family = PF_UNSPEC,
.ai_socktype = 0,
.ai_protocol = 0,
.ai_addrlen = 0,
.ai_addr = NULL,
.ai_canonname = NULL,
.ai_next = NULL
};
#if 0
@ -265,93 +271,137 @@ gaih_inet_serv (const char *servicename, const struct gaih_typeproto *tp,
return 0;
}
#define gethosts(_family, _type) \
{ \
int i, herrno; \
size_t tmpbuflen; \
struct hostent th; \
char *tmpbuf = NULL; \
tmpbuflen = 512; \
no_data = 0; \
do { \
tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
rc = __gethostbyname2_r (name, _family, &th, tmpbuf, \
tmpbuflen, &h, &herrno); \
} while (rc == ERANGE && herrno == NETDB_INTERNAL); \
if (rc != 0) \
{ \
if (herrno == NETDB_INTERNAL) \
{ \
__set_h_errno (herrno); \
return -EAI_SYSTEM; \
} \
if (herrno == TRY_AGAIN) \
no_data = EAI_AGAIN; \
else \
no_data = herrno == NO_DATA; \
} \
else if (h != NULL) \
{ \
for (i = 0; h->h_addr_list[i]; i++) \
{ \
if (*pat == NULL) { \
*pat = __alloca (sizeof (struct gaih_addrtuple)); \
(*pat)->scopeid = 0; \
} \
(*pat)->next = NULL; \
(*pat)->family = _family; \
memcpy ((*pat)->addr, h->h_addr_list[i], \
sizeof(_type)); \
pat = &((*pat)->next); \
} \
} \
#define gethosts(_family, _type) \
{ \
int i, herrno; \
size_t tmpbuflen; \
struct hostent th; \
char *tmpbuf = NULL; \
tmpbuflen = 512; \
no_data = 0; \
do { \
tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
rc = __gethostbyname2_r (name, _family, &th, tmpbuf, \
tmpbuflen, &h, &herrno); \
} while (rc == ERANGE && herrno == NETDB_INTERNAL); \
if (rc != 0) \
{ \
if (herrno == NETDB_INTERNAL) \
{ \
__set_h_errno (herrno); \
return -EAI_SYSTEM; \
} \
if (herrno == TRY_AGAIN) \
no_data = EAI_AGAIN; \
else \
no_data = herrno == NO_DATA; \
} \
else if (h != NULL) \
{ \
for (i = 0; h->h_addr_list[i]; i++) \
{ \
if (*pat == NULL) { \
*pat = __alloca (sizeof (struct gaih_addrtuple)); \
(*pat)->scopeid = 0; \
} \
(*pat)->next = NULL; \
(*pat)->family = _family; \
memcpy ((*pat)->addr, h->h_addr_list[i], \
sizeof(_type)); \
pat = &((*pat)->next); \
} \
if (_family == AF_INET6) \
got_ipv6 = true; \
} \
else if (_family == AF_INET6 && (req->ai_flags & AI_V4MAPPED)) \
{ \
/* We have to add V4 mapped addresses. Maybe we discard them \
later again but we get them anyhow for now. */ \
while ((rc = __gethostbyname2_r (name, AF_INET6, &th, tmpbuf, \
tmpbuflen, &h, &herrno)) == ERANGE \
&& herrno == NETDB_INTERNAL) \
tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
\
if (rc != 0) \
{ \
if (herrno == NETDB_INTERNAL) \
{ \
__set_h_errno (herrno); \
return -EAI_SYSTEM; \
} \
if (herrno == TRY_AGAIN) \
no_data = EAI_AGAIN; \
else \
no_data = herrno == NO_DATA; \
} \
else if (h != NULL) \
{ \
for (i = 0; h->h_addr_list[i]; ++i) \
{ \
if (*pat == NULL) \
{ \
*pat = __alloca (sizeof (struct gaih_addrtuple)); \
(*pat)->scopeid = 0; \
} \
uint32_t *addr = (uint32_t *) (*pat)->addr; \
(*pat)->next = NULL; \
(*pat)->family = _family; \
addr[3] = *(uint32_t *) h->h_addr_list[i]; \
addr[2] = htonl (0xffff); \
addr[1] = 0; \
addr[0] = 0; \
pat = &((*pat)->next); \
} \
} \
} \
}
#define gethosts2(_family, _type) \
{ \
int i, herrno; \
size_t tmpbuflen; \
struct hostent th; \
char *tmpbuf = NULL; \
tmpbuflen = 512; \
no_data = 0; \
do { \
tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
rc = 0; \
status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, \
tmpbuflen, &rc, &herrno)); \
} while (rc == ERANGE && herrno == NETDB_INTERNAL); \
if (status == NSS_STATUS_SUCCESS && rc == 0) \
h = &th; \
else \
h = NULL; \
if (rc != 0) \
{ \
if (herrno == NETDB_INTERNAL) \
{ \
__set_h_errno (herrno); \
return -EAI_SYSTEM; \
} \
if (herrno == TRY_AGAIN) \
no_data = EAI_AGAIN; \
else \
no_data = herrno == NO_DATA; \
} \
else if (h != NULL) \
{ \
for (i = 0; h->h_addr_list[i]; i++) \
{ \
if (*pat == NULL) { \
*pat = __alloca (sizeof (struct gaih_addrtuple)); \
(*pat)->scopeid = 0; \
} \
(*pat)->next = NULL; \
(*pat)->family = _family; \
memcpy ((*pat)->addr, h->h_addr_list[i], \
sizeof(_type)); \
pat = &((*pat)->next); \
} \
} \
#define gethosts2(_family, _type) \
{ \
int i, herrno; \
size_t tmpbuflen; \
struct hostent th; \
char *tmpbuf = NULL; \
tmpbuflen = 512; \
no_data = 0; \
do { \
tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); \
rc = 0; \
status = DL_CALL_FCT (fct, (name, _family, &th, tmpbuf, \
tmpbuflen, &rc, &herrno)); \
} while (rc == ERANGE && herrno == NETDB_INTERNAL); \
if (status == NSS_STATUS_SUCCESS && rc == 0) \
h = &th; \
else \
h = NULL; \
if (rc != 0) \
{ \
if (herrno == NETDB_INTERNAL) \
{ \
__set_h_errno (herrno); \
return -EAI_SYSTEM; \
} \
if (herrno == TRY_AGAIN) \
no_data = EAI_AGAIN; \
else \
no_data = herrno == NO_DATA; \
} \
else if (h != NULL) \
{ \
for (i = 0; h->h_addr_list[i]; i++) \
{ \
if (*pat == NULL) { \
*pat = __alloca (sizeof (struct gaih_addrtuple)); \
(*pat)->scopeid = 0; \
} \
(*pat)->next = NULL; \
(*pat)->family = _family; \
memcpy ((*pat)->addr, h->h_addr_list[i], \
sizeof(_type)); \
pat = &((*pat)->next); \
} \
} \
}
typedef enum nss_status (*nss_gethostbyname2_r)
@ -368,6 +418,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
struct gaih_servtuple *st = (struct gaih_servtuple *) &nullserv;
struct gaih_addrtuple *at = NULL;
int rc;
bool got_ipv6 = false;
if (req->ai_protocol || req->ai_socktype)
{
@ -490,6 +541,13 @@ gaih_inet (const char *name, const struct gaih_service *service,
{
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET)
at->family = AF_INET;
else if (req->ai_flags & AI_V4MAPPED)
{
((uint32_t *) at->addr)[3] = *(uint32_t *) at->addr;
((uint32_t *) at->addr)[2] = htonl (0xffff);
((uint32_t *) at->addr)[1] = 0;
((uint32_t *) at->addr)[0] = 0;
}
else
return -EAI_ADDRFAMILY;
}
@ -507,6 +565,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
{
if (req->ai_family == AF_UNSPEC || req->ai_family == AF_INET6)
at->family = AF_INET6;
else if (IN6_IS_ADDR_V4MAPPED (at->addr))
*(uint32_t *) at->addr = ((uint32_t *) at->addr)[3];
else
return -EAI_ADDRFAMILY;
@ -747,6 +807,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
{
family = AF_INET6;
socklen = sizeof (struct sockaddr_in6);
/* If we looked up IPv4 mapped address discard them here if
the caller isn't interested in all address and we have
found at least one IPv6 address. */
if (! got_ipv6
&& (req->ai_flags & (AI_V4MAPPED|AI_ALL)) == AI_V4MAPPED
&& IN6_IS_ADDR_V4MAPPED (at2->addr))
goto ignore;
}
else
{
@ -765,7 +833,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
(*pai)->ai_socktype = st2->socktype;
(*pai)->ai_protocol = st2->protocol;
(*pai)->ai_addrlen = socklen;
(*pai)->ai_addr = (void *) (*pai) + sizeof(struct addrinfo);
(*pai)->ai_addr = (void *) (*pai) + sizeof (struct addrinfo);
#if SALEN
(*pai)->ai_addr->sa_len = socklen;
#endif /* SALEN */
@ -805,6 +873,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
pai = &((*pai)->ai_next);
}
ignore:
at2 = at2->next;
}
}
@ -829,6 +898,7 @@ getaddrinfo (const char *name, const char *service,
struct addrinfo *p = NULL, **end;
struct gaih *g = gaih, *pg = NULL;
struct gaih_service gaih_service, *pservice;
struct addrinfo local_hints;
if (name != NULL && name[0] == '*' && name[1] == 0)
name = NULL;
@ -842,12 +912,62 @@ getaddrinfo (const char *name, const char *service,
if (hints == NULL)
hints = &default_hints;
if (hints->ai_flags & ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST))
if (hints->ai_flags
& ~(AI_PASSIVE|AI_CANONNAME|AI_NUMERICHOST|AI_ADDRCONFIG|AI_V4MAPPED
|AI_ALL))
return EAI_BADFLAGS;
if ((hints->ai_flags & AI_CANONNAME) && name == NULL)
return EAI_BADFLAGS;
if (hints->ai_flags & AI_ADDRCONFIG)
{
/* Determine whether we have IPv4 or IPv6 interfaces or both.
We cannot cache the results since new interfaces could be
added at any time.
XXX We are using getifaddrs here which is more costly than
it is really necessary. Once things are stable we will have
a special function which performs the task with less overhead. */
struct ifaddrs* ifa = NULL;
if (getifaddrs (&ifa) != 0)
/* Cannot get the interface list, very bad. */
return EAI_SYSTEM;
bool seen_ipv4 = false;
bool seen_ipv6 = false;
while (ifa != NULL)
{
if (ifa->ifa_addr->sa_family == PF_INET)
seen_ipv4 = true;
else if (ifa->ifa_addr->sa_family == PF_INET6)
seen_ipv6 = true;
ifa = ifa->ifa_next;
}
(void) freeifaddrs (ifa);
/* Now make a decision on what we return, if anything. */
if (hints->ai_family == PF_UNSPEC)
{
/* If we haven't seen both IPv4 and IPv6 interfaces we can
narrow down the search. */
if (! seen_ipv4 || ! seen_ipv6)
{
local_hints = *hints;
local_hints.ai_family = seen_ipv4 ? PF_INET : PF_INET6;
hints = &local_hints;
}
}
else if ((hints->ai_family == PF_INET && ! seen_ipv4)
|| (hints->ai_family == PF_INET6 && ! seen_ipv6))
/* We cannot possibly return a valid answer. */
return EAI_NONAME;
}
if (service && service[0])
{
char *c;

View File

@ -796,6 +796,7 @@ getifaddrs (struct ifaddrs **ifap)
return result;
}
libc_hidden_def (getifaddrs)
#if __ASSUME_NETLINK_SUPPORT != 0
@ -804,4 +805,5 @@ freeifaddrs (struct ifaddrs *ifa)
{
free (ifa);
}
libc_hidden_def (freeifaddrs)
#endif