Loading ares/ares.h +21 −2 Original line number Diff line number Diff line Loading @@ -240,10 +240,29 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen); int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, int alen, unsigned char **s, long *enclen); struct addrttl { struct in_addr ipaddr; int ttl; }; struct addr6ttl { struct in6_addr ip6addr; int ttl; }; /* ** Parse the buffer, starting at *abuf and of length alen bytes, previously ** obtained from an ares_search call. Put the results in *host, if nonnull. ** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with ** their TTLs in that array, and set *naddrttls to the number of addresses ** so written. */ int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host); struct hostent **host, struct addrttl *addrttls, int *naddrttls); int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host); struct hostent **host, struct addr6ttl *addrttls, int *naddrttls); int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host); int ares_parse_ns_reply(const unsigned char *abuf, int alen, Loading ares/ares_gethostbyname.c +2 −2 Original line number Diff line number Diff line Loading @@ -160,13 +160,13 @@ static void host_callback(void *arg, int status, int timeouts, { if (hquery->family == AF_INET) { status = ares_parse_a_reply(abuf, alen, &host); 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) { status = ares_parse_aaaa_reply(abuf, alen, &host); status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); if (host && channel->nsort) sort6_addresses(host, channel->sortlist, channel->nsort); } Loading ares/ares_parse_a_reply.3 +18 −3 Original line number Diff line number Diff line Loading @@ -22,24 +22,39 @@ ares_parse_a_reply \- Parse a reply to a DNS query of type A into a hostent .B #include <ares.h> .PP .B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP, .B struct hostent **\fIhost\fP); .B struct hostent **\fIhost\fP, .B struct addrttl *\fIaddrttls\fB, int *\fInaddrttls\fB); .fi .SH DESCRIPTION The .B ares_parse_a_reply function parses the response to a query of type A into a .BR "struct hostent" . .BR "struct hostent" and/or an array of .BR "struct addrttls" . The parameters .I abuf and .I alen give the contents of the response. The result is stored in allocated memory and a pointer to it stored into the variable pointed to by .IR host . .IR host , if host is nonnull. It is the caller's responsibility to free the resulting host structure using .BR ares_free_hostent (3) when it is no longer needed. .PP If .IR addrttls and .IR naddrttls are both nonnull, then up to *naddrttls .BR "struct addrttl" records are stored in the array pointed to by addrttls, and then *naddrttls is set to the number of records so stored. Note that the memory for these records is supplied by the caller. .SH RETURN VALUES .B ares_parse_a_reply can return any of the following values: Loading ares/ares_parse_a_reply.c +98 −36 Original line number Diff line number Diff line Loading @@ -37,19 +37,26 @@ #include "ares_private.h" int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host) struct hostent **host, struct addrttl *addrttls, int *naddrttls) { unsigned int qdcount, ancount; int status, i, rr_type, rr_class, rr_len, naddrs; int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs; int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */ int naliases; long len; const unsigned char *aptr; char *hostname, *rr_name, *rr_data, **aliases; struct in_addr *addrs; struct hostent *hostent; const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0; /* Set *host to NULL for all failure cases. */ if (host) *host = NULL; /* Same with *naddrttls. */ if (naddrttls) *naddrttls = 0; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) Loading @@ -73,6 +80,8 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, } aptr += len + QFIXEDSZ; if (host) { /* Allocate addresses and aliases; ancount gives an upper bound for both. */ addrs = malloc(ancount * sizeof(struct in_addr)); if (!addrs) Loading @@ -87,6 +96,13 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, free(addrs); return ARES_ENOMEM; } } else { addrs = NULL; aliases = NULL; } naddrs = 0; naliases = 0; Loading @@ -106,13 +122,33 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, rr_type = DNS_RR_TYPE(aptr); rr_class = DNS_RR_CLASS(aptr); rr_len = DNS_RR_LEN(aptr); rr_ttl = DNS_RR_TTL(aptr); aptr += RRFIXEDSZ; if (rr_class == C_IN && rr_type == T_A && rr_len == sizeof(struct in_addr) && strcasecmp(rr_name, hostname) == 0) { if (addrs) { if (aptr + sizeof(struct in_addr) > abuf + alen) { status = ARES_EBADRESP; break; } memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); } if (naddrs < max_addr_ttls) { struct addrttl * const at = &addrttls[naddrs]; if (aptr + sizeof(struct in_addr) > abuf + alen) { status = ARES_EBADRESP; break; } memcpy(&at->ipaddr, aptr, sizeof(struct in_addr)); at->ttl = rr_ttl; } naddrs++; status = ARES_SUCCESS; } Loading @@ -120,7 +156,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, if (rr_class == C_IN && rr_type == T_CNAME) { /* Record the RR name as an alias. */ if (aliases) aliases[naliases] = rr_name; else free(rr_name); naliases++; /* Decode the RR data and replace the hostname with it. */ Loading @@ -129,6 +168,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, break; free(hostname); hostname = rr_data; /* Take the min of the TTLs we see in the CNAME chain. */ if (cname_ttl > rr_ttl) cname_ttl = rr_ttl; } else free(rr_name); Loading @@ -145,8 +188,23 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, status = ARES_ENODATA; if (status == ARES_SUCCESS) { /* We got our answer. Allocate memory to build the host entry. */ /* We got our answer. */ if (naddrttls) { const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls; for (i = 0; i < n; i++) { /* Ensure that each A TTL is no larger than the CNAME TTL. */ if (addrttls[i].ttl > cname_ttl) addrttls[i].ttl = cname_ttl; } *naddrttls = n; } if (aliases) aliases[naliases] = NULL; if (host) { /* Allocate memory to build the host entry. */ hostent = malloc(sizeof(struct hostent)); if (hostent) { Loading @@ -168,9 +226,13 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, } status = ARES_ENOMEM; } } if (aliases) { for (i = 0; i < naliases; i++) free(aliases[i]); free(aliases); } free(addrs); free(hostname); return status; Loading ares/ares_parse_aaaa_reply.3 +18 −3 Original line number Diff line number Diff line Loading @@ -22,24 +22,39 @@ ares_parse_aaaa_reply \- Parse a reply to a DNS query of type AAAA into a hosten .B #include <ares.h> .PP .B int ares_parse_aaaa_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP, .B struct hostent **\fIhost\fP); .B struct hostent **\fIhost\fP, .B struct addrttl *\fIaddrttls\fB, int *\fInaddrttls\fB); .fi .SH DESCRIPTION The .B ares_parse_aaaa_reply function parses the response to a query of type AAAA into a .BR "struct hostent" . .BR "struct hostent" and/or an array of .BR "struct addrttls" . The parameters .I abuf and .I alen give the contents of the response. The result is stored in allocated memory and a pointer to it stored into the variable pointed to by .IR host . .IR host , if host is nonnull. It is the caller's responsibility to free the resulting host structure using .BR ares_free_hostent (3) when it is no longer needed. .PP If .IR addrttls and .IR naddrttls are both nonnull, then up to *naddrttls .BR "struct addr6ttl" records are stored in the array pointed to by addrttls, and then *naddrttls is set to the number of records so stored. Note that the memory for these records is supplied by the caller. .SH RETURN VALUES .B ares_parse_aaaa_reply can return any of the following values: Loading Loading
ares/ares.h +21 −2 Original line number Diff line number Diff line Loading @@ -240,10 +240,29 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen); int ares_expand_string(const unsigned char *encoded, const unsigned char *abuf, int alen, unsigned char **s, long *enclen); struct addrttl { struct in_addr ipaddr; int ttl; }; struct addr6ttl { struct in6_addr ip6addr; int ttl; }; /* ** Parse the buffer, starting at *abuf and of length alen bytes, previously ** obtained from an ares_search call. Put the results in *host, if nonnull. ** Also, if addrttls is nonnull, put up to *naddrttls IPv4 addresses along with ** their TTLs in that array, and set *naddrttls to the number of addresses ** so written. */ int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host); struct hostent **host, struct addrttl *addrttls, int *naddrttls); int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host); struct hostent **host, struct addr6ttl *addrttls, int *naddrttls); int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int addrlen, int family, struct hostent **host); int ares_parse_ns_reply(const unsigned char *abuf, int alen, Loading
ares/ares_gethostbyname.c +2 −2 Original line number Diff line number Diff line Loading @@ -160,13 +160,13 @@ static void host_callback(void *arg, int status, int timeouts, { if (hquery->family == AF_INET) { status = ares_parse_a_reply(abuf, alen, &host); 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) { status = ares_parse_aaaa_reply(abuf, alen, &host); status = ares_parse_aaaa_reply(abuf, alen, &host, NULL, NULL); if (host && channel->nsort) sort6_addresses(host, channel->sortlist, channel->nsort); } Loading
ares/ares_parse_a_reply.3 +18 −3 Original line number Diff line number Diff line Loading @@ -22,24 +22,39 @@ ares_parse_a_reply \- Parse a reply to a DNS query of type A into a hostent .B #include <ares.h> .PP .B int ares_parse_a_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP, .B struct hostent **\fIhost\fP); .B struct hostent **\fIhost\fP, .B struct addrttl *\fIaddrttls\fB, int *\fInaddrttls\fB); .fi .SH DESCRIPTION The .B ares_parse_a_reply function parses the response to a query of type A into a .BR "struct hostent" . .BR "struct hostent" and/or an array of .BR "struct addrttls" . The parameters .I abuf and .I alen give the contents of the response. The result is stored in allocated memory and a pointer to it stored into the variable pointed to by .IR host . .IR host , if host is nonnull. It is the caller's responsibility to free the resulting host structure using .BR ares_free_hostent (3) when it is no longer needed. .PP If .IR addrttls and .IR naddrttls are both nonnull, then up to *naddrttls .BR "struct addrttl" records are stored in the array pointed to by addrttls, and then *naddrttls is set to the number of records so stored. Note that the memory for these records is supplied by the caller. .SH RETURN VALUES .B ares_parse_a_reply can return any of the following values: Loading
ares/ares_parse_a_reply.c +98 −36 Original line number Diff line number Diff line Loading @@ -37,19 +37,26 @@ #include "ares_private.h" int ares_parse_a_reply(const unsigned char *abuf, int alen, struct hostent **host) struct hostent **host, struct addrttl *addrttls, int *naddrttls) { unsigned int qdcount, ancount; int status, i, rr_type, rr_class, rr_len, naddrs; int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs; int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */ int naliases; long len; const unsigned char *aptr; char *hostname, *rr_name, *rr_data, **aliases; struct in_addr *addrs; struct hostent *hostent; const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0; /* Set *host to NULL for all failure cases. */ if (host) *host = NULL; /* Same with *naddrttls. */ if (naddrttls) *naddrttls = 0; /* Give up if abuf doesn't have room for a header. */ if (alen < HFIXEDSZ) Loading @@ -73,6 +80,8 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, } aptr += len + QFIXEDSZ; if (host) { /* Allocate addresses and aliases; ancount gives an upper bound for both. */ addrs = malloc(ancount * sizeof(struct in_addr)); if (!addrs) Loading @@ -87,6 +96,13 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, free(addrs); return ARES_ENOMEM; } } else { addrs = NULL; aliases = NULL; } naddrs = 0; naliases = 0; Loading @@ -106,13 +122,33 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, rr_type = DNS_RR_TYPE(aptr); rr_class = DNS_RR_CLASS(aptr); rr_len = DNS_RR_LEN(aptr); rr_ttl = DNS_RR_TTL(aptr); aptr += RRFIXEDSZ; if (rr_class == C_IN && rr_type == T_A && rr_len == sizeof(struct in_addr) && strcasecmp(rr_name, hostname) == 0) { if (addrs) { if (aptr + sizeof(struct in_addr) > abuf + alen) { status = ARES_EBADRESP; break; } memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); } if (naddrs < max_addr_ttls) { struct addrttl * const at = &addrttls[naddrs]; if (aptr + sizeof(struct in_addr) > abuf + alen) { status = ARES_EBADRESP; break; } memcpy(&at->ipaddr, aptr, sizeof(struct in_addr)); at->ttl = rr_ttl; } naddrs++; status = ARES_SUCCESS; } Loading @@ -120,7 +156,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, if (rr_class == C_IN && rr_type == T_CNAME) { /* Record the RR name as an alias. */ if (aliases) aliases[naliases] = rr_name; else free(rr_name); naliases++; /* Decode the RR data and replace the hostname with it. */ Loading @@ -129,6 +168,10 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, break; free(hostname); hostname = rr_data; /* Take the min of the TTLs we see in the CNAME chain. */ if (cname_ttl > rr_ttl) cname_ttl = rr_ttl; } else free(rr_name); Loading @@ -145,8 +188,23 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, status = ARES_ENODATA; if (status == ARES_SUCCESS) { /* We got our answer. Allocate memory to build the host entry. */ /* We got our answer. */ if (naddrttls) { const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls; for (i = 0; i < n; i++) { /* Ensure that each A TTL is no larger than the CNAME TTL. */ if (addrttls[i].ttl > cname_ttl) addrttls[i].ttl = cname_ttl; } *naddrttls = n; } if (aliases) aliases[naliases] = NULL; if (host) { /* Allocate memory to build the host entry. */ hostent = malloc(sizeof(struct hostent)); if (hostent) { Loading @@ -168,9 +226,13 @@ int ares_parse_a_reply(const unsigned char *abuf, int alen, } status = ARES_ENOMEM; } } if (aliases) { for (i = 0; i < naliases; i++) free(aliases[i]); free(aliases); } free(addrs); free(hostname); return status; Loading
ares/ares_parse_aaaa_reply.3 +18 −3 Original line number Diff line number Diff line Loading @@ -22,24 +22,39 @@ ares_parse_aaaa_reply \- Parse a reply to a DNS query of type AAAA into a hosten .B #include <ares.h> .PP .B int ares_parse_aaaa_reply(const unsigned char *\fIabuf\fP, int \fIalen\fP, .B struct hostent **\fIhost\fP); .B struct hostent **\fIhost\fP, .B struct addrttl *\fIaddrttls\fB, int *\fInaddrttls\fB); .fi .SH DESCRIPTION The .B ares_parse_aaaa_reply function parses the response to a query of type AAAA into a .BR "struct hostent" . .BR "struct hostent" and/or an array of .BR "struct addrttls" . The parameters .I abuf and .I alen give the contents of the response. The result is stored in allocated memory and a pointer to it stored into the variable pointed to by .IR host . .IR host , if host is nonnull. It is the caller's responsibility to free the resulting host structure using .BR ares_free_hostent (3) when it is no longer needed. .PP If .IR addrttls and .IR naddrttls are both nonnull, then up to *naddrttls .BR "struct addr6ttl" records are stored in the array pointed to by addrttls, and then *naddrttls is set to the number of records so stored. Note that the memory for these records is supplied by the caller. .SH RETURN VALUES .B ares_parse_aaaa_reply can return any of the following values: Loading