1 /**
2  *
3  * /brief type declarations private to the getdns library
4  *
5  * These type declarations are not meant to be used by applications calling
6  * the public library functions.
7  */
8 
9 /*
10  * Copyright (c) 2013, NLnet Labs, Verisign, Inc.
11  * All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  * * Redistributions of source code must retain the above copyright
16  *   notice, this list of conditions and the following disclaimer.
17  * * Redistributions in binary form must reproduce the above copyright
18  *   notice, this list of conditions and the following disclaimer in the
19  *   documentation and/or other materials provided with the distribution.
20  * * Neither the names of the copyright holders nor the
21  *   names of its contributors may be used to endorse or promote products
22  *   derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
28  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef TYPES_INTERNAL_H_
37 #define TYPES_INTERNAL_H_
38 
39 #include "getdns/getdns.h"
40 #include "getdns/getdns_extra.h"
41 #include "util/rbtree.h"
42 
43 
44 /**
45  * this structure represents a single item in a list or dict
46  */
47 typedef union getdns_union {
48 	void            *ptr;
49 	getdns_dict     *dict;
50 	getdns_list     *list;
51 	getdns_bindata  *bindata;
52 	uint32_t         n;
53 } getdns_union;
54 
55 typedef struct getdns_item {
56 	getdns_data_type dtype;
57 	getdns_union     data;
58 } getdns_item;
59 
60 typedef enum getdns_auth_state {
61 	GETDNS_AUTH_NONE,      /* Not tried (Oppotunistic)*/
62 	GETDNS_AUTH_FAILED,    /* Tried but failed or not possible*/
63 	GETDNS_AUTH_OK,        /* Tried and worked (Strict) */
64 } getdns_auth_state_t;
65 
66 #define GETDNS_STR_AUTH_NONE "None"
67 #define GETDNS_STR_AUTH_FAILED "Failed"
68 #define GETDNS_STR_AUTH_OK "Success"
69 
70 struct getdns_context;
71 struct getdns_upstreams;
72 struct getdns_upstream;
73 
74 /* String constants for internal use */
75 #define GETDNS_STR_IPV4 "IPv4"
76 #define GETDNS_STR_IPV6 "IPv6"
77 #define GETDNS_STR_ADDRESS_TYPE "address_type"
78 #define GETDNS_STR_ADDRESS_DATA "address_data"
79 #define GETDNS_STR_PORT "port"
80 #define GETDNS_STR_EXTENSION_RETURN_BOTH_V4_AND_V6 "return_both_v4_and_v6"
81 
82 #define GETDNS_STR_KEY_STATUS "status"
83 #define GETDNS_STR_KEY_REPLIES_TREE "replies_tree"
84 #define GETDNS_STR_KEY_REPLIES_FULL "replies_full"
85 #define GETDNS_STR_KEY_JUST_ADDRS "just_address_answers"
86 #define GETDNS_STR_KEY_CANONICAL_NM "canonical_name"
87 #define GETDNS_STR_KEY_ANSWER_TYPE "answer_type"
88 #define GETDNS_STR_KEY_INTERM_ALIASES "intermediate_aliases"
89 #define GETDNS_STR_KEY_NAME "name"
90 #define GETDNS_STR_KEY_HEADER "header"
91 #define GETDNS_STR_KEY_QUESTION "question"
92 #define GETDNS_STR_KEY_ANSWER "answer"
93 #define GETDNS_STR_KEY_TYPE "type"
94 #define GETDNS_STR_KEY_CLASS "class"
95 #define GETDNS_STR_KEY_TTL "ttl"
96 #define GETDNS_STR_KEY_RDATA "rdata"
97 #define GETDNS_STR_KEY_V4_ADDR "ipv4_address"
98 #define GETDNS_STR_KEY_V6_ADDR "ipv6_address"
99 #define GETDNS_STR_KEY_RDATA_RAW "rdata_raw"
100 #define GETDNS_STR_KEY_AUTHORITY "authority"
101 #define GETDNS_STR_KEY_ADDITIONAL "additional"
102 #define GETDNS_STR_KEY_QTYPE "qtype"
103 #define GETDNS_STR_KEY_QCLASS "qclass"
104 #define GETDNS_STR_KEY_QNAME "qname"
105 #define GETDNS_STR_KEY_QR "qr"
106 /* header flags */
107 #define GETDNS_STR_KEY_ID "id"
108 #define GETDNS_STR_KEY_OPCODE "opcode"
109 #define GETDNS_STR_KEY_RCODE "rcode"
110 #define GETDNS_STR_KEY_AA "aa"
111 #define GETDNS_STR_KEY_TC "tc"
112 #define GETDNS_STR_KEY_RD "rd"
113 #define GETDNS_STR_KEY_RA "ra"
114 #define GETDNS_STR_KEY_AD "ad"
115 #define GETDNS_STR_KEY_CD "cd"
116 #define GETDNS_STR_KEY_Z "z"
117 #define GETDNS_STR_KEY_QDCOUNT "qdcount"
118 #define GETDNS_STR_KEY_ANCOUNT "ancount"
119 #define GETDNS_STR_KEY_NSCOUNT "nscount"
120 #define GETDNS_STR_KEY_ARCOUNT "arcount"
121 
122 #define TIMEOUT_FOREVER ((uint64_t)0xFFFFFFFFFFFFFFFF)
123 #define ASSERT_UNREACHABLE 0
124 
125 #define GETDNS_TRANSPORTS_MAX 3
126 #define GETDNS_UPSTREAM_TRANSPORTS 2
127 #define GETDNS_TRANSPORT_FAIL_MULT 5
128 
129 
130 /* declarations */
131 struct getdns_dns_req;
132 struct getdns_network_req;
133 
134 typedef void (*internal_cb_t)(struct getdns_dns_req *dns_req);
135 
136 #define MF_PLAIN ((void *)&plain_mem_funcs_user_arg)
137 extern void *plain_mem_funcs_user_arg;
138 
139 typedef union {
140         struct {
141             void *(*malloc)(size_t);
142             void *(*realloc)(void *, size_t);
143             void (*free)(void *);
144         } pln;
145         struct {
146             void *(*malloc)(void *userarg, size_t);
147             void *(*realloc)(void *userarg, void *, size_t);
148             void (*free)(void *userarg, void *);
149         } ext;
150     } mf_union;
151 
152 struct mem_funcs {
153     void *mf_arg;
154     mf_union mf;
155 };
156 
157 struct mem_funcs *
158 priv_getdns_context_mf(getdns_context *context);
159 
160 typedef enum network_req_state_enum
161 {
162 	NET_REQ_NOT_SENT  =  0,
163 	NET_REQ_IN_FLIGHT =  1,
164 	NET_REQ_FINISHED  =  2, /* Finish type in bits 2 and 3 */
165 	NET_REQ_CANCELED  =  6, /* 2 + (1 << 2) */
166 	NET_REQ_TIMED_OUT = 10, /* 2 + (2 << 2) */
167 	NET_REQ_ERRORED   = 14  /* 2 + (3 << 2) */
168 } network_req_state;
169 
170 
171 /* State for async tcp stub resolving */
172 typedef struct getdns_tcp_state {
173 
174 	const uint8_t *write_buf;
175 	size_t   write_buf_len;
176 	size_t   written;
177 
178 	uint8_t *read_buf;
179 	size_t   read_buf_len;
180 	uint8_t *read_pos;
181 	size_t   to_read;
182 
183 } getdns_tcp_state;
184 
185 /**
186  * Request data
187  **/
188 typedef struct getdns_network_req
189 {
190 	/* For storage in upstream->netreq_by_query_id */
191 	_getdns_rbnode_t  node;
192 	/* The netreq_by_query_id tree in which this netreq was registered */
193 	_getdns_rbtree_t *query_id_registered;
194 #ifdef HAVE_MDNS_SUPPORT
195 	/*
196 	 * for storage of continuous query context in hash table of cached results.
197 	 */
198 	struct getdns_network_req * mdns_netreq_next;
199 #endif /* HAVE_MDNS_SUPPORT */
200 	/* the async_id from unbound */
201 	int unbound_id;
202 	/* state var */
203 	network_req_state state;
204 	/* owner request (contains name) */
205 	struct getdns_dns_req *owner;
206 
207 	/* request type */
208 	uint16_t request_type;
209 
210 	/* dnssec status */
211 	int dnssec_status;
212 
213 	/* tsig status:
214 	 * GETDNS_DNSSEC_INDETERMINATE means "No TSIG processing"
215 	 * GETDNS_DNSSEC_INSECURE      means "TSIG sent, validate reply"
216 	 * GETDNS_DNSSEC_SECURE        means "Validated"
217 	 * GETDNS_DNSSEC_BOGUS         means "Validation failed"
218 	 */
219 	int tsig_status;
220 
221 	getdns_redirects_t      follow_redirects;
222 
223 	/* For stub resolving */
224 	struct getdns_upstream *first_upstream;
225 	struct getdns_upstream *upstream;
226 	int                     fd;
227 	getdns_transport_list_t transports[GETDNS_TRANSPORTS_MAX];
228 	size_t                  transport_count;
229 	size_t                  transport_current;
230 	getdns_tls_authentication_t  tls_auth_min;
231 	getdns_eventloop_event  event;
232 
233 	int                     edns_maximum_udp_payload_size;
234 	uint16_t                max_udp_payload_size;
235 
236 	size_t                  keepalive_sent;
237 
238 	/* Network requests scheduled to write after me */
239 	struct getdns_network_req *write_queue_tail;
240 
241 	/* Some fields to record info for return_call_reporting */
242 	uint64_t                debug_start_time;
243 	uint64_t                debug_end_time;
244 	getdns_auth_state_t     debug_tls_auth_status;
245 	getdns_bindata          debug_tls_peer_cert;
246 	const char             *debug_tls_version;
247 	size_t                  debug_udp;
248 
249 	/* When more space is needed for the wire_data response than is
250 	 * available in wire_data[], it will be allocated separately.
251 	 * response will then not point to wire_data anymore.
252 	 */
253 	uint8_t *query;
254 	uint8_t *opt; /* offset of OPT RR in query */
255 
256 	/* each network_req has a set of base options that are
257 	 * specific to the query, which are static and included when
258 	 * the network_req is created.  When the query is sent out to
259 	 * a given upstream, some additional options are added that
260 	 * are specific to the upstream.  There can be at most
261 	 * GETDNS_MAXIMUM_UPSTREAM_OPTION_SPACE bytes of
262 	 * upstream-specific options.
263 
264 	 * use _getdns_network_req_clear_upstream_options() and
265 	 * _getdns_network_req_add_upstream_option() to fiddle with the
266 	 */
267 	size_t   base_query_option_sz;
268 	size_t   response_len;
269 	uint8_t *response;
270 	size_t   wire_data_sz;
271 	uint8_t  wire_data[];
272 
273 } getdns_network_req;
274 
_getdns_netreq_finished(getdns_network_req * req)275 static inline int _getdns_netreq_finished(getdns_network_req *req)
276 { return !req || (req->state & NET_REQ_FINISHED); }
277 
278 struct chain_head;
279 /**
280  * dns request - manages a number of network requests and
281  * the initial data passed to getdns_general
282  */
283 typedef struct getdns_dns_req {
284 	/* For storage in context->outbound_requests */
285 	_getdns_rbnode_t node;
286 
287 	/* name */
288 	uint8_t name[256];
289 	size_t  name_len;
290 
291 	uint16_t request_class;
292 
293 	/* context that owns the request */
294 	struct getdns_context *context;
295 
296 	getdns_append_name_t append_name;
297 	const uint8_t *suffix;
298 	size_t  suffix_len;
299 	unsigned suffix_appended			: 1;
300 
301 	/* request extensions */
302 	unsigned dnssec					: 1;
303 	unsigned dnssec_return_status			: 1;
304 	unsigned dnssec_return_only_secure		: 1;
305 	unsigned dnssec_return_all_statuses		: 1;
306 	unsigned dnssec_return_validation_chain		: 1;
307 	unsigned dnssec_return_full_validation_chain	: 1;
308 	unsigned dnssec_extension_set                   : 1;
309 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
310 	unsigned dnssec_roadblock_avoidance		: 1;
311 	unsigned avoid_dnssec_roadblocks		: 1;
312 #endif
313 	unsigned edns_cookies				: 1;
314 	unsigned edns_client_subnet_private		: 1;
315 	unsigned return_call_reporting			: 1;
316 	unsigned add_warning_for_bad_dns		: 1;
317 
318 	/* Internally used by return_validation_chain */
319 	unsigned dnssec_ok_checking_disabled		: 1;
320 	unsigned is_sync_request			: 1;
321 	unsigned is_dns_request				: 1;
322 	unsigned request_timed_out			: 1;
323 
324 	/* The validating and freed variables are used to make sure a single
325 	 * code path is followed while processing a DNS request, even when
326 	 * callbacks are already fired whilst the registering/scheduling call
327 	 * (i.e. ub_resolve_event) has not returned yet.
328 	 *
329 	 * validating is touched by _getdns_get_validation_chain only and
330 	 * freed      is touched by _getdns_submit_netreq only
331 	 */
332 	unsigned validating				: 1;
333 	unsigned waiting_for_ta                         : 1;
334 	int *freed;
335 
336 	/* Validation chain to be canceled when this request is canceled */
337 	struct chain_head *chain;
338 
339 	uint16_t tls_query_padding_blocksize;
340 
341 	/* internally scheduled request */
342 	internal_cb_t internal_cb;
343 
344 	/* event loop */
345 	getdns_eventloop *loop;
346 
347 	/* callback data */
348 	getdns_callback_t user_callback;
349 	void *user_pointer;
350 
351 	/* the transaction id */
352 	getdns_transaction_t trans_id;
353 
354 	/* Absolute time (in milliseconds since epoch),
355 	 * after which this dns request is expired; i.e. timed out
356 	 */
357 	uint64_t expires;
358 
359 	/* for scheduling timeouts when using libunbound */
360 	getdns_eventloop_event timeout;
361 
362 	/* mem funcs */
363 	struct mem_funcs my_mf;
364 
365 	/* Stuff for stub resolving */
366 	struct getdns_upstreams *upstreams;
367 
368 	/* Linked list pointer for dns requests, for which answers are received
369 	 * from open connections as aside-effect of doing a synchronous call.
370 	 * See also the type definition of getdns_upstream in context.h for a
371 	 * more elaborate description.
372 	 */
373 	struct getdns_dns_req *finished_next;
374 
375 	/* Linked list pointer for dns requests, which need to validate DNSSEC
376 	 * and are waiting for the root trust-anchors fetch.
377 	 */
378 	struct getdns_dns_req *ta_notify;
379 
380 	/* network requests for this dns request.
381 	 * The array is terminated with NULL.
382 	 *
383 	 * Memory for these netreqs has been allocated by the same malloc
384 	 * operation that reserved space for this getdns_dns_req.
385 	 * They will thus be freed as part of the destruction of this struct,
386 	 * and do not need to be freed separately.
387 	 */
388 	getdns_network_req *netreqs[];
389 
390 } getdns_dns_req;
391 
392 #define GETDNS_XMALLOC(obj, type, count)	\
393     ((obj).mf_arg == MF_PLAIN \
394     ? ((type *)(*(obj).mf.pln.malloc)(              (count)*sizeof(type))) \
395     : ((type *)(*(obj).mf.ext.malloc)((obj).mf_arg, (count)*sizeof(type))) \
396     )
397 
398 #define GETDNS_XREALLOC(obj, ptr, type, count)	\
399     ((obj).mf_arg == MF_PLAIN \
400     ? ((type *)(*(obj).mf.pln.realloc)( (ptr), (count)*sizeof(type))) \
401     : ((type *)(*(obj).mf.ext.realloc)( (obj).mf_arg                  \
402                                       , (ptr), (count)*sizeof(type))) \
403     )
404 
405 #define GETDNS_FREE(obj, ptr)	\
406     ((obj).mf_arg == MF_PLAIN \
407     ? ((*(obj).mf.pln.free)(              (ptr))) \
408     : ((*(obj).mf.ext.free)((obj).mf_arg, (ptr))) \
409     )
410 
411 #define GETDNS_NULL_FREE(obj, ptr)	\
412 	do { \
413 		if (!(ptr)) \
414 			break; \
415 		if ((obj).mf_arg == MF_PLAIN) \
416 			(*(obj).mf.pln.free)(              (ptr)); \
417 		else \
418 			(*(obj).mf.ext.free)((obj).mf_arg, (ptr)); \
419 		(ptr) = NULL; \
420 	} while (0);
421 
422 #define GETDNS_MALLOC(obj, type)	GETDNS_XMALLOC(obj, type, 1)
423 #define GETDNS_REALLOC(obj, ptr, type)	GETDNS_XREALLOC(obj, ptr, type, 1);
424 
425 
426 /* utility methods */
427 
428 extern getdns_dict *dnssec_ok_checking_disabled;
429 extern getdns_dict *dnssec_ok_checking_disabled_roadblock_avoidance;
430 extern getdns_dict *dnssec_ok_checking_disabled_avoid_roadblocks;
431 extern getdns_dict *no_dnssec_checking_disabled_opportunistic;
432 
433 /* dns request utils */
434 getdns_dns_req *_getdns_dns_req_new(getdns_context *context, getdns_eventloop *loop,
435     const char *name, uint16_t request_type, const getdns_dict *extensions,
436     uint64_t *now_ms);
437 
438 void _getdns_dns_req_free(getdns_dns_req * req);
439 
440 /* network request utils */
441 getdns_return_t _getdns_network_req_add_upstream_option(getdns_network_req * req,
442 					     uint16_t code, uint16_t sz, const void* data);
443 void _getdns_network_req_clear_upstream_options(getdns_network_req * req);
444 
445 /* Adds TSIG signature (if needed) and returns query length */
446 size_t _getdns_network_req_add_tsig(getdns_network_req *req);
447 
448 void _getdns_network_validate_tsig(getdns_network_req *req);
449 
450 void _getdns_netreq_reinit(getdns_network_req *netreq);
451 
452 const char * _getdns_auth_str(getdns_auth_state_t auth);
453 
454 #endif
455 /* types-internal.h */
456