1 /**
2 *
3 * \file context.h
4 * @brief getdns context management functions
5 *
6 * Originally taken from the getdns API description pseudo implementation.
7 *
8 */
9
10 /*
11 * Copyright (c) 2013, NLnet Labs, Verisign, Inc.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are met:
16 * * Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * * Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * * Neither the names of the copyright holders nor the
22 * names of its contributors may be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
29 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
32 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #ifndef _GETDNS_CONTEXT_H_
38 #define _GETDNS_CONTEXT_H_
39
40 #include "getdns/getdns.h"
41 #include "getdns/getdns_extra.h"
42 #include "config.h"
43 #include "types-internal.h"
44 #include "extension/default_eventloop.h"
45 #include "util/rbtree.h"
46 #include "ub_loop.h"
47 #include "server.h"
48 #ifdef HAVE_MDNS_SUPPORT
49 #include "util/lruhash.h"
50 #endif
51 #include "rr-iter.h"
52 #include "anchor.h"
53 #include "tls.h"
54
55 struct getdns_dns_req;
56 struct ub_ctx;
57
58 enum filechgs { GETDNS_FCHG_ERRORS = -1
59 , GETDNS_FCHG_NOERROR = 0
60 , GETDNS_FCHG_NOCHANGES = 0
61 , GETDNS_FCHG_MTIME = 1
62 , GETDNS_FCHG_CTIME = 2};
63
64 /** function pointer typedefs */
65 typedef void (*getdns_update_callback) (struct getdns_context *,
66 getdns_context_code_t);
67
68 typedef void (*getdns_update_callback2) (struct getdns_context *,
69 getdns_context_code_t, void *userarg);
70
71 /* internal use only for detecting changes to system files */
72 struct filechg {
73 char fn[_GETDNS_PATH_MAX];
74 int changes;
75 int errors;
76 struct stat prevstat;
77 };
78
79 typedef enum getdns_tls_hs_state {
80 GETDNS_HS_NONE,
81 GETDNS_HS_WRITE,
82 GETDNS_HS_READ,
83 GETDNS_HS_DONE,
84 GETDNS_HS_FAILED
85 } getdns_tls_hs_state_t;
86
87 typedef enum getdns_conn_state {
88 GETDNS_CONN_CLOSED,
89 GETDNS_CONN_SETUP,
90 GETDNS_CONN_OPEN,
91 GETDNS_CONN_TEARDOWN,
92 GETDNS_CONN_BACKOFF
93 } getdns_conn_state_t;
94
95 typedef enum getdns_tasrc {
96 GETDNS_TASRC_NONE,
97 GETDNS_TASRC_ZONE,
98 GETDNS_TASRC_APP,
99 GETDNS_TASRC_FETCHING,
100 GETDNS_TASRC_XML,
101 GETDNS_TASRC_XML_UPDATE,
102 GETDNS_TASRC_FAILED
103 } getdns_tasrc;
104
105 typedef enum getdns_tsig_algo {
106 GETDNS_NO_TSIG = 0, /* Do not use tsig */
107 GETDNS_HMAC_MD5 = 1, /* 128 bits */
108 GETDNS_GSS_TSIG = 2, /* Not supported */
109 GETDNS_HMAC_SHA1 = 3, /* 160 bits */
110 GETDNS_HMAC_SHA224 = 4,
111 GETDNS_HMAC_SHA256 = 5,
112 GETDNS_HMAC_SHA384 = 6,
113 GETDNS_HMAC_SHA512 = 7
114 } getdns_tsig_algo;
115
116
117 typedef struct getdns_tsig_info {
118 getdns_tsig_algo alg;
119 const char *name;
120 size_t strlen_name;
121 const uint8_t *dname;
122 size_t dname_len;
123 size_t min_size; /* in # octets */
124 size_t max_size; /* Actual size in # octets */
125 } getdns_tsig_info;
126
127 const getdns_tsig_info *_getdns_get_tsig_info(getdns_tsig_algo tsig_alg);
128
129 /* for doing public key pinning of TLS-capable upstreams: */
130 typedef struct sha256_pin {
131 uint8_t pin[SHA256_DIGEST_LENGTH];
132 struct sha256_pin *next;
133 } sha256_pin_t;
134
135 typedef struct getdns_upstream {
136 /* backpointer to containing upstreams structure */
137 struct getdns_upstreams *upstreams;
138
139 socklen_t addr_len;
140 struct sockaddr_storage addr;
141 char addr_str[INET6_ADDRSTRLEN];
142
143 /**
144 * How is this upstream doing over UDP?
145 *
146 * to_retry = 1, back_off = 1, in context.c:upstream_init()
147 *
148 * When querying over UDP, first a upstream is selected which to_retry
149 * value > 0 in stub.c:upstream_select().
150 *
151 * Every time a udp request times out, to_retry is decreased, and if
152 * it reaches 0, it is set to minus back_off in
153 * stub.c:stub_next_upstream().
154 *
155 * to_retry will become > 0 again. because each time an upstream is
156 * selected for a UDP query in stub.c:upstream_select(), all to_retry
157 * counters <= 0 are incremented.
158 *
159 * On continuous failure, the stubs are less likely to be reselected,
160 * because each time to_retry is set to minus back_off, in
161 * stub.c:stub_next_upstream(), the back_off value is doubled.
162 *
163 * Finally, if all upstreams are failing, the upstreams with the
164 * smallest back_off value will be selected, and the back_off value
165 * decremented by one.
166 */
167 int to_retry; /* (initialized to 1) */
168 int back_off; /* (initialized to 1) */
169 size_t udp_responses;
170 size_t udp_timeouts;
171
172 /* For stateful upstreams, need to share the connection and track the
173 activity on the connection */
174 int fd;
175 getdns_transport_list_t transport;
176 getdns_eventloop_event event;
177 getdns_eventloop *loop;
178 getdns_tcp_state tcp;
179 /* These are running totals or historical info */
180 size_t conn_completed;
181 size_t conn_shutdowns;
182 size_t conn_setup_failed;
183 time_t conn_retry_time;
184 uint16_t conn_backoff_interval;
185 size_t conn_backoffs;
186 size_t total_responses;
187 size_t total_timeouts;
188 getdns_auth_state_t best_tls_auth_state;
189 getdns_auth_state_t last_tls_auth_state;
190 /* These are per connection. */
191 getdns_conn_state_t conn_state;
192 size_t queries_sent;
193 size_t responses_received;
194 size_t responses_timeouts;
195 size_t keepalive_shutdown;
196 uint64_t keepalive_timeout;
197 int server_keepalive_received;
198
199 /* Management of outstanding requests on stateful transports */
200 getdns_network_req *write_queue;
201 getdns_network_req *write_queue_last;
202 _getdns_rbtree_t netreq_by_query_id;
203
204 /* TCP specific connection handling*/
205 unsigned tfo_use_sendto : 1;
206 /* TLS specific connection handling*/
207 unsigned tls_fallback_ok : 1;
208 _getdns_tls_connection* tls_obj;
209 _getdns_tls_session* tls_session;
210 getdns_tls_hs_state_t tls_hs_state;
211 getdns_auth_state_t tls_auth_state;
212
213 /* TLS settings */
214 char *tls_cipher_list;
215 char *tls_ciphersuites;
216 char *tls_curves_list;
217 getdns_tls_version_t tls_min_version;
218 getdns_tls_version_t tls_max_version;
219
220 /* Auth credentials */
221 char tls_auth_name[256];
222 sha256_pin_t *tls_pubkey_pinset;
223
224 /* When requests have been scheduled asynchronously on an upstream
225 * that is kept open, and a synchronous call is then done with the
226 * upstream before all scheduled requests have been answered, answers
227 * for the asynchronous requests may be received on the open upstream.
228 * Those cannot be processed immediately, because then asynchronous
229 * callbacks will be fired as a side-effect.
230 *
231 * finished_dnsreqs is a list of dnsreqs for which answers have been
232 * received during a synchronous request. They will be processed
233 * when the asynchronous eventloop is run. For this the finished_event
234 * will be scheduled to the registered asynchronous event loop with a
235 * timeout of 1, so it will fire immediately (but not while scheduling)
236 * when the asynchronous eventloop is run.
237 */
238 getdns_dns_req *finished_dnsreqs;
239 getdns_eventloop_event finished_event;
240 unsigned is_sync_loop : 1;
241
242 /* EDNS cookies */
243 uint32_t secret;
244 uint8_t client_cookie[8];
245 uint8_t prev_client_cookie[8];
246 uint8_t server_cookie[32];
247
248 unsigned has_client_cookie : 1;
249 unsigned has_prev_client_cookie : 1;
250 unsigned has_server_cookie : 1;
251 unsigned server_cookie_len : 5;
252
253 /* TSIG */
254 uint8_t tsig_dname[256];
255 size_t tsig_dname_len;
256 size_t tsig_size;
257 uint8_t tsig_key[256];
258 getdns_tsig_algo tsig_alg;
259
260 } getdns_upstream;
261
262 typedef struct getdns_log_config {
263 getdns_logfunc_type func;
264 void *userarg;
265 uint64_t system;
266 getdns_loglevel_type level;
267 } getdns_log_config;
268
269 typedef struct getdns_upstreams {
270 struct mem_funcs mf;
271 size_t referenced;
272 size_t count;
273 size_t current_udp;
274 size_t current_stateful;
275 uint16_t max_backoff_value;
276 uint16_t tls_backoff_time;
277 uint16_t tls_connection_retries;
278 getdns_log_config log;
279 getdns_upstream upstreams[];
280 } getdns_upstreams;
281
282 typedef enum tas_state {
283 TAS_LOOKUP_ADDRESSES = 0,
284 TAS_WRITE_GET_XML,
285 TAS_READ_XML_HDR,
286 TAS_READ_XML_DOC,
287 TAS_WRITE_GET_PS7,
288 TAS_READ_PS7_HDR,
289 TAS_READ_PS7_DOC,
290 TAS_DONE,
291 TAS_RETRY,
292 TAS_RETRY_GET_PS7,
293 TAS_RETRY_PS7_HDR,
294 TAS_RETRY_PS7_DOC,
295 TAS_RETRY_DONE
296 } tas_state;
297
298 typedef enum _getdns_property {
299 PROP_INHERIT = 0,
300 PROP_UNKNOWN = 1,
301 PROP_UNABLE = 2,
302 PROP_ABLE = 3
303 } _getdns_property;
304
305 typedef struct tas_connection {
306 getdns_eventloop *loop;
307 getdns_network_req *req;
308 _getdns_rrset_spc rrset_spc;
309 _getdns_rrset *rrset;
310 _getdns_rrtype_iter rr_spc;
311 _getdns_rrtype_iter *rr;
312 int fd;
313 getdns_eventloop_event event;
314 tas_state state;
315 getdns_tcp_state tcp;
316 char *http;
317 getdns_bindata xml;
318 } tas_connection;
319
320 struct getdns_context {
321 /* Context values */
322 getdns_resolution_t resolution_type;
323 getdns_namespace_t *namespaces;
324 size_t namespace_count;
325 uint64_t timeout;
326 uint64_t idle_timeout;
327 getdns_redirects_t follow_redirects;
328 getdns_list *dns_root_servers;
329
330 #if defined(HAVE_LIBUNBOUND) && !defined(HAVE_UB_CTX_SET_STUB)
331 char root_servers_fn[FILENAME_MAX];
332 #endif
333 getdns_append_name_t append_name;
334 /* Suffix buffer containing a list of (length byte | dname) where
335 * length bytes contains the length of the following dname.
336 * The last dname should be the zero byte.
337 */
338 const uint8_t *suffixes;
339 /* Length of all suffixes in the suffix buffer */
340 size_t suffixes_len;
341
342 uint8_t *trust_anchors;
343 size_t trust_anchors_len;
344 getdns_tasrc trust_anchors_source;
345
346 tas_connection a;
347 tas_connection aaaa;
348 uint8_t tas_hdr_spc[512];
349
350 char *trust_anchors_url;
351 char *trust_anchors_verify_CA;
352 char *trust_anchors_verify_email;
353 uint64_t trust_anchors_backoff_time;
354 uint64_t trust_anchors_backoff_expiry;
355
356 _getdns_ksks root_ksk;
357
358 char *appdata_dir;
359 _getdns_property can_write_appdata;
360
361 char *tls_ca_path;
362 char *tls_ca_file;
363 char *tls_cipher_list;
364 char *tls_ciphersuites;
365 char *tls_curves_list;
366 getdns_tls_version_t tls_min_version;
367 getdns_tls_version_t tls_max_version;
368
369 getdns_upstreams *upstreams;
370 uint16_t limit_outstanding_queries;
371 uint32_t dnssec_allowed_skew;
372 getdns_tls_authentication_t tls_auth; /* What user requested for TLS*/
373 getdns_tls_authentication_t tls_auth_min; /* Derived minimum auth allowed*/
374 uint8_t round_robin_upstreams;
375 uint16_t max_backoff_value;
376 uint16_t tls_backoff_time;
377 uint16_t tls_connection_retries;
378
379 getdns_transport_list_t *dns_transports;
380 size_t dns_transport_count;
381
382 uint8_t edns_extended_rcode;
383 uint8_t edns_version;
384 uint8_t edns_do_bit;
385 int edns_maximum_udp_payload_size; /* -1 is unset */
386 uint8_t edns_client_subnet_private;
387 uint16_t tls_query_padding_blocksize;
388 _getdns_tls_context* tls_ctx;
389
390 getdns_update_callback update_callback;
391 getdns_update_callback2 update_callback2;
392 void *update_userarg;
393
394 getdns_log_config log;
395
396 int processing;
397 int destroying;
398
399 struct mem_funcs mf;
400 struct mem_funcs my_mf;
401
402 #ifdef HAVE_LIBUNBOUND
403 /* The underlying contexts that do the real work */
404 struct ub_ctx *unbound_ctx;
405 int unbound_ta_set;
406 #ifdef HAVE_UNBOUND_EVENT_API
407 _getdns_ub_loop ub_loop;
408 #endif
409 #endif
410 /* A tree to hold local host information*/
411 _getdns_rbtree_t local_hosts;
412
413 /* which resolution type the contexts are configured for
414 * 0 means nothing set
415 */
416 getdns_resolution_t resolution_type_set;
417
418 /*
419 * outbound requests -> transaction to getdns_dns_req
420 */
421 _getdns_rbtree_t outbound_requests;
422
423 /* network requests
424 */
425 size_t netreqs_in_flight;
426
427 _getdns_rbtree_t pending_netreqs;
428 getdns_network_req *first_pending_netreq;
429 getdns_eventloop_event pending_timeout_event;
430
431 struct listen_set *server;
432
433 /* Event loop extension. */
434 getdns_eventloop *extension;
435
436 #ifdef HAVE_LIBUNBOUND
437 getdns_eventloop_event ub_event;
438 /* lock to prevent nested ub_event scheduling */
439 int ub_event_scheduling;
440 #endif
441
442 /* The default extension */
443 _getdns_default_eventloop default_eventloop;
444 _getdns_default_eventloop sync_eventloop;
445
446 /* request extension defaults */
447 getdns_dict *header;
448 getdns_dict *add_opt_parameters;
449 unsigned add_warning_for_bad_dns : 1;
450 unsigned dnssec : 1;
451 unsigned dnssec_return_all_statuses : 1;
452 unsigned dnssec_return_full_validation_chain : 1;
453 unsigned dnssec_return_only_secure : 1;
454 unsigned dnssec_return_status : 1;
455 unsigned dnssec_return_validation_chain : 1;
456 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
457 unsigned dnssec_roadblock_avoidance : 1;
458 #endif
459 unsigned edns_cookies : 1;
460 unsigned return_api_information : 1; /* Not used */
461 unsigned return_both_v4_and_v6 : 1;
462 unsigned return_call_reporting : 1;
463 uint16_t specify_class;
464
465 /*
466 * Context for doing system queries.
467 * For example to resolve data.iana.org or to resolver the addresses
468 * of upstreams without specified addresses.
469 */
470 getdns_context *sys_ctxt;
471
472 /* List of dnsreqs that want to be notified when we have fetched a
473 * trust anchor from data.iana.org.
474 */
475 getdns_dns_req *ta_notify;
476
477 /*
478 * state data used to detect changes to the system config files
479 */
480 struct filechg fchg_resolvconf;
481 struct filechg fchg_hosts;
482
483 uint8_t trust_anchors_spc[1024];
484
485 #ifdef USE_WINSOCK
486 /* We need to run WSAStartup() to be able to use getaddrinfo() */
487 WSADATA wsaData;
488 #endif
489
490 /* MDNS */
491 #ifdef HAVE_MDNS_SUPPORT
492 /*
493 * If supporting MDNS, context may be instantiated either in basic mode
494 * or in full mode. If working in extended mode, two multicast sockets are
495 * left open, for IPv4 and IPv6. Data can be received on either socket.
496 * The context also keeps a list of open queries, characterized by a
497 * name and an RR type, and a list of received answers, characterized
498 * by name, RR type and data value.
499 */
500 int mdns_extended_support; /* 0 = no support, 1 = supported, 2 = initialization needed */
501 int mdns_connection_nb; /* typically 0 or 2 for IPv4 and IPv6 */
502 struct mdns_network_connection * mdns_connection;
503 struct lruhash * mdns_cache;
504
505 #endif /* HAVE_MDNS_SUPPORT */
506 }; /* getdns_context */
507
_getdns_check_log(const getdns_log_config * log,uint64_t system,getdns_loglevel_type level)508 static inline int _getdns_check_log(const getdns_log_config *log,
509 uint64_t system, getdns_loglevel_type level)
510 { assert(log)
511 ; return log->func && (log->system & system) && level <= log->level; }
512
_getdns_log(const getdns_log_config * log,uint64_t system,getdns_loglevel_type level,const char * fmt,...)513 static inline void _getdns_log(const getdns_log_config *log,
514 uint64_t system, getdns_loglevel_type level, const char *fmt, ...)
515 {
516 va_list args;
517
518 if (!_getdns_check_log(log, system, level))
519 return;
520
521 va_start(args, fmt);
522 log->func(log->userarg, system, level, fmt, args);
523 va_end(args);
524 }
525
_getdns_upstream_log(const getdns_upstream * up,uint64_t system,getdns_loglevel_type level,const char * fmt,...)526 static inline void _getdns_upstream_log(const getdns_upstream *up,
527 uint64_t system, getdns_loglevel_type level, const char *fmt, ...)
528 {
529 va_list args;
530
531 if (!up || !up->upstreams
532 || !_getdns_check_log(&up->upstreams->log, system, level))
533 return;
534
535 va_start(args, fmt);
536 up->upstreams->log.func(
537 up->upstreams->log.userarg, system, level, fmt, args);
538 va_end(args);
539 }
540
541
542 /** internal functions **/
543 /**
544 * Sets up the unbound contexts with stub or recursive behavior
545 * if needed.
546 * @param context previously initialized getdns_context
547 * @return GETDNS_RETURN_GOOD on success
548 */
549 getdns_return_t _getdns_context_prepare_for_resolution(getdns_context *context);
550
551 /* Register a getdns_dns_req with context.
552 * - Without pluggable unbound event API,
553 * ub_fd() is scheduled when this was the first request.
554 */
555 void _getdns_context_track_outbound_request(getdns_dns_req *dnsreq);
556
557 /* Deregister getdns_dns_req from the context.
558 * - Without pluggable unbound event API,
559 * ub_fd() is scheduled when this was the first request.
560 * - Potential timeout events will be cleared.
561 * - All associated getdns_dns_reqs (to get the validation chain)
562 * will be canceled.
563 */
564 void _getdns_context_clear_outbound_request(getdns_dns_req *dnsreq);
565
566 /* Cancels and frees a getdns_dns_req (without calling user callbacks)
567 * - Deregisters getdns_dns_req with _getdns_context_clear_outbound_request()
568 * - Cancels associated getdns_network_reqs
569 * (by calling ub_cancel() or _getdns_cancel_stub_request())
570 * - Frees the getdns_dns_req
571 */
572 void _getdns_context_cancel_request(getdns_dns_req *dnsreq);
573
574 /* Calls user callback (with GETDNS_CALLBACK_TIMEOUT + response dict), then
575 * cancels and frees the getdns_dns_req with _getdns_context_cancel_request()
576 */
577 void _getdns_context_request_timed_out(getdns_dns_req *dnsreq);
578
579 struct getdns_bindata *_getdns_bindata_copy(
580 struct mem_funcs *mfs, size_t size, const uint8_t *data);
581
582 void _getdns_bindata_destroy(
583 struct mem_funcs *mfs,
584 struct getdns_bindata *bindata);
585
586 /* perform name resolution in /etc/hosts */
587 getdns_return_t _getdns_context_local_namespace_resolve(
588 getdns_dns_req* req, struct getdns_dict **response);
589
590 void _getdns_context_ub_read_cb(void *userarg);
591
592 void _getdns_upstreams_dereference(getdns_upstreams *upstreams);
593
594 void _getdns_upstream_shutdown(getdns_upstream *upstream);
595
596 FILE *_getdns_context_get_priv_fp(
597 const getdns_context *context, const char *fn);
598 uint8_t *_getdns_context_get_priv_file(const getdns_context *context,
599 const char *fn, uint8_t *buf, size_t buf_len, size_t *file_sz);
600
601 int _getdns_context_write_priv_file(getdns_context *context,
602 const char *fn, getdns_bindata *content);
603
604 int _getdns_context_can_write_appdata(getdns_context *context);
605
606 getdns_context *_getdns_context_get_sys_ctxt(
607 getdns_context *context, getdns_eventloop *loop);
608
609 #endif /* _GETDNS_CONTEXT_H_ */
610