ares_parse_soa_reply.c
Go to the documentation of this file.
1 
2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3  * Copyright (C) 2012 Marko Kreen <markokr@gmail.com>
4  *
5  * Permission to use, copy, modify, and distribute this
6  * software and its documentation for any purpose and without
7  * fee is hereby granted, provided that the above copyright
8  * notice appear in all copies and that both that copyright
9  * notice and this permission notice appear in supporting
10  * documentation, and that the name of M.I.T. not be used in
11  * advertising or publicity pertaining to distribution of the
12  * software without specific, written prior permission.
13  * M.I.T. makes no representations about the suitability of
14  * this software for any purpose. It is provided "as is"
15  * without express or implied warranty.
16  */
17 
18 #include "ares_setup.h"
19 
20 #ifdef HAVE_NETINET_IN_H
21 # include <netinet/in.h>
22 #endif
23 #ifdef HAVE_NETDB_H
24 # include <netdb.h>
25 #endif
26 #ifdef HAVE_ARPA_INET_H
27 # include <arpa/inet.h>
28 #endif
29 
30 #include "ares_nameser.h"
31 
32 #include "ares.h"
33 #include "ares_dns.h"
34 #include "ares_data.h"
35 #include "ares_private.h"
36 
37 int
38 ares_parse_soa_reply(const unsigned char *abuf, int alen,
39  struct ares_soa_reply **soa_out)
40 {
41  const unsigned char *aptr;
42  long len;
43  char *qname = NULL, *rr_name = NULL;
44  struct ares_soa_reply *soa = NULL;
45  int qdcount, ancount, qclass;
46  int status, i, rr_type, rr_class, rr_len;
47 
48  if (alen < HFIXEDSZ)
49  return ARES_EBADRESP;
50 
51  /* parse message header */
52  qdcount = DNS_HEADER_QDCOUNT(abuf);
53  ancount = DNS_HEADER_ANCOUNT(abuf);
54 
55  if (qdcount != 1)
56  return ARES_EBADRESP;
57  if (ancount == 0)
58  return ARES_EBADRESP;
59 
60  aptr = abuf + HFIXEDSZ;
61 
62  /* query name */
63  status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len, 0);
64  if (status != ARES_SUCCESS)
65  goto failed_stat;
66 
67  if (alen <= len + HFIXEDSZ + 1)
68  goto failed;
69  aptr += len;
70 
71  qclass = DNS_QUESTION_TYPE(aptr);
72 
73  /* skip qtype & qclass */
74  if (aptr + QFIXEDSZ > abuf + alen)
75  goto failed;
76  aptr += QFIXEDSZ;
77 
78  /* qclass of SOA with multiple answers */
79  if (qclass == T_SOA && ancount > 1)
80  goto failed;
81 
82  /* examine all the records, break and return if found soa */
83  for (i = 0; i < ancount; i++)
84  {
85  rr_name = NULL;
86  status = ares__expand_name_for_response (aptr, abuf, alen, &rr_name, &len, 0);
87  if (status != ARES_SUCCESS)
88  {
89  ares_free(rr_name);
90  goto failed_stat;
91  }
92 
93  aptr += len;
94  if ( aptr + RRFIXEDSZ > abuf + alen )
95  {
96  ares_free(rr_name);
98  goto failed_stat;
99  }
100  rr_type = DNS_RR_TYPE( aptr );
101  rr_class = DNS_RR_CLASS( aptr );
102  rr_len = DNS_RR_LEN( aptr );
103  aptr += RRFIXEDSZ;
104  if (aptr + rr_len > abuf + alen)
105  {
106  ares_free(rr_name);
108  goto failed_stat;
109  }
110  if ( rr_class == C_IN && rr_type == T_SOA )
111  {
112  /* allocate result struct */
114  if (!soa)
115  {
116  ares_free(rr_name);
118  goto failed_stat;
119  }
120 
121  /* nsname */
122  status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname,
123  &len, 0);
124  if (status != ARES_SUCCESS)
125  {
126  ares_free(rr_name);
127  goto failed_stat;
128  }
129  aptr += len;
130 
131  /* hostmaster */
132  status = ares__expand_name_for_response(aptr, abuf, alen,
133  &soa->hostmaster, &len, 0);
134  if (status != ARES_SUCCESS)
135  {
136  ares_free(rr_name);
137  goto failed_stat;
138  }
139  aptr += len;
140 
141  /* integer fields */
142  if (aptr + 5 * 4 > abuf + alen)
143  {
144  ares_free(rr_name);
145  goto failed;
146  }
147  soa->serial = DNS__32BIT(aptr + 0 * 4);
148  soa->refresh = DNS__32BIT(aptr + 1 * 4);
149  soa->retry = DNS__32BIT(aptr + 2 * 4);
150  soa->expire = DNS__32BIT(aptr + 3 * 4);
151  soa->minttl = DNS__32BIT(aptr + 4 * 4);
152 
153  ares_free(qname);
154  ares_free(rr_name);
155 
156  *soa_out = soa;
157 
158  return ARES_SUCCESS;
159  }
160  aptr += rr_len;
161 
162  ares_free(rr_name);
163 
164  if (aptr > abuf + alen)
165  goto failed_stat;
166  }
167  /* no SOA record found */
169  goto failed_stat;
170 failed:
172 
173 failed_stat:
174  if (soa)
175  ares_free_data(soa);
176  if (qname)
177  ares_free(qname);
178  return status;
179 }
ARES_ENOMEM
#define ARES_ENOMEM
Definition: ares.h:117
DNS_RR_LEN
#define DNS_RR_LEN(r)
Definition: ares_dns.h:104
ares_soa_reply::minttl
unsigned int minttl
Definition: ares.h:587
ares.h
ares_soa_reply::refresh
unsigned int refresh
Definition: ares.h:584
ares_soa_reply::hostmaster
char * hostmaster
Definition: ares.h:582
ares__expand_name_for_response
int ares__expand_name_for_response(const unsigned char *encoded, const unsigned char *abuf, int alen, char **s, long *enclen, int is_hostname)
Definition: ares_expand_name.c:291
ares_dns.h
status
absl::Status status
Definition: rls.cc:251
DNS_RR_TYPE
#define DNS_RR_TYPE(r)
Definition: ares_dns.h:101
ares_soa_reply::serial
unsigned int serial
Definition: ares.h:583
ARES_EBADRESP
#define ARES_EBADRESP
Definition: ares.h:112
ares_soa_reply
Definition: ares.h:580
T_SOA
#define T_SOA
Definition: ares_nameser.h:325
ares_soa_reply::retry
unsigned int retry
Definition: ares.h:585
DNS_QUESTION_TYPE
#define DNS_QUESTION_TYPE(q)
Definition: ares_dns.h:93
ares_data.h
ares_soa_reply::expire
unsigned int expire
Definition: ares.h:586
DNS_RR_CLASS
#define DNS_RR_CLASS(r)
Definition: ares_dns.h:102
DNS__32BIT
#define DNS__32BIT(p)
Definition: ares_dns.h:40
RRFIXEDSZ
#define RRFIXEDSZ
Definition: ares_nameser.h:211
ARES_SUCCESS
#define ARES_SUCCESS
Definition: ares.h:98
DNS_HEADER_QDCOUNT
#define DNS_HEADER_QDCOUNT(h)
Definition: ares_dns.h:72
ares_setup.h
ares_free_data
CARES_EXTERN void ares_free_data(void *dataptr)
Definition: ares_data.c:41
C_IN
#define C_IN
Definition: ares_nameser.h:292
ares_malloc_data
void * ares_malloc_data(ares_datatype type)
Definition: ares_data.c:153
ares_free
void(* ares_free)(void *ptr)=default_free
Definition: ares_library_init.c:60
DNS_HEADER_ANCOUNT
#define DNS_HEADER_ANCOUNT(h)
Definition: ares_dns.h:73
ares_private.h
QFIXEDSZ
#define QFIXEDSZ
Definition: ares_nameser.h:207
HFIXEDSZ
#define HFIXEDSZ
Definition: ares_nameser.h:203
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
ares_nameser.h
ARES_DATATYPE_SOA_REPLY
@ ARES_DATATYPE_SOA_REPLY
Definition: ares_data.h:25
ares_soa_reply::nsname
char * nsname
Definition: ares.h:581
ares_parse_soa_reply
int ares_parse_soa_reply(const unsigned char *abuf, int alen, struct ares_soa_reply **soa_out)
Definition: ares_parse_soa_reply.c:38
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:33