Loading ares/CHANGES +5 −0 Original line number Diff line number Diff line Changelog for the c-ares project * March 11, 2005 - Dominick Meglio added ares_parse_aaaa_reply.c and did various adjustments. The first little steps towards IPv6 support! * November 7 - Fixed the VC project and makefile to use ares_cancel and ares_version Loading ares/Makefile.inc +3 −2 Original line number Diff line number Diff line Loading @@ -3,7 +3,8 @@ 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 windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \ ares_parse_aaaa_reply.c HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h Loading ares/acinclude.m4 +49 −0 Original line number Diff line number Diff line Loading @@ -99,3 +99,52 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], ]) 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_TRY_RUN( [ $1 int main() { #ifdef $2 return 0; #else return 1; #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 ]) ares/ares.h +2 −1 Original line number Diff line number Diff line Loading @@ -137,12 +137,13 @@ int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, int alen, unsigned char **s, long *enclen); int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host); int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host); int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host); void ares_free_string(void *str); void ares_free_hostent(struct hostent *host); const char *ares_strerror(int code); void ares_free_errmem(char *mem); #ifdef __cplusplus } Loading ares/ares_parse_aaaa_reply.c 0 → 100644 +173 −0 Original line number Diff line number Diff line /* Copyright 2005 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 <sys/types.h> #if defined(WIN32) && !defined(WATT32) #include "nameser.h" #else #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <arpa/nameser.h> #endif #include <stdlib.h> #include <string.h> #include "ares.h" #include "ares_dns.h" #include "ares_private.h" int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host) { unsigned int qdcount, ancount; int status, i, rr_type, rr_class, rr_len, naddrs; int naliases; long len; const unsigned char *aptr; char *hostname, *rr_name, *rr_data, **aliases; struct in6_addr *addrs; struct hostent *hostent; /* Set *host to NULL for all failure cases. */ *host = NULL; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); if (qdcount != 1) return ARES_EBADRESP; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares_expand_name(aptr, abuf, alen, &hostname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free(hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Allocate addresses and aliases; ancount gives an upper bound for both. */ addrs = malloc(ancount * sizeof(struct in6_addr)); if (!addrs) { free(hostname); return ARES_ENOMEM; } aliases = malloc((ancount + 1) * sizeof(char *)); if (!aliases) { free(hostname); free(addrs); return ARES_ENOMEM; } naddrs = 0; naliases = 0; /* Examine each answer resource record (RR) in turn. */ for (i = 0; i < (int)ancount; i++) { /* Decode the RR up to the data field. */ status = ares_expand_name(aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) break; aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE(aptr); rr_class = DNS_RR_CLASS(aptr); rr_len = DNS_RR_LEN(aptr); aptr += RRFIXEDSZ; if (rr_class == C_IN && rr_type == T_AAAA && rr_len == sizeof(struct in6_addr) && strcasecmp(rr_name, hostname) == 0) { memcpy(&addrs[naddrs], aptr, sizeof(struct in6_addr)); naddrs++; status = ARES_SUCCESS; } if (rr_class == C_IN && rr_type == T_CNAME) { /* Record the RR name as an alias. */ aliases[naliases] = rr_name; naliases++; /* Decode the RR data and replace the hostname with it. */ status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); if (status != ARES_SUCCESS) break; free(hostname); hostname = rr_data; } else free(rr_name); aptr += rr_len; if (aptr > abuf + alen) { status = ARES_EBADRESP; break; } } if (status == ARES_SUCCESS && naddrs == 0) status = ARES_ENODATA; if (status == ARES_SUCCESS) { /* We got our answer. Allocate memory to build the host entry. */ aliases[naliases] = NULL; hostent = malloc(sizeof(struct hostent)); if (hostent) { hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); if (hostent->h_addr_list) { /* Fill in the hostent and return successfully. */ hostent->h_name = hostname; hostent->h_aliases = aliases; hostent->h_addrtype = AF_INET6; hostent->h_length = sizeof(struct in6_addr); for (i = 0; i < naddrs; i++) hostent->h_addr_list[i] = (char *) &addrs[i]; hostent->h_addr_list[naddrs] = NULL; *host = hostent; return ARES_SUCCESS; } free(hostent); } status = ARES_ENOMEM; } for (i = 0; i < naliases; i++) free(aliases[i]); free(aliases); free(addrs); free(hostname); return status; } Loading
ares/CHANGES +5 −0 Original line number Diff line number Diff line Changelog for the c-ares project * March 11, 2005 - Dominick Meglio added ares_parse_aaaa_reply.c and did various adjustments. The first little steps towards IPv6 support! * November 7 - Fixed the VC project and makefile to use ares_cancel and ares_version Loading
ares/Makefile.inc +3 −2 Original line number Diff line number Diff line Loading @@ -3,7 +3,8 @@ 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 windows_port.c ares_expand_string.c ares_parse_ptr_reply.c \ ares_parse_aaaa_reply.c HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h nameser.h Loading
ares/acinclude.m4 +49 −0 Original line number Diff line number Diff line Loading @@ -99,3 +99,52 @@ AC_DEFUN([CURL_CC_DEBUG_OPTS], ]) 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_TRY_RUN( [ $1 int main() { #ifdef $2 return 0; #else return 1; #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 ])
ares/ares.h +2 −1 Original line number Diff line number Diff line Loading @@ -137,12 +137,13 @@ int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, int alen, unsigned char **s, long *enclen); int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host); int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host); int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host); void ares_free_string(void *str); void ares_free_hostent(struct hostent *host); const char *ares_strerror(int code); void ares_free_errmem(char *mem); #ifdef __cplusplus } Loading
ares/ares_parse_aaaa_reply.c 0 → 100644 +173 −0 Original line number Diff line number Diff line /* Copyright 2005 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 <sys/types.h> #if defined(WIN32) && !defined(WATT32) #include "nameser.h" #else #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <arpa/nameser.h> #endif #include <stdlib.h> #include <string.h> #include "ares.h" #include "ares_dns.h" #include "ares_private.h" int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host) { unsigned int qdcount, ancount; int status, i, rr_type, rr_class, rr_len, naddrs; int naliases; long len; const unsigned char *aptr; char *hostname, *rr_name, *rr_data, **aliases; struct in6_addr *addrs; struct hostent *hostent; /* Set *host to NULL for all failure cases. */ *host = NULL; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) return ARES_EBADRESP; /* Fetch the question and answer count from the header. */ qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); if (qdcount != 1) return ARES_EBADRESP; /* Expand the name from the question, and skip past the question. */ aptr = abuf + HFIXEDSZ; status = ares_expand_name(aptr, abuf, alen, &hostname, &len); if (status != ARES_SUCCESS) return status; if (aptr + len + QFIXEDSZ > abuf + alen) { free(hostname); return ARES_EBADRESP; } aptr += len + QFIXEDSZ; /* Allocate addresses and aliases; ancount gives an upper bound for both. */ addrs = malloc(ancount * sizeof(struct in6_addr)); if (!addrs) { free(hostname); return ARES_ENOMEM; } aliases = malloc((ancount + 1) * sizeof(char *)); if (!aliases) { free(hostname); free(addrs); return ARES_ENOMEM; } naddrs = 0; naliases = 0; /* Examine each answer resource record (RR) in turn. */ for (i = 0; i < (int)ancount; i++) { /* Decode the RR up to the data field. */ status = ares_expand_name(aptr, abuf, alen, &rr_name, &len); if (status != ARES_SUCCESS) break; aptr += len; if (aptr + RRFIXEDSZ > abuf + alen) { status = ARES_EBADRESP; break; } rr_type = DNS_RR_TYPE(aptr); rr_class = DNS_RR_CLASS(aptr); rr_len = DNS_RR_LEN(aptr); aptr += RRFIXEDSZ; if (rr_class == C_IN && rr_type == T_AAAA && rr_len == sizeof(struct in6_addr) && strcasecmp(rr_name, hostname) == 0) { memcpy(&addrs[naddrs], aptr, sizeof(struct in6_addr)); naddrs++; status = ARES_SUCCESS; } if (rr_class == C_IN && rr_type == T_CNAME) { /* Record the RR name as an alias. */ aliases[naliases] = rr_name; naliases++; /* Decode the RR data and replace the hostname with it. */ status = ares_expand_name(aptr, abuf, alen, &rr_data, &len); if (status != ARES_SUCCESS) break; free(hostname); hostname = rr_data; } else free(rr_name); aptr += rr_len; if (aptr > abuf + alen) { status = ARES_EBADRESP; break; } } if (status == ARES_SUCCESS && naddrs == 0) status = ARES_ENODATA; if (status == ARES_SUCCESS) { /* We got our answer. Allocate memory to build the host entry. */ aliases[naliases] = NULL; hostent = malloc(sizeof(struct hostent)); if (hostent) { hostent->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); if (hostent->h_addr_list) { /* Fill in the hostent and return successfully. */ hostent->h_name = hostname; hostent->h_aliases = aliases; hostent->h_addrtype = AF_INET6; hostent->h_length = sizeof(struct in6_addr); for (i = 0; i < naddrs; i++) hostent->h_addr_list[i] = (char *) &addrs[i]; hostent->h_addr_list[naddrs] = NULL; *host = hostent; return ARES_SUCCESS; } free(hostent); } status = ARES_ENOMEM; } for (i = 0; i < naliases; i++) free(aliases[i]); free(aliases); free(addrs); free(hostname); return status; }