Loading ares/CHANGES +5 −0 Original line number Diff line number Diff line Changelog for the c-ares project * January 31 2009 (Daniel Stenberg) - ares_gethostbyname() now accepts 'AF_UNSPEC' as a family for resolving either AF_INET6 or AF_INET. It works by accepting any of the looksups in the hosts file, and it resolves the AAAA field with a fallback to A. * January 14 2009 (Daniel Stenberg) - ares.h no longer uses the HAVE_STRUCT_IN6_ADDR define check, but instead it now declares the private struct ares_in6_addr for all systems instead of Loading ares/RELEASE-NOTES +4 −2 Original line number Diff line number Diff line Loading @@ -2,8 +2,10 @@ This is what's new and changed in the c-ares 1.6.1 release: Changed: o in6_addr is not used in ares.h anymore, but a private ares_in6_addr is instead declared and used o in6_addr is not used in ares.h anymore, but a private ares_in6_addr is instead declared and used p ares_gethostbyname() now supports 'AF_UNSPEC' as a family for resolving either AF_INET6 or AF_INET Fixed: Loading ares/ares__get_hostent.c +14 −10 Original line number Diff line number Diff line Loading @@ -69,16 +69,20 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) addr.s_addr = inet_addr(line); if (addr.s_addr == INADDR_NONE) { if (ares_inet_pton(AF_INET6, line, &addr6) > 0) { if (family != AF_INET6) continue; /* It wasn't an AF_INET dotted address, then AF_UNSPEC and AF_INET6 families are subject for this further check */ if ((family != AF_INET) && (ares_inet_pton(AF_INET6, line, &addr6) > 0)) { addrlen = sizeof(struct in6_addr); family = AF_INET6; } else continue; } else if (family == AF_UNSPEC) family = AF_INET; /* now confirmed! */ else if (family != AF_INET) /* unknown, keep moving */ continue; /* Get the canonical hostname. */ Loading ares/ares_gethostbyname.c +54 −41 Original line number Diff line number Diff line Loading @@ -61,7 +61,8 @@ struct host_query { char *name; ares_host_callback callback; void *arg; int family; int sent_family; /* this family is what was is being used */ int want_family; /* this family is what is asked for in the API */ const char *remaining_lookups; int timeouts; }; Loading @@ -71,26 +72,31 @@ static void host_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); static void end_hquery(struct host_query *hquery, int status, struct hostent *host); static int fake_hostent(const char *name, int family, ares_host_callback callback, void *arg); static int fake_hostent(const char *name, int family, ares_host_callback callback, void *arg); static int file_lookup(const char *name, int family, struct hostent **host); static void sort_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static void sort6_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static int get_address_index(const struct in_addr *addr, const struct apattern *sortlist, int nsort); static int get6_address_index(const struct in6_addr *addr, const struct apattern *sortlist, int nsort); static void sort_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static void sort6_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static int get_address_index(const struct in_addr *addr, const struct apattern *sortlist, int nsort); static int get6_address_index(const struct in6_addr *addr, const struct apattern *sortlist, int nsort); void ares_gethostbyname(ares_channel channel, const char *name, int family, ares_host_callback callback, void *arg) { struct host_query *hquery; /* Right now we only know how to look up Internet addresses. */ if (family != AF_INET && family != AF_INET6) { /* Right now we only know how to look up Internet addresses - and unspec means try both basically. */ switch (family) { case AF_INET: case AF_INET6: case AF_UNSPEC: break; default: callback(arg, ARES_ENOTIMP, 0, NULL); return; } Loading @@ -107,9 +113,9 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family, } hquery->channel = channel; hquery->name = strdup(name); hquery->family = family; if (!hquery->name) { hquery->want_family = family; hquery->sent_family = -1; /* nothing is sent yet */ if (!hquery->name) { free(hquery); callback(arg, ARES_ENOMEM, 0, NULL); return; Loading @@ -136,17 +142,23 @@ static void next_lookup(struct host_query *hquery, int status_code) case 'b': /* DNS lookup */ hquery->remaining_lookups = p + 1; if (hquery->family == AF_INET6) if ((hquery->want_family == AF_INET6) || (hquery->want_family == AF_UNSPEC)) { /* if inet6 or unspec, start out with AAAA */ hquery->sent_family = AF_INET6; ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback, hquery); else } else { hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); } return; case 'f': /* Host file lookup */ status = file_lookup(hquery->name, hquery->family, &host); status = file_lookup(hquery->name, hquery->want_family, &host); /* this status check below previously checked for !ARES_ENOTFOUND, but we should not assume that this single error code is the one Loading @@ -173,22 +185,22 @@ static void host_callback(void *arg, int status, int timeouts, hquery->timeouts += timeouts; if (status == ARES_SUCCESS) { if (hquery->family == AF_INET) if (hquery->sent_family == AF_INET) { status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); if (host && channel->nsort) sort_addresses(host, channel->sortlist, channel->nsort); } else if (hquery->family == AF_INET6) else if (hquery->sent_family == AF_INET6) { status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); if (status == ARES_ENODATA) { if (status == ARES_ENODATA) { /* The query returned something (e.g. CNAME) but there were no AAAA records. Try looking up A instead. */ hquery->family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); AAAA records. Try looking up A instead. We should possibly limit this attempt-next logic to AF_UNSPEC lookups only. */ hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); return; } if (host && channel->nsort) Loading @@ -196,10 +208,11 @@ static void host_callback(void *arg, int status, int timeouts, } end_hquery(hquery, status, host); } else if (status == ARES_ENODATA && hquery->family == AF_INET6) else if (status == ARES_ENODATA && hquery->sent_family == AF_INET6) { /* There was no AAAA. Now lookup an A */ hquery->family = AF_INET; /* There was no AAAA. Now lookup an A. We should possibly limit this attempt-next logic to AF_UNSPEC lookups only. */ hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); } Loading Loading
ares/CHANGES +5 −0 Original line number Diff line number Diff line Changelog for the c-ares project * January 31 2009 (Daniel Stenberg) - ares_gethostbyname() now accepts 'AF_UNSPEC' as a family for resolving either AF_INET6 or AF_INET. It works by accepting any of the looksups in the hosts file, and it resolves the AAAA field with a fallback to A. * January 14 2009 (Daniel Stenberg) - ares.h no longer uses the HAVE_STRUCT_IN6_ADDR define check, but instead it now declares the private struct ares_in6_addr for all systems instead of Loading
ares/RELEASE-NOTES +4 −2 Original line number Diff line number Diff line Loading @@ -2,8 +2,10 @@ This is what's new and changed in the c-ares 1.6.1 release: Changed: o in6_addr is not used in ares.h anymore, but a private ares_in6_addr is instead declared and used o in6_addr is not used in ares.h anymore, but a private ares_in6_addr is instead declared and used p ares_gethostbyname() now supports 'AF_UNSPEC' as a family for resolving either AF_INET6 or AF_INET Fixed: Loading
ares/ares__get_hostent.c +14 −10 Original line number Diff line number Diff line Loading @@ -69,16 +69,20 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) addr.s_addr = inet_addr(line); if (addr.s_addr == INADDR_NONE) { if (ares_inet_pton(AF_INET6, line, &addr6) > 0) { if (family != AF_INET6) continue; /* It wasn't an AF_INET dotted address, then AF_UNSPEC and AF_INET6 families are subject for this further check */ if ((family != AF_INET) && (ares_inet_pton(AF_INET6, line, &addr6) > 0)) { addrlen = sizeof(struct in6_addr); family = AF_INET6; } else continue; } else if (family == AF_UNSPEC) family = AF_INET; /* now confirmed! */ else if (family != AF_INET) /* unknown, keep moving */ continue; /* Get the canonical hostname. */ Loading
ares/ares_gethostbyname.c +54 −41 Original line number Diff line number Diff line Loading @@ -61,7 +61,8 @@ struct host_query { char *name; ares_host_callback callback; void *arg; int family; int sent_family; /* this family is what was is being used */ int want_family; /* this family is what is asked for in the API */ const char *remaining_lookups; int timeouts; }; Loading @@ -71,26 +72,31 @@ static void host_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); static void end_hquery(struct host_query *hquery, int status, struct hostent *host); static int fake_hostent(const char *name, int family, ares_host_callback callback, void *arg); static int fake_hostent(const char *name, int family, ares_host_callback callback, void *arg); static int file_lookup(const char *name, int family, struct hostent **host); static void sort_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static void sort6_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static int get_address_index(const struct in_addr *addr, const struct apattern *sortlist, int nsort); static int get6_address_index(const struct in6_addr *addr, const struct apattern *sortlist, int nsort); static void sort_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static void sort6_addresses(struct hostent *host, const struct apattern *sortlist, int nsort); static int get_address_index(const struct in_addr *addr, const struct apattern *sortlist, int nsort); static int get6_address_index(const struct in6_addr *addr, const struct apattern *sortlist, int nsort); void ares_gethostbyname(ares_channel channel, const char *name, int family, ares_host_callback callback, void *arg) { struct host_query *hquery; /* Right now we only know how to look up Internet addresses. */ if (family != AF_INET && family != AF_INET6) { /* Right now we only know how to look up Internet addresses - and unspec means try both basically. */ switch (family) { case AF_INET: case AF_INET6: case AF_UNSPEC: break; default: callback(arg, ARES_ENOTIMP, 0, NULL); return; } Loading @@ -107,9 +113,9 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family, } hquery->channel = channel; hquery->name = strdup(name); hquery->family = family; if (!hquery->name) { hquery->want_family = family; hquery->sent_family = -1; /* nothing is sent yet */ if (!hquery->name) { free(hquery); callback(arg, ARES_ENOMEM, 0, NULL); return; Loading @@ -136,17 +142,23 @@ static void next_lookup(struct host_query *hquery, int status_code) case 'b': /* DNS lookup */ hquery->remaining_lookups = p + 1; if (hquery->family == AF_INET6) if ((hquery->want_family == AF_INET6) || (hquery->want_family == AF_UNSPEC)) { /* if inet6 or unspec, start out with AAAA */ hquery->sent_family = AF_INET6; ares_search(hquery->channel, hquery->name, C_IN, T_AAAA, host_callback, hquery); else } else { hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); } return; case 'f': /* Host file lookup */ status = file_lookup(hquery->name, hquery->family, &host); status = file_lookup(hquery->name, hquery->want_family, &host); /* this status check below previously checked for !ARES_ENOTFOUND, but we should not assume that this single error code is the one Loading @@ -173,22 +185,22 @@ static void host_callback(void *arg, int status, int timeouts, hquery->timeouts += timeouts; if (status == ARES_SUCCESS) { if (hquery->family == AF_INET) if (hquery->sent_family == AF_INET) { status = ares_parse_a_reply(abuf, alen, &host, NULL, NULL); if (host && channel->nsort) sort_addresses(host, channel->sortlist, channel->nsort); } else if (hquery->family == AF_INET6) else if (hquery->sent_family == AF_INET6) { status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); if (status == ARES_ENODATA) { if (status == ARES_ENODATA) { /* The query returned something (e.g. CNAME) but there were no AAAA records. Try looking up A instead. */ hquery->family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); AAAA records. Try looking up A instead. We should possibly limit this attempt-next logic to AF_UNSPEC lookups only. */ hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); return; } if (host && channel->nsort) Loading @@ -196,10 +208,11 @@ static void host_callback(void *arg, int status, int timeouts, } end_hquery(hquery, status, host); } else if (status == ARES_ENODATA && hquery->family == AF_INET6) else if (status == ARES_ENODATA && hquery->sent_family == AF_INET6) { /* There was no AAAA. Now lookup an A */ hquery->family = AF_INET; /* There was no AAAA. Now lookup an A. We should possibly limit this attempt-next logic to AF_UNSPEC lookups only. */ hquery->sent_family = AF_INET; ares_search(hquery->channel, hquery->name, C_IN, T_A, host_callback, hquery); } Loading