diff --git a/ares/CHANGES b/ares/CHANGES index eb38613c1..858804065 100644 --- a/ares/CHANGES +++ b/ares/CHANGES @@ -1,5 +1,10 @@ Changelog for the c-ares project +* May 16 + +- Added ares_getnameinfo which mimics the getnameinfo API (another feature + that could use testing). + * May 14 - Added an inet_ntop function from BIND for systems that do not have it. diff --git a/ares/Makefile.inc b/ares/Makefile.inc index 121fa6bb7..80ad621e4 100644 --- a/ares/Makefile.inc +++ b/ares/Makefile.inc @@ -1,17 +1,18 @@ -CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \ -ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \ -ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c \ -ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \ -ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \ -windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \ -ares_parse_aaaa_reply.c inet_net_pton.c bitncmp.c inet_ntop.c +CSOURCES = ares_fds.c ares_process.c ares_free_hostent.c ares_query.c \ +ares__close_sockets.c ares_free_string.c ares_search.c ares__get_hostent.c \ +ares_gethostbyaddr.c ares_send.c ares__read_line.c ares_gethostbyname.c \ +ares_strerror.c ares_cancel.c ares_init.c ares_timeout.c ares_destroy.c \ +ares_mkquery.c ares_version.c ares_expand_name.c ares_parse_a_reply.c \ +windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \ +ares_parse_aaaa_reply.c ares_getnameinfo.c inet_net_pton.c bitncmp.c \ +inet_ntop.c -HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h \ - inet_net_pton.h ares_ipv6.h bitncmp.h +HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h \ + nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h MANPAGES= ares_destroy.3 ares_expand_name.3 ares_expand_string.3 ares_fds.3 \ ares_free_hostent.3 ares_free_string.3 ares_gethostbyaddr.3 \ ares_gethostbyname.3 ares_init.3 ares_init_options.3 ares_mkquery.3 \ ares_parse_a_reply.3 ares_parse_ptr_reply.3 ares_process.3 \ ares_query.3 ares_search.3 ares_send.3 ares_strerror.3 ares_timeout.3 \ - ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 + ares_version.3 ares_cancel.3 ares_parse_aaaa_reply.3 ares_getnameinfo.3 diff --git a/ares/acinclude.m4 b/ares/acinclude.m4 index 2d4aa918f..1b197f0a0 100644 --- a/ares/acinclude.m4 +++ b/ares/acinclude.m4 @@ -1,148 +1,168 @@ - -dnl We create a function for detecting which compiler we use and then set as -dnl pendantic compiler options as possible for that particular compiler. The -dnl options are only used for debug-builds. - -dnl This is a copy of the original found in curl's configure script. Don't -dnl modify this one, edit the one in curl and copy it back here when that one -dnl is changed. - -AC_DEFUN([CURL_CC_DEBUG_OPTS], -[ - if test "$GCC" = "yes"; then - - dnl figure out gcc version! - AC_MSG_CHECKING([gcc version]) - gccver=`$CC -dumpversion` - num1=`echo $gccver | cut -d . -f1` - num2=`echo $gccver | cut -d . -f2` - gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null` - AC_MSG_RESULT($gccver) - - AC_MSG_CHECKING([if this is icc in disguise]) - AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER], - dnl action if the text is found, this it has not been replaced by the - dnl cpp - ICC="no" - AC_MSG_RESULT([no]), - dnl the text was not found, it was replaced by the cpp - ICC="yes" - AC_MSG_RESULT([yes]) - ) - - if test "$ICC" = "yes"; then - dnl this is icc, not gcc. - - dnl ICC warnings we ignore: - dnl * 279 warns on static conditions in while expressions - dnl * 269 warns on our "%Od" printf formatters for curl_off_t output: - dnl "invalid format string conversion" - - WARN="-wd279,269" - - if test "$gccnum" -gt "600"; then - dnl icc 6.0 and older doesn't have the -Wall flag - WARN="-Wall $WARN" - fi - else dnl $ICC = yes - dnl - WARN="-W -Wall -Wwrite-strings -pedantic -Wno-long-long -Wundef -Wpointer-arith -Wnested-externs -Winline -Wmissing-declarations -Wmissing-prototypes -Wsign-compare" - - dnl -Wcast-align is a bit too annoying ;-) - - if test "$gccnum" -ge "296"; then - dnl gcc 2.96 or later - WARN="$WARN -Wfloat-equal" - - if test "$gccnum" -gt "296"; then - dnl this option does not exist in 2.96 - WARN="$WARN -Wno-format-nonliteral" - fi - - dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on - dnl on i686-Linux as it gives us heaps with false positives - if test "$gccnum" -ge "303"; then - dnl gcc 3.3 and later - WARN="$WARN -Wendif-labels -Wstrict-prototypes" - fi - fi - - for flag in $CPPFLAGS; do - case "$flag" in - -I*) - dnl include path - add=`echo $flag | sed 's/^-I/-isystem /g'` - WARN="$WARN $add" - ;; - esac - done - - fi dnl $ICC = no - - CFLAGS="$CFLAGS $WARN" - - fi dnl $GCC = yes - - dnl strip off optimizer flags - NEWFLAGS="" - for flag in $CFLAGS; do - case "$flag" in - -O*) - dnl echo "cut off $flag" - ;; - *) - NEWFLAGS="$NEWFLAGS $flag" - ;; - esac - done - CFLAGS=$NEWFLAGS - -]) dnl end of AC_DEFUN() - - -dnl This macro determines if the specified struct exists in the specified file -dnl Syntax: -dnl CARES_CHECK_STRUCT(headers, struct name, if found, [if not found]) - -AC_DEFUN([CARES_CHECK_STRUCT], [ - AC_MSG_CHECKING([for struct $2]) - AC_TRY_COMPILE([$1], - [ - struct $2 struct_instance; - ], ac_struct="yes", ac_found="no") - if test "$ac_struct" = "yes" ; then - AC_MSG_RESULT(yes) - $3 - else - AC_MSG_RESULT(no) - $4 - fi -]) - -dnl This macro determines if the specified constant exists in the specified file -dnl Syntax: -dnl CARES_CHECK_CONSTANT(headers, constant name, if found, [if not found]) - -AC_DEFUN([CARES_CHECK_CONSTANT], [ - AC_MSG_CHECKING([for $2]) - AC_EGREP_CPP(VARIABLEWASDEFINED, - [ - $1 - - #ifdef $2 - VARIABLEWASDEFINED - #else - NJET - #endif - ], ac_constant="yes", ac_constant="no" - ) - if test "$ac_constant" = "yes" ; then - AC_MSG_RESULT(yes) - $3 - else - AC_MSG_RESULT(no) - $4 - fi -]) - - + +dnl We create a function for detecting which compiler we use and then set as +dnl pendantic compiler options as possible for that particular compiler. The +dnl options are only used for debug-builds. + +dnl This is a copy of the original found in curl's configure script. Don't +dnl modify this one, edit the one in curl and copy it back here when that one +dnl is changed. + +AC_DEFUN([CURL_CC_DEBUG_OPTS], +[ + if test "$GCC" = "yes"; then + + dnl figure out gcc version! + AC_MSG_CHECKING([gcc version]) + gccver=`$CC -dumpversion` + num1=`echo $gccver | cut -d . -f1` + num2=`echo $gccver | cut -d . -f2` + gccnum=`(expr $num1 "*" 100 + $num2) 2>/dev/null` + AC_MSG_RESULT($gccver) + + AC_MSG_CHECKING([if this is icc in disguise]) + AC_EGREP_CPP([^__INTEL_COMPILER], [__INTEL_COMPILER], + dnl action if the text is found, this it has not been replaced by the + dnl cpp + ICC="no" + AC_MSG_RESULT([no]), + dnl the text was not found, it was replaced by the cpp + ICC="yes" + AC_MSG_RESULT([yes]) + ) + + if test "$ICC" = "yes"; then + dnl this is icc, not gcc. + + dnl ICC warnings we ignore: + dnl * 279 warns on static conditions in while expressions + dnl * 269 warns on our "%Od" printf formatters for curl_off_t output: + dnl "invalid format string conversion" + + WARN="-wd279,269" + + if test "$gccnum" -gt "600"; then + dnl icc 6.0 and older doesn't have the -Wall flag + WARN="-Wall $WARN" + fi + else dnl $ICC = yes + dnl + WARN="-W -Wall -Wwrite-strings -pedantic -Wno-long-long -Wundef -Wpointer-arith -Wnested-externs -Winline -Wmissing-declarations -Wmissing-prototypes -Wsign-compare" + + dnl -Wcast-align is a bit too annoying ;-) + + if test "$gccnum" -ge "296"; then + dnl gcc 2.96 or later + WARN="$WARN -Wfloat-equal" + + if test "$gccnum" -gt "296"; then + dnl this option does not exist in 2.96 + WARN="$WARN -Wno-format-nonliteral" + fi + + dnl -Wunreachable-code seems totally unreliable on my gcc 3.3.2 on + dnl on i686-Linux as it gives us heaps with false positives + if test "$gccnum" -ge "303"; then + dnl gcc 3.3 and later + WARN="$WARN -Wendif-labels -Wstrict-prototypes" + fi + fi + + for flag in $CPPFLAGS; do + case "$flag" in + -I*) + dnl include path + add=`echo $flag | sed 's/^-I/-isystem /g'` + WARN="$WARN $add" + ;; + esac + done + + fi dnl $ICC = no + + CFLAGS="$CFLAGS $WARN" + + fi dnl $GCC = yes + + dnl strip off optimizer flags + NEWFLAGS="" + for flag in $CFLAGS; do + case "$flag" in + -O*) + dnl echo "cut off $flag" + ;; + *) + NEWFLAGS="$NEWFLAGS $flag" + ;; + esac + done + CFLAGS=$NEWFLAGS + +]) dnl end of AC_DEFUN() + + +dnl This macro determines if the specified struct exists in the specified file +dnl Syntax: +dnl CARES_CHECK_STRUCT(headers, struct name, if found, [if not found]) + +AC_DEFUN([CARES_CHECK_STRUCT], [ + AC_MSG_CHECKING([for struct $2]) + AC_TRY_COMPILE([$1], + [ + struct $2 struct_instance; + ], ac_struct="yes", ac_found="no") + if test "$ac_struct" = "yes" ; then + AC_MSG_RESULT(yes) + $3 + else + AC_MSG_RESULT(no) + $4 + fi +]) + +dnl This macro determins if the specified struct contains a specific member. +dnl Syntax: +dnl CARES_CHECK_STRUCT_MEMBER(headers, struct name, member name, if found, [if not found]) + +AC_DEFUN([CARES_CHECK_STRUCT_MEMBER], [ + AC_MSG_CHECKING([if struct $2 has member $3]) + AC_TRY_COMPILE([$1], + [ + struct $2 struct_instance; + struct_instance.$3 = 0; + ], ac_struct="yes", ac_found="no") + if test "$ac_struct" = "yes" ; then + AC_MSG_RESULT(yes) + $4 + else + AC_MSG_RESULT(no) + $5 + fi +]) + +dnl This macro determines if the specified constant exists in the specified file +dnl Syntax: +dnl CARES_CHECK_CONSTANT(headers, constant name, if found, [if not found]) + +AC_DEFUN([CARES_CHECK_CONSTANT], [ + AC_MSG_CHECKING([for $2]) + AC_EGREP_CPP(VARIABLEWASDEFINED, + [ + $1 + + #ifdef $2 + VARIABLEWASDEFINED + #else + NJET + #endif + ], ac_constant="yes", ac_constant="no" + ) + if test "$ac_constant" = "yes" ; then + AC_MSG_RESULT(yes) + $3 + else + AC_MSG_RESULT(no) + $4 + fi +]) + + diff --git a/ares/ares.h b/ares/ares.h index d032de434..01a6b8ac3 100644 --- a/ares/ares.h +++ b/ares/ares.h @@ -29,12 +29,14 @@ #if defined(WATT32) #include + #include #include #elif defined(WIN32) #include #include #else #include + #include #endif #ifdef __cplusplus @@ -64,6 +66,9 @@ extern "C" { #define ARES_EDESTRUCTION 16 #define ARES_EBADSTR 17 +/* ares_getnameinfo error codes */ +#define ARES_EBADFLAGS 18 + /* Flag values */ #define ARES_FLAG_USEVC (1 << 0) #define ARES_FLAG_PRIMARY (1 << 1) @@ -85,6 +90,24 @@ extern "C" { #define ARES_OPT_DOMAINS (1 << 7) #define ARES_OPT_LOOKUPS (1 << 8) +/* Nameinfo flag values */ +#define ARES_NI_NOFQDN (1 << 0) +#define ARES_NI_NUMERICHOST (1 << 1) +#define ARES_NI_NAMEREQD (1 << 2) +#define ARES_NI_NUMERICSERV (1 << 3) +#define ARES_NI_DGRAM (1 << 4) +#define ARES_NI_TCP 0 +#define ARES_NI_UDP ARES_NI_DGRAM +#define ARES_NI_SCTP (1 << 5) +#define ARES_NI_DCCP (1 << 6) +#define ARES_NI_NUMERICSCOPE (1 << 7) +#define ARES_NI_LOOKUPHOST (1 << 8) +#define ARES_NI_LOOKUPSERVICE (1 << 9) +/* Reserved for future use */ +#define ARES_NI_IDN (1 << 10) +#define ARES_NI_ALLOW_UNASSIGNED (1 << 11) +#define ARES_NI_USE_STD3_ASCII_RULES (1 << 12) + struct ares_options { int flags; int timeout; @@ -101,12 +124,15 @@ struct ares_options { struct hostent; struct timeval; +struct sockaddr; struct ares_channeldata; typedef struct ares_channeldata *ares_channel; typedef void (*ares_callback)(void *arg, int status, unsigned char *abuf, int alen); typedef void (*ares_host_callback)(void *arg, int status, struct hostent *hostent); +typedef void (*ares_nameinfo_callback)(void *arg, int status, + char *node, char *service); int ares_init(ares_channel *channelptr); int ares_init_options(ares_channel *channelptr, struct ares_options *options, @@ -123,7 +149,9 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family, ares_host_callback callback, void *arg); void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, int family, ares_host_callback callback, void *arg); - +void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, + socklen_t salen, int flags, ares_nameinfo_callback callback, + void *arg); int ares_fds(ares_channel channel, fd_set *read_fds, fd_set *write_fds); struct timeval *ares_timeout(ares_channel channel, struct timeval *maxtv, struct timeval *tv); diff --git a/ares/ares_getnameinfo.3 b/ares/ares_getnameinfo.3 new file mode 100644 index 000000000..9b6bd73a9 --- /dev/null +++ b/ares/ares_getnameinfo.3 @@ -0,0 +1,145 @@ +.\" $Id$ +.\" +.\" Copyright 2005 by Dominick Meglio. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_GETNAMEINFO 3 "16 May 2005" +.SH NAME +ares_getnameinfo \- Address-to-nodename translation in protocol-independent manner +.SH SYNOPSIS +.nf +.B #include +.PP +.B typedef void (*ares_nameinfo_callback)(void *\fIarg\fP, int \fIstatus\fP, +.B char *\fInode\fP, char *\fIservice\fP) +.PP +.B void ares_getnameinfo(ares_channel \fIchannel\fP, const struct sockaddr *\fIsa\fP, +.B socklen_t \fIsalen\fP, int \fIflags\fP, ares_nameinfo_callback \fIcallback\fP, +.B void *\fIarg\fP) +.fi +.SH DESCRIPTION +The +.B ares_getnameinfo +function is defined for protocol-independent address translation. The function +is a combination of \fIares_gethostbyaddr(3)\fP and \fIgetservbyport(3)\fP. The function will +translate the address either by executing a host query on the name service channel +identified by +.IR channel +or it will attempt to resolve it locally if possible. +The parameters +.I sa +and +.I len +give the address as a sockaddr structure, and +.I flags +gives the options that the function will use. Valid flags are listed below: +.TP 19 +.B ARES_NI_NOFQDN +Only the nodename portion of the FQDN is returned for local hosts. +.TP 19 +.B ARES_NI_NUMERICHOST +The numeric form of the hostname is returned rather than the name. +.TP 19 +.B ARES_NI_NAMEREQD +An error is returned if the hostname cannot be found in the DNS. +.TP 19 +.B ARES_NI_NUMERICSERV +The numeric form of the service is returned rather than the name. +.TP 19 +.B ARES_NI_TCP +The service name is to be looked up for the TCP protocol. +.TP 19 +.B ARES_NI_UDP +The service name is to be looked up for the UDP protocol. +.TP 19 +.B ARES_NI_SCTP +The service name is to be looked up for the SCTP protocol. +.TP 19 +.B ARES_NI_DCCP +The service name is to be looked up for the DCCP protocol. +.TP 19 +.B ARES_NI_NUMERICSCOPE +The numeric form of the scope ID is returned rather than the name. +.TP 19 +.B ARES_NI_LOOKUPHOST +A hostname lookup is being requested. +.TP 19 +.B ARES_NI_LOOKUPSERVICE +A service name lookup is being requested. +.PP +When the query +is complete or has +failed, the ares library will invoke \fIcallback\fP. Completion or failure of +the query may happen immediately, or may happen during a later call to +\fIares_process(3)\fP, \fIares_destroy(3)\fP or \fIares_cancel(3)\fP. +.PP +The callback argument +.I arg +is copied from the +.B ares_getnameinfo +argument +.IR arg . +The callback argument +.I status +indicates whether the query succeeded and, if not, how it failed. It +may have any of the following values: +.TP 19 +.B ARES_SUCCESS +The host lookup completed successfully. +.TP 19 +.B ARES_ENOTIMP +The ares library does not know how to look up addresses of type +.IR family . +.TP 19 +.B ARES_ENOTFOUND +The address +.I addr +was not found. +.TP 19 +.B ARES_ENOMEM +Memory was exhausted. +.TP 19 +.B ARES_EDESTRUCTION +The name service channel +.I channel +is being destroyed; the query will not be completed. +.TP 19 +.B ARES_EBADFLAGS +The +.I flags +parameter contains an illegal value. +.PP +On successful completion of the query, the callback argument +.I node +contains a string representing the hostname (assuming +.B ARES_NI_LOOKUPHOST +was specified). Additionally, +.I service +contains a string representing the service name (assuming +.B ARES_NI_LOOKUPSERVICE +was specified). +If the query did not complete successfully, or one of the values +was not requested, +.I node +or +.I service +will be +.BR NULL . +.SH SEE ALSO +.BR ares_process (3), +.BR ares_getaddrinfo (3) +.SH AUTHOR +Dominick Meglio +.br +Copyright 2005 by Dominick Meglio. diff --git a/ares/ares_getnameinfo.c b/ares/ares_getnameinfo.c new file mode 100644 index 000000000..955207a2e --- /dev/null +++ b/ares/ares_getnameinfo.c @@ -0,0 +1,322 @@ +/* Copyright 2005 by Dominick Meglio + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ +#include "setup.h" +#include + +#if defined(WIN32) && !defined(WATT32) +#include "nameser.h" +#else +#include +#include +#include +#include +#ifdef HAVE_ARPA_NAMESER_COMPAT_H +#include +#endif +#endif + +#ifdef HAVE_NET_IF_H +#include +#endif + +#include +#include +#include + +#include "ares.h" +#include "ares_private.h" +#include "ares_ipv6.h" +#include "inet_ntop.h" + +#ifdef WATT32 +#undef WIN32 +#endif + +struct nameinfo_query { + ares_nameinfo_callback callback; + void *arg; + union { + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; + } addr; + int family; + int flags; +}; + +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID +#define IPBUFSIZ 40+IF_NAMESIZE +#else +#define IPBUFSIZ 40 +#endif + +static void nameinfo_callback(void *arg, int status, struct hostent *host); +static char *lookup_service(unsigned short port, int flags, char *buf); +static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int scopeid, char *buf); +static char *ares_striendstr(const char *s1, const char *s2); + +void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, socklen_t salen, + int flags, ares_nameinfo_callback callback, void *arg) +{ + struct sockaddr_in *addr; + struct sockaddr_in6 *addr6; + struct nameinfo_query *niquery; + + /* Verify the buffer size */ + if (salen == sizeof(struct sockaddr_in)) + addr = (struct sockaddr_in *)sa; + else if (salen == sizeof(struct sockaddr_in6)) + addr6 = (struct sockaddr_in6 *)sa; + else + { + callback(arg, ARES_ENOTIMP, NULL, NULL); + return; + } + + /* If neither, assume they want a host */ + if (!(flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST)) + flags |= ARES_NI_LOOKUPHOST; + + /* All they want is a service, no need for DNS */ + if ((flags & ARES_NI_LOOKUPSERVICE) && !(flags & ARES_NI_LOOKUPHOST)) + { + char buf[33], *service; + unsigned int port = 0; + + if (salen == sizeof(struct sockaddr_in)) + port = addr->sin_port; + else + port = addr6->sin6_port; + service = lookup_service(port, flags, buf); + callback(arg, ARES_SUCCESS, NULL, service); + return; + } + + /* They want a host lookup */ + if ((flags & ARES_NI_LOOKUPHOST)) + { + /* A numeric host can be handled without DNS */ + if ((flags & ARES_NI_NUMERICHOST)) + { + unsigned int port = 0; + char ipbuf[IPBUFSIZ]; + char srvbuf[32]; + char *service = NULL; + ipbuf[0] = 0; + + /* Specifying not to lookup a host, but then saying a host + * is required has to be illegal. + */ + if (flags & ARES_NI_NAMEREQD) + { + callback(arg, ARES_EBADFLAGS, NULL, NULL); + return; + } + if (salen == sizeof(struct sockaddr_in6)) + { + ares_inet_ntop(AF_INET6, &addr6->sin6_addr, ipbuf, IPBUFSIZ); + port = addr6->sin6_port; + /* If the system supports scope IDs, use it */ +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + append_scopeid(addr6, flags, ipbuf); +#endif + } + else + { + ares_inet_ntop(AF_INET, &addr->sin_addr, ipbuf, IPBUFSIZ); + port = addr->sin_port; + } + /* They also want a service */ + if (flags & ARES_NI_LOOKUPSERVICE) + service = lookup_service(port, flags, srvbuf); + callback(arg, ARES_SUCCESS, ipbuf, service); + return; + } + /* This is where a DNS lookup becomes necessary */ + else + { + niquery = malloc(sizeof(struct nameinfo_query)); + if (!niquery) + { + callback(arg, ARES_ENOMEM, NULL, NULL); + return; + } + niquery->callback = callback; + niquery->arg = arg; + niquery->flags = flags; + if (sa->sa_family == AF_INET) + { + niquery->family = AF_INET; + memcpy(&niquery->addr.addr4, addr, sizeof(addr)); + ares_gethostbyaddr(channel, &addr->sin_addr, sizeof(struct in_addr), AF_INET, + nameinfo_callback, niquery); + } + else + { + niquery->family = AF_INET6; + memcpy(&niquery->addr.addr6, addr6, sizeof(addr6)); + ares_gethostbyaddr(channel, &addr6->sin6_addr, sizeof(struct in6_addr), AF_INET6, + nameinfo_callback, niquery); + } + } + } +} + +static void nameinfo_callback(void *arg, int status, struct hostent *host) +{ + struct nameinfo_query *niquery = (struct nameinfo_query *) arg; + char srvbuf[33]; + char *service = NULL; + + + if (status == ARES_SUCCESS) + { + /* They want a service too */ + if (niquery->flags & ARES_NI_LOOKUPSERVICE) + { + if (niquery->family == AF_INET) + service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, srvbuf); + else + service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, srvbuf); + } + /* NOFQDN means we have to strip off the domain name portion. + We do this by determining our own domain name, then searching the string + for this domain name and removing it. + */ + if (niquery->flags & ARES_NI_NOFQDN) + { + char buf[255]; + char *domain; + gethostname(buf, 255); + if ((domain = strchr(buf, '.'))) + { + char *end = ares_striendstr(host->h_name, domain); + if (end) + *end = 0; + } + } + callback(niquery->arg, ARES_SUCCESS, host->h_name, service); + return; + } + /* We couldn't find the host, but it's OK, we can use the IP */ + else if (status == ARES_ENOTFOUND && !(niquery->flags & ARES_NI_NAMEREQD)) + { + char ipbuf[IPBUFSIZ]; + if (niquery->family == AF_INET) + ares_inet_ntop(AF_INET, &niquery->addr.addr4.sin_addr, ipbuf, IPBUFSIZ); + else + { + ares_inet_ntop(AF_INET6, &niquery->addr.addr6.sin6_addr, ipbuf, IPBUFSIZ); +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + append_scopeid(&niquery->addr.addr6, niquery->flags, ipbuf); +#endif + } + /* They want a service too */ + if (niquery->flags & ARES_NI_LOOKUPSERVICE) + { + if (niquery->family == AF_INET) + service = lookup_service(niquery->addr.addr4.sin_port, niquery->flags, srvbuf); + else + service = lookup_service(niquery->addr.addr6.sin6_port, niquery->flags, srvbuf); + } + callback(niquery->arg, ARES_SUCCESS, ipbuf, service); + return; + } + callback(niquery->arg, status, NULL, NULL); + free(niquery); +} + +static char *lookup_service(unsigned short port, int flags, char *buf) +{ + if (port) + { + /* Just return the port as a string */ + if (flags & ARES_NI_NUMERICSERV) + sprintf(buf, "%u", ntohs(port)); + else + { + struct servent *se; + char *proto; + + if (flags & ARES_NI_UDP) + proto = "udp"; + else if (flags & ARES_NI_SCTP) + proto = "sctp"; + else if (flags & ARES_NI_DCCP) + proto = "dccp"; + else + proto = "tcp"; + se = getservbyport(port, proto); + if (se && se->s_name) + strcpy(buf, se->s_name); + else + sprintf(buf, "%u", ntohs(port)); + } + return buf; + } + return NULL; +} + +#ifdef HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID +static char *append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, char *buf) +{ + char tmpbuf[IF_NAMESIZE + 1]; + + tmpbuf[0] = '%'; +#ifdef HAVE_IF_INDEXTONAME + if ((flags & ARES_NI_NUMERICSCOPE) || (!IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr) + && !IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr))) + { + sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id); + } + else + { + if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL) + sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id); + } +#else + sprintf(&tmpbuf[1], "%u", addr6->sin6_scope_id); +#endif + strcat(buf, tmpbuf); + return buf; +} +#endif + +/* Determines if s1 ends with the string in s2 (case-insensitive) */ +static char *ares_striendstr(const char *s1, const char *s2) +{ + const char *c1, *c2, *c1_begin; + size_t s1_len = strlen(s1), s2_len = strlen(s2); + + /* If the substr is longer than the full str, it can't match */ + if (s2_len > s1_len) + return NULL; + + /* Jump to the end of s1 minus the length of s2 */ + c1 = (const char *)c1_begin = s1+s1_len-s2_len; + c2 = s2; + while (c2 < s2+s2_len) + { + if (tolower(*c1) != tolower(*c2)) + return NULL; + else + { + c1++; + c2++; + } + } + if (c2 == c1 == NULL) + return c1_begin; + return NULL; +} diff --git a/ares/ares_ipv6.h b/ares/ares_ipv6.h index 3a5bd0699..79a37c401 100644 --- a/ares/ares_ipv6.h +++ b/ares/ares_ipv6.h @@ -28,6 +28,17 @@ struct in6_addr }; #endif +#ifndef HAVE_STRUCT_SOCKADDR_IN6 +struct sockaddr_in6 +{ + unsigned short sin6_family; + unsigned short sin6_port; + unsigned long sin6_flowinfo; + struct in6_addr sin6_addr; + unsigned int sin6_scope_id; +}; +#endif + #ifndef NS_IN6ADDRSZ #if SIZEOF_STRUCT_IN6_ADDR == 0 /* We cannot have it set to zero, so we pick a fixed value here */ @@ -45,4 +56,12 @@ struct in6_addr #define NS_INT16SZ 2 #endif +#ifndef IF_NAMESIZE +#ifdef IFNAMSIZ +#define IF_NAMESIZE IFNAMSIZ +#else +#define IF_NAMESIZE 256 +#endif +#endif + #endif /* ARES_IPV6_H */ diff --git a/ares/ares_strerror.c b/ares/ares_strerror.c index 5681b93ca..6e9fa0edd 100644 --- a/ares/ares_strerror.c +++ b/ares/ares_strerror.c @@ -38,7 +38,8 @@ const char *ares_strerror(int code) "Error reading file", "Out of memory", "Channel is being destroyed", - "Misformatted string" + "Misformatted string", + "Illegal flags specified" }; assert(code >= 0 && code < (int)(sizeof(errtext) / sizeof(*errtext))); diff --git a/ares/configure.ac b/ares/configure.ac index 9239957da..120119812 100644 --- a/ares/configure.ac +++ b/ares/configure.ac @@ -1,274 +1,332 @@ -dnl Process this file with autoconf to produce a configure script. -AC_INIT(ares_init.c) -AM_CONFIG_HEADER(config.h) -AM_MAINTAINER_MODE -AM_INIT_AUTOMAKE(c-ares, CVS) - -AC_PROG_CC -AC_PROG_INSTALL - -case $host_os in -solaris*) - AC_DEFINE(ETC_INET, 1, [if a /etc/inet dir is being used]) - ;; -esac - -# check for ssize_t -AC_CHECK_TYPE(ssize_t, , - AC_DEFINE(ssize_t, int, [the signed version of size_t])) - -AC_SEARCH_LIBS(gethostbyname, nsl) -AC_SEARCH_LIBS(socket, socket) - -dnl ************************************************************ -dnl Option to switch on debug options. This makes an assumption that -dnl this is built as an 'ares' subdir in the curl source tree. Subject for -dnl improval in the future! -dnl -AC_MSG_CHECKING([whether to enable debug options]) -AC_ARG_ENABLE(debug, -AC_HELP_STRING([--enable-debug],[Enable pedantic debug options]) -AC_HELP_STRING([--disable-debug],[Disable debug options]), -[ case "$enableval" in - no) - AC_MSG_RESULT(no) - ;; - *) AC_MSG_RESULT(yes) - - dnl when doing the debug stuff, use static library only - AC_DISABLE_SHARED - - dnl Checks for standard header files, to make memdebug.h inclusions bettter - AC_HEADER_STDC - - dnl the entire --enable-debug is a hack that lives and runs on top of - dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier - AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl]) - - CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include" - CFLAGS="$CFLAGS -g" - - dnl set compiler "debug" options to become more picky, and remove - dnl optimize options from CFLAGS - CURL_CC_DEBUG_OPTS - - ;; - esac ], - AC_MSG_RESULT(no) -) - -AC_PROG_LIBTOOL - -dnl check for a few basic system headers we need -AC_CHECK_HEADERS( - sys/types.h \ - sys/time.h \ - sys/select.h \ - sys/socket.h \ - winsock.h \ - netinet/in.h \ - arpa/nameser.h \ - arpa/nameser_compat.h \ - arpa/inet.h, , , -[ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -dnl We do this default-include simply to make sure that the nameser_compat.h -dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1 -dnl (and others?) is not designed to allow this. -#ifdef HAVE_ARPA_NAMESER_H -#include -#endif -] - ) - -dnl check for AF_INET6 -CARES_CHECK_CONSTANT( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif - - ], [PF_INET6], - AC_DEFINE_UNQUOTED(HAVE_PF_INET6,1,[Define to 1 if you have PF_INET6.]) -) - -dnl check for PF_INET6 -CARES_CHECK_CONSTANT( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif - - ], [AF_INET6], - AC_DEFINE_UNQUOTED(HAVE_AF_INET6,1,[Define to 1 if you have AF_INET6.]) -) - - -dnl check for the in6_addr structure -CARES_CHECK_STRUCT( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif - ], [in6_addr], - AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.]) -) - -dnl check for inet_pton -AC_CHECK_FUNCS(inet_pton) -dnl Some systems have it, but not IPv6 -if test "$ac_cv_func_inet_pton" = "yes" ; then -AC_MSG_CHECKING(if inet_pton supports IPv6) -AC_TRY_RUN( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -int main() - { - struct in6_addr addr6; - if (inet_pton(AF_INET6, "::1", &addr6) < 1) - exit(1); - else - exit(0); - } - ], [ - AC_MSG_RESULT(yes) - AC_DEFINE_UNQUOTED(HAVE_INET_PTON_IPV6,1,[Define to 1 if inet_pton supports IPv6.]) - ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) -fi -dnl Check for inet_net_pton -AC_CHECK_FUNCS(inet_net_pton) -dnl Again, some systems have it, but not IPv6 -if test "$ac_cv_func_inet_net_pton" = "yes" ; then -AC_MSG_CHECKING(if inet_net_pton supports IPv6) -AC_TRY_RUN( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -int main() - { - struct in6_addr addr6; - if (inet_net_pton(AF_INET6, "::1", &addr6, sizeof(addr6)) < 1) - exit(1); - else - exit(0); - } - ], [ - AC_MSG_RESULT(yes) - AC_DEFINE_UNQUOTED(HAVE_INET_NET_PTON_IPV6,1,[Define to 1 if inet_net_pton supports IPv6.]) - ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) -fi - - -dnl Check for inet_ntop -AC_CHECK_FUNCS(inet_ntop) -dnl Again, some systems have it, but not IPv6 -if test "$ac_cv_func_inet_ntop" = "yes" ; then -AC_MSG_CHECKING(if inet_ntop supports IPv6) -AC_TRY_RUN( - [ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#include -int main() - { - struct in6_addr addr6; - char buf[128]; - if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT) - exit(1); - else - exit(0); - } - ], [ - AC_MSG_RESULT(yes) - AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,[Define to 1 if inet_ntop supports IPv6.]) - ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) -fi - -AC_CHECK_SIZEOF(struct in6_addr, , -[ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -] -) -AC_CHECK_SIZEOF(struct in_addr, , -[ -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifdef HAVE_WINSOCK_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -] -) - -AC_CHECK_FUNCS(bitncmp) - - -AC_OUTPUT(Makefile) +dnl Process this file with autoconf to produce a configure script. +AC_INIT(ares_init.c) +AM_CONFIG_HEADER(config.h) +AM_MAINTAINER_MODE +AM_INIT_AUTOMAKE(c-ares, CVS) + +AC_PROG_CC +AC_PROG_INSTALL + +case $host_os in +solaris*) + AC_DEFINE(ETC_INET, 1, [if a /etc/inet dir is being used]) + ;; +esac + +# check for ssize_t +AC_CHECK_TYPE(ssize_t, , + AC_DEFINE(ssize_t, int, [the signed version of size_t])) + +AC_SEARCH_LIBS(gethostbyname, nsl) +AC_SEARCH_LIBS(socket, socket) + +dnl ************************************************************ +dnl Option to switch on debug options. This makes an assumption that +dnl this is built as an 'ares' subdir in the curl source tree. Subject for +dnl improval in the future! +dnl +AC_MSG_CHECKING([whether to enable debug options]) +AC_ARG_ENABLE(debug, +AC_HELP_STRING([--enable-debug],[Enable pedantic debug options]) +AC_HELP_STRING([--disable-debug],[Disable debug options]), +[ case "$enableval" in + no) + AC_MSG_RESULT(no) + ;; + *) AC_MSG_RESULT(yes) + + dnl when doing the debug stuff, use static library only + AC_DISABLE_SHARED + + dnl Checks for standard header files, to make memdebug.h inclusions bettter + AC_HEADER_STDC + + dnl the entire --enable-debug is a hack that lives and runs on top of + dnl libcurl stuff so this BUILDING_LIBCURL is not THAT much uglier + AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl]) + + CPPFLAGS="$CPPFLAGS -DCURLDEBUG -I$srcdir/../include" + CFLAGS="$CFLAGS -g" + + dnl set compiler "debug" options to become more picky, and remove + dnl optimize options from CFLAGS + CURL_CC_DEBUG_OPTS + + ;; + esac ], + AC_MSG_RESULT(no) +) + +AC_PROG_LIBTOOL + +dnl check for a few basic system headers we need +AC_CHECK_HEADERS( + sys/types.h \ + sys/time.h \ + sys/select.h \ + sys/socket.h \ + winsock.h \ + netinet/in.h \ + net/if.h \ + arpa/nameser.h \ + arpa/nameser_compat.h \ + arpa/inet.h, , , +[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +dnl We do this default-include simply to make sure that the nameser_compat.h +dnl header *REALLY* can be include after the new nameser.h. It seems AIX 5.1 +dnl (and others?) is not designed to allow this. +#ifdef HAVE_ARPA_NAMESER_H +#include +#endif + +dnl *Sigh* these are needed in order for net/if.h to get properly detected. +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +] + ) + +AC_CHECK_TYPE(socklen_t, , + AC_DEFINE(socklen_t, int, [the length of a socket address]), + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif + ]) + +dnl check for AF_INET6 +CARES_CHECK_CONSTANT( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif + + ], [PF_INET6], + AC_DEFINE_UNQUOTED(HAVE_PF_INET6,1,[Define to 1 if you have PF_INET6.]) +) + +dnl check for PF_INET6 +CARES_CHECK_CONSTANT( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif + + ], [AF_INET6], + AC_DEFINE_UNQUOTED(HAVE_AF_INET6,1,[Define to 1 if you have AF_INET6.]) +) + + +dnl check for the in6_addr structure +CARES_CHECK_STRUCT( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif + ], [in6_addr], + AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.]) +) + +dnl check for the sockaddr_in6 structure +CARES_CHECK_STRUCT( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif + ], [sockaddr_in6], + AC_DEFINE_UNQUOTED(HAVE_STRUCT_SOCKADDR_IN6,1, + [Define to 1 if you have struct sockaddr_in6.]) ac_have_sockaddr_in6=yes +) + +if test "$ac_have_sockaddr_in6" = "yes" ; then +CARES_CHECK_STRUCT_MEMBER( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif + ], [sockaddr_in6], [sin6_scope_id], + AC_DEFINE_UNQUOTED(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID,1, + [Define to 1 if your struct sockaddr_in6 has sin6_scope_id.]) +) +fi + +dnl check for inet_pton +AC_CHECK_FUNCS(inet_pton) +dnl Some systems have it, but not IPv6 +if test "$ac_cv_func_inet_pton" = "yes" ; then +AC_MSG_CHECKING(if inet_pton supports IPv6) +AC_TRY_RUN( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +int main() + { + struct in6_addr addr6; + if (inet_pton(AF_INET6, "::1", &addr6) < 1) + exit(1); + else + exit(0); + } + ], [ + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_INET_PTON_IPV6,1,[Define to 1 if inet_pton supports IPv6.]) + ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) +fi +dnl Check for inet_net_pton +AC_CHECK_FUNCS(inet_net_pton) +dnl Again, some systems have it, but not IPv6 +if test "$ac_cv_func_inet_net_pton" = "yes" ; then +AC_MSG_CHECKING(if inet_net_pton supports IPv6) +AC_TRY_RUN( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +int main() + { + struct in6_addr addr6; + if (inet_net_pton(AF_INET6, "::1", &addr6, sizeof(addr6)) < 1) + exit(1); + else + exit(0); + } + ], [ + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_INET_NET_PTON_IPV6,1,[Define to 1 if inet_net_pton supports IPv6.]) + ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) +fi + + +dnl Check for inet_ntop +AC_CHECK_FUNCS(inet_ntop) +dnl Again, some systems have it, but not IPv6 +if test "$ac_cv_func_inet_ntop" = "yes" ; then +AC_MSG_CHECKING(if inet_ntop supports IPv6) +AC_TRY_RUN( + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#include +int main() + { + struct in6_addr addr6; + char buf[128]; + if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT) + exit(1); + else + exit(0); + } + ], [ + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6,1,[Define to 1 if inet_ntop supports IPv6.]) + ], AC_MSG_RESULT(no),AC_MSG_RESULT(no)) +fi + +AC_CHECK_SIZEOF(struct in6_addr, , +[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +] +) +AC_CHECK_SIZEOF(struct in_addr, , +[ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifdef HAVE_WINSOCK_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +] +) + +AC_CHECK_FUNCS([bitncmp if_indextoname]) + + +AC_OUTPUT(Makefile) diff --git a/ares/setup.h b/ares/setup.h index e972702d5..619a285d2 100644 --- a/ares/setup.h +++ b/ares/setup.h @@ -19,6 +19,7 @@ #else /* simple work-around for now, for systems without configure support */ #define ssize_t int +#define socklen_t int #endif /* Recent autoconf versions define these symbols in config.h. We don't want