summaryrefslogtreecommitdiff
path: root/src/lib/ares_parse_aaaa_reply.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ares_parse_aaaa_reply.c')
-rw-r--r--src/lib/ares_parse_aaaa_reply.c174
1 files changed, 24 insertions, 150 deletions
diff --git a/src/lib/ares_parse_aaaa_reply.c b/src/lib/ares_parse_aaaa_reply.c
index 346d430..091065d 100644
--- a/src/lib/ares_parse_aaaa_reply.c
+++ b/src/lib/ares_parse_aaaa_reply.c
@@ -27,14 +27,8 @@
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#else
-# include "nameser.h"
-#endif
-#ifdef HAVE_ARPA_NAMESER_COMPAT_H
-# include <arpa/nameser_compat.h>
-#endif
+
+#include "ares_nameser.h"
#ifdef HAVE_STRINGS_H
# include <strings.h>
@@ -54,165 +48,45 @@ int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
int *naddrttls)
{
struct ares_addrinfo ai;
- struct ares_addrinfo_node *next;
- struct ares_addrinfo_cname *next_cname;
- char **aliases = NULL;
char *question_hostname = NULL;
- struct hostent *hostent = NULL;
- struct ares_in6_addr *addrs = NULL;
- int naliases = 0, naddrs = 0, alias = 0, i;
- int cname_ttl = INT_MAX;
int status;
+ int req_naddrttls = 0;
- memset(&ai, 0, sizeof(ai));
-
- status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
- if (status != ARES_SUCCESS)
- {
- ares_free(question_hostname);
-
- if (naddrttls)
- {
- *naddrttls = 0;
- }
-
- return status;
- }
-
- hostent = ares_malloc(sizeof(struct hostent));
- if (!hostent)
- {
- goto enomem;
- }
-
- next = ai.nodes;
- while (next)
- {
- if(next->ai_family == AF_INET6)
- {
- ++naddrs;
- }
- next = next->ai_next;
- }
-
- next_cname = ai.cnames;
- while (next_cname)
- {
- if(next_cname->alias)
- ++naliases;
- next_cname = next_cname->next;
- }
-
- aliases = ares_malloc((naliases + 1) * sizeof(char *));
- if (!aliases)
- {
- goto enomem;
- }
-
- if (naliases)
- {
- next_cname = ai.cnames;
- while (next_cname)
- {
- if(next_cname->alias)
- aliases[alias++] = strdup(next_cname->alias);
- if(next_cname->ttl < cname_ttl)
- cname_ttl = next_cname->ttl;
- next_cname = next_cname->next;
- }
- }
-
- aliases[alias] = NULL;
-
- hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
- if (!hostent->h_addr_list)
+ if (naddrttls)
{
- goto enomem;
+ req_naddrttls = *naddrttls;
+ *naddrttls = 0;
}
- for (i = 0; i < naddrs + 1; ++i)
- {
- hostent->h_addr_list[i] = NULL;
- }
+ memset(&ai, 0, sizeof(ai));
- if (ai.cnames)
+ status = ares__parse_into_addrinfo(abuf, alen, 0, 0, &ai);
+ if (status != ARES_SUCCESS && status != ARES_ENODATA)
{
- hostent->h_name = strdup(ai.cnames->name);
- ares_free(question_hostname);
+ goto fail;
}
- else
- {
- hostent->h_name = question_hostname;
- }
-
- hostent->h_aliases = aliases;
- hostent->h_addrtype = AF_INET6;
- hostent->h_length = sizeof(struct ares_in6_addr);
- if (naddrs)
+ if (host != NULL)
{
- addrs = ares_malloc(naddrs * sizeof(struct ares_in6_addr));
- if (!addrs)
+ status = ares__addrinfo2hostent(&ai, AF_INET6, host);
+ if (status != ARES_SUCCESS && status != ARES_ENODATA)
{
- goto enomem;
+ goto fail;
}
-
- i = 0;
- next = ai.nodes;
- while (next)
- {
- if(next->ai_family == AF_INET6)
- {
- hostent->h_addr_list[i] = (char*)&addrs[i];
- memcpy(hostent->h_addr_list[i],
- &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
- sizeof(struct ares_in6_addr));
- if (naddrttls && i < *naddrttls)
- {
- if(next->ai_ttl > cname_ttl)
- addrttls[i].ttl = cname_ttl;
- else
- addrttls[i].ttl = next->ai_ttl;
-
- memcpy(&addrttls[i].ip6addr,
- &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
- sizeof(struct ares_in6_addr));
- }
- ++i;
- }
- next = next->ai_next;
- }
-
- if (i == 0)
- {
- ares_free(addrs);
- }
- }
-
- if (host)
- {
- *host = hostent;
- }
- else
- {
- ares_free_hostent(hostent);
- }
-
- if (naddrttls)
- {
- /* Truncated to at most *naddrttls entries */
- *naddrttls = (naddrs > *naddrttls)?*naddrttls:naddrs;
}
- ares__freeaddrinfo_cnames(ai.cnames);
- ares__freeaddrinfo_nodes(ai.nodes);
- return ARES_SUCCESS;
+ if (addrttls != NULL && req_naddrttls)
+ {
+ ares__addrinfo2addrttl(&ai, AF_INET6, req_naddrttls, NULL,
+ addrttls, naddrttls);
+ }
-enomem:
- ares_free(aliases);
- ares_free(hostent);
+fail:
ares__freeaddrinfo_cnames(ai.cnames);
ares__freeaddrinfo_nodes(ai.nodes);
ares_free(question_hostname);
- return ARES_ENOMEM;
+ ares_free(ai.name);
+
+ return status;
}
+