ares_parse_aaaa_reply.c
Go to the documentation of this file.
1 
2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3  * Copyright 2005 Dominick Meglio
4  * Copyright (C) 2019 by Andrew Selivanov
5  *
6  * Permission to use, copy, modify, and distribute this
7  * software and its documentation for any purpose and without
8  * fee is hereby granted, provided that the above copyright
9  * notice appear in all copies and that both that copyright
10  * notice and this permission notice appear in supporting
11  * documentation, and that the name of M.I.T. not be used in
12  * advertising or publicity pertaining to distribution of the
13  * software without specific, written prior permission.
14  * M.I.T. makes no representations about the suitability of
15  * this software for any purpose. It is provided "as is"
16  * without express or implied warranty.
17  */
18 
19 #include "ares_setup.h"
20 
21 #ifdef HAVE_NETINET_IN_H
22 # include <netinet/in.h>
23 #endif
24 #ifdef HAVE_NETDB_H
25 # include <netdb.h>
26 #endif
27 #ifdef HAVE_ARPA_INET_H
28 # include <arpa/inet.h>
29 #endif
30 
31 #include "ares_nameser.h"
32 
33 #ifdef HAVE_STRINGS_H
34 # include <strings.h>
35 #endif
36 
37 #ifdef HAVE_LIMITS_H
38 # include <limits.h>
39 #endif
40 
41 #include "ares.h"
42 #include "ares_dns.h"
43 #include "ares_inet_net_pton.h"
44 #include "ares_private.h"
45 
46 int ares_parse_aaaa_reply(const unsigned char *abuf, int alen,
47  struct hostent **host, struct ares_addr6ttl *addrttls,
48  int *naddrttls)
49 {
50  struct ares_addrinfo ai;
51  struct ares_addrinfo_node *next;
52  struct ares_addrinfo_cname *next_cname;
53  char **aliases = NULL;
54  char *question_hostname = NULL;
55  struct hostent *hostent = NULL;
56  struct ares_in6_addr *addrs = NULL;
57  int naliases = 0, naddrs = 0, alias = 0, i;
58  int cname_ttl = INT_MAX;
59  int status;
60 
61  memset(&ai, 0, sizeof(ai));
62 
63  status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai);
64  if (status != ARES_SUCCESS)
65  {
66  ares_free(question_hostname);
67 
68  if (naddrttls)
69  {
70  *naddrttls = 0;
71  }
72 
73  return status;
74  }
75 
76  hostent = ares_malloc(sizeof(struct hostent));
77  if (!hostent)
78  {
79  goto enomem;
80  }
81 
82  next = ai.nodes;
83  while (next)
84  {
85  if(next->ai_family == AF_INET6)
86  {
87  ++naddrs;
88  }
89  next = next->ai_next;
90  }
91 
92  next_cname = ai.cnames;
93  while (next_cname)
94  {
95  if(next_cname->alias)
96  ++naliases;
97  next_cname = next_cname->next;
98  }
99 
100  aliases = ares_malloc((naliases + 1) * sizeof(char *));
101  if (!aliases)
102  {
103  goto enomem;
104  }
105 
106  if (naliases)
107  {
108  next_cname = ai.cnames;
109  while (next_cname)
110  {
111  if(next_cname->alias)
112  aliases[alias++] = ares_strdup(next_cname->alias);
113  if(next_cname->ttl < cname_ttl)
114  cname_ttl = next_cname->ttl;
115  next_cname = next_cname->next;
116  }
117  }
118 
119  aliases[alias] = NULL;
120 
121  hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *));
122  if (!hostent->h_addr_list)
123  {
124  goto enomem;
125  }
126 
127  for (i = 0; i < naddrs + 1; ++i)
128  {
129  hostent->h_addr_list[i] = NULL;
130  }
131 
132  if (ai.cnames)
133  {
134  hostent->h_name = ares_strdup(ai.cnames->name);
135  ares_free(question_hostname);
136  }
137  else
138  {
139  hostent->h_name = question_hostname;
140  }
141 
142  hostent->h_aliases = aliases;
143  hostent->h_addrtype = AF_INET6;
144  hostent->h_length = sizeof(struct ares_in6_addr);
145 
146  if (naddrs)
147  {
148  addrs = ares_malloc(naddrs * sizeof(struct ares_in6_addr));
149  if (!addrs)
150  {
151  goto enomem;
152  }
153 
154  i = 0;
155  next = ai.nodes;
156  while (next)
157  {
158  if(next->ai_family == AF_INET6)
159  {
160  hostent->h_addr_list[i] = (char*)&addrs[i];
161  memcpy(hostent->h_addr_list[i],
162  &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
163  sizeof(struct ares_in6_addr));
164  if (naddrttls && i < *naddrttls)
165  {
166  if(next->ai_ttl > cname_ttl)
167  addrttls[i].ttl = cname_ttl;
168  else
169  addrttls[i].ttl = next->ai_ttl;
170 
171  memcpy(&addrttls[i].ip6addr,
172  &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr),
173  sizeof(struct ares_in6_addr));
174  }
175  ++i;
176  }
177  next = next->ai_next;
178  }
179 
180  if (i == 0)
181  {
182  ares_free(addrs);
183  }
184  }
185 
186  if (host)
187  {
188  *host = hostent;
189  }
190  else
191  {
192  ares_free_hostent(hostent);
193  }
194 
195  if (naddrttls)
196  {
197  /* Truncated to at most *naddrttls entries */
198  *naddrttls = (naddrs > *naddrttls)?*naddrttls:naddrs;
199  }
200 
203  return ARES_SUCCESS;
204 
205 enomem:
206  ares_free(aliases);
207  ares_free(hostent);
210  ares_free(question_hostname);
211  return ARES_ENOMEM;
212 }
ares__freeaddrinfo_nodes
void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *head)
Definition: ares_freeaddrinfo.c:40
ARES_ENOMEM
#define ARES_ENOMEM
Definition: ares.h:117
ares_addrinfo_node
Definition: ares.h:593
ares__freeaddrinfo_cnames
void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *head)
Definition: ares_freeaddrinfo.c:27
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
ares_addrinfo
Definition: ares.h:616
memset
return memset(p, 0, total)
ares.h
ares_strdup
char * ares_strdup(const char *s1)
Definition: ares_strdup.c:23
ares_inet_net_pton.h
ares_addrinfo_cname::alias
char * alias
Definition: ares.h:611
ares_dns.h
status
absl::Status status
Definition: rls.cc:251
ares_parse_aaaa_reply
int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, struct hostent **host, struct ares_addr6ttl *addrttls, int *naddrttls)
Definition: ares_parse_aaaa_reply.c:46
ares_addr6ttl
Definition: ares.h:525
ares_free_hostent
CARES_EXTERN void ares_free_hostent(struct hostent *host)
Definition: ares_free_hostent.c:26
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
ares_malloc
void *(* ares_malloc)(size_t size)=default_malloc
Definition: ares_library_init.c:58
sockaddr_in6
Definition: ares_ipv6.h:25
CARES_INADDR_CAST
#define CARES_INADDR_CAST(type, var)
Definition: ares_private.h:56
ARES_SUCCESS
#define ARES_SUCCESS
Definition: ares.h:98
ares_setup.h
ares_addrinfo_cname::next
struct ares_addrinfo_cname * next
Definition: ares.h:613
ares_addrinfo::nodes
struct ares_addrinfo_node * nodes
Definition: ares.h:618
ares_addrinfo_cname
Definition: ares.h:609
ares_addrinfo::cnames
struct ares_addrinfo_cname * cnames
Definition: ares.h:617
ares__parse_into_addrinfo2
int ares__parse_into_addrinfo2(const unsigned char *abuf, int alen, char **question_hostname, struct ares_addrinfo *ai)
Definition: ares__parse_into_addrinfo.c:42
ares_in6_addr
Definition: ares.h:514
next
AllocList * next[kMaxLevel]
Definition: abseil-cpp/absl/base/internal/low_level_alloc.cc:100
ares_addrinfo_cname::ttl
int ttl
Definition: ares.h:610
ares_free
void(* ares_free)(void *ptr)=default_free
Definition: ares_library_init.c:60
ares_addr6ttl::ttl
int ttl
Definition: ares.h:527
ares_private.h
ares_nameser.h
ares_addrinfo_cname::name
char * name
Definition: ares.h:612
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:43