1 /*
2  * Copyright (c) 2014, Vsevolod Stakhov
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *	 * Redistributions of source code must retain the above copyright
9  *	   notice, this list of conditions and the following disclaimer.
10  *	 * Redistributions in binary form must reproduce the above copyright
11  *	   notice, this list of conditions and the following disclaimer in the
12  *	   documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17  * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <stdarg.h>
34 
35 #include "rdns.h"
36 #include "dns_private.h"
37 #include "ottery.h"
38 #include "util.h"
39 #include "packet.h"
40 #include "parse.h"
41 #include "logger.h"
42 #include "compression.h"
43 
44 static int
rdns_send_request(struct rdns_request * req,int fd,bool new_req)45 rdns_send_request (struct rdns_request *req, int fd, bool new_req)
46 {
47 	int r;
48 	struct rdns_server *serv = req->io->srv;
49 	struct rdns_resolver *resolver = req->resolver;
50 	struct rdns_request *tmp;
51 	struct dns_header *header;
52 	const int max_id_cycles = 32;
53 
54 	/* Find ID collision */
55 	if (new_req) {
56 		r = 0;
57 		HASH_FIND_INT (req->io->requests, &req->id, tmp);
58 		while (tmp != NULL) {
59 			/* Check for unique id */
60 			header = (struct dns_header *)req->packet;
61 			header->qid = rdns_permutor_generate_id ();
62 			req->id = header->qid;
63 			if (++r > max_id_cycles) {
64 				return -1;
65 			}
66 			HASH_FIND_INT (req->io->requests, &req->id, tmp);
67 		}
68 	}
69 
70 	if (resolver->curve_plugin == NULL) {
71 		if (!req->io->connected) {
72 			r = sendto (fd, req->packet, req->pos, 0,
73 					req->io->saddr,
74 					req->io->slen);
75 		}
76 		else {
77 			r = send (fd, req->packet, req->pos, 0);
78 		}
79 	}
80 	else {
81 		if (!req->io->connected) {
82 			r = resolver->curve_plugin->cb.curve_plugin.send_cb (req,
83 					resolver->curve_plugin->data,
84 					req->io->saddr,
85 					req->io->slen);
86 		}
87 		else {
88 			r = resolver->curve_plugin->cb.curve_plugin.send_cb (req,
89 					resolver->curve_plugin->data,
90 					NULL,
91 					0);
92 		}
93 	}
94 	if (r == -1) {
95 		if (errno == EAGAIN || errno == EINTR) {
96 			if (new_req) {
97 				/* Write when socket is ready */
98 				HASH_ADD_INT (req->io->requests, id, req);
99 				req->async_event = resolver->async->add_write (resolver->async->data,
100 					fd, req);
101 				req->state = RDNS_REQUEST_WAIT_SEND;
102 			}
103 			/*
104 			 * If request is already processed then the calling function
105 			 * should take care about events processing
106 			 */
107 			return 0;
108 		}
109 		else {
110 			rdns_debug ("send failed: %s for server %s", strerror (errno), serv->name);
111 			return -1;
112 		}
113 	}
114 	else if (!req->io->connected) {
115 		/* Connect socket */
116 		r = connect (fd, req->io->saddr, req->io->slen);
117 
118 		if (r == -1) {
119 			rdns_err ("cannot connect after sending request: %s for server %s",
120 					strerror (errno), serv->name);
121 		}
122 		else {
123 			req->io->connected = true;
124 		}
125 	}
126 
127 	if (new_req) {
128 		/* Add request to hash table */
129 		HASH_ADD_INT (req->io->requests, id, req);
130 		/* Fill timeout */
131 		req->async_event = resolver->async->add_timer (resolver->async->data,
132 				req->timeout, req);
133 		req->state = RDNS_REQUEST_WAIT_REPLY;
134 	}
135 
136 	return 1;
137 }
138 
139 
140 static struct rdns_reply *
rdns_make_reply(struct rdns_request * req,enum dns_rcode rcode)141 rdns_make_reply (struct rdns_request *req, enum dns_rcode rcode)
142 {
143 	struct rdns_reply *rep;
144 
145 	rep = malloc (sizeof (struct rdns_reply));
146 	if (rep != NULL) {
147 		rep->request = req;
148 		rep->resolver = req->resolver;
149 		rep->entries = NULL;
150 		rep->code = rcode;
151 		req->reply = rep;
152 		rep->flags = 0;
153 		rep->requested_name = req->requested_names[0].name;
154 	}
155 
156 	return rep;
157 }
158 
159 static struct rdns_request *
rdns_find_dns_request(uint8_t * in,struct rdns_io_channel * ioc)160 rdns_find_dns_request (uint8_t *in, struct rdns_io_channel *ioc)
161 {
162 	struct dns_header *header = (struct dns_header *)in;
163 	struct rdns_request *req;
164 	int id;
165 	struct rdns_resolver *resolver = ioc->resolver;
166 
167 	id = header->qid;
168 	HASH_FIND_INT (ioc->requests, &id, req);
169 	if (req == NULL) {
170 		/* No such requests found */
171 		rdns_debug ("DNS request with id %d has not been found for IO channel", (int)id);
172 	}
173 
174 	return req;
175 }
176 
177 static bool
rdns_parse_reply(uint8_t * in,int r,struct rdns_request * req,struct rdns_reply ** _rep)178 rdns_parse_reply (uint8_t *in, int r, struct rdns_request *req,
179 		struct rdns_reply **_rep)
180 {
181 	struct dns_header *header = (struct dns_header *)in;
182 	struct rdns_reply *rep;
183 	struct rdns_reply_entry *elt;
184 	uint8_t *pos, *npos;
185 	struct rdns_resolver *resolver = req->resolver;
186 	uint16_t qdcount;
187 	int type;
188 	bool found = false;
189 
190 	int i, t;
191 
192 	/* First check header fields */
193 	if (header->qr == 0) {
194 		rdns_info ("got request while waiting for reply");
195 		return false;
196 	}
197 
198 	qdcount = ntohs (header->qdcount);
199 
200 	if (qdcount != req->qcount) {
201 		rdns_info ("request has %d queries, reply has %d queries", (int)req->qcount, (int)header->qdcount);
202 		return false;
203 	}
204 
205 	/*
206 	 * Now we have request and query data is now at the end of header, so compare
207 	 * request QR section and reply QR section
208 	 */
209 	req->pos = sizeof (struct dns_header);
210 	pos = in + sizeof (struct dns_header);
211 	t = r - sizeof (struct dns_header);
212 	for (i = 0; i < (int)qdcount; i ++) {
213 		if ((npos = rdns_request_reply_cmp (req, pos,t)) == NULL) {
214 			rdns_info ("DNS request with id %d is for different query, ignoring", (int)req->id);
215 			return false;
216 		}
217 		t -= npos - pos;
218 		pos = npos;
219 	}
220 	/*
221 	 * Now pos is in answer section, so we should extract data and form reply
222 	 */
223 	rep = rdns_make_reply (req, header->rcode);
224 
225 	if (header->ad) {
226 		rep->flags |= RDNS_AUTH;
227 	}
228 
229 	if (header->tc) {
230 		rep->flags |= RDNS_TRUNCATED;
231 	}
232 
233 	if (rep == NULL) {
234 		rdns_warn ("Cannot allocate memory for reply");
235 		return false;
236 	}
237 
238 	type = req->requested_names[0].type;
239 
240 	if (rep->code == RDNS_RC_NOERROR) {
241 		r -= pos - in;
242 		/* Extract RR records */
243 		for (i = 0; i < ntohs (header->ancount); i ++) {
244 			elt = malloc (sizeof (struct rdns_reply_entry));
245 			t = rdns_parse_rr (resolver, in, elt, &pos, rep, &r);
246 			if (t == -1) {
247 				free (elt);
248 				rdns_debug ("incomplete reply");
249 				break;
250 			}
251 			else if (t == 1) {
252 				DL_APPEND (rep->entries, elt);
253 				if (elt->type == type) {
254 					found = true;
255 				}
256 			}
257 			else {
258 				rdns_debug ("no matching reply for %s",
259 						req->requested_names[0].name);
260 				free (elt);
261 			}
262 		}
263 	}
264 
265 	if (!found && type != RDNS_REQUEST_ANY) {
266 		/* We have not found the requested RR type */
267 		if (rep->code == RDNS_RC_NOERROR) {
268 			rep->code = RDNS_RC_NOREC;
269 		}
270 	}
271 
272 	*_rep = rep;
273 	return true;
274 }
275 
276 void
rdns_process_read(int fd,void * arg)277 rdns_process_read (int fd, void *arg)
278 {
279 	struct rdns_io_channel *ioc = arg;
280 	struct rdns_resolver *resolver;
281 	struct rdns_request *req = NULL;
282 	ssize_t r;
283 	struct rdns_reply *rep;
284 	uint8_t in[UDP_PACKET_SIZE];
285 
286 	resolver = ioc->resolver;
287 
288 	/* First read packet from socket */
289 	if (resolver->curve_plugin == NULL) {
290 		r = recv (fd, in, sizeof (in), 0);
291 		if (r > (int)(sizeof (struct dns_header) + sizeof (struct dns_query))) {
292 			req = rdns_find_dns_request (in, ioc);
293 		}
294 	}
295 	else {
296 		r = resolver->curve_plugin->cb.curve_plugin.recv_cb (ioc, in,
297 				sizeof (in), resolver->curve_plugin->data, &req,
298 				ioc->saddr, ioc->slen);
299 		if (req == NULL &&
300 				r > (int)(sizeof (struct dns_header) + sizeof (struct dns_query))) {
301 			req = rdns_find_dns_request (in, ioc);
302 		}
303 	}
304 
305 	if (req != NULL) {
306 		if (rdns_parse_reply (in, r, req, &rep)) {
307 			UPSTREAM_OK (req->io->srv);
308 
309 			if (req->resolver->ups && req->io->srv->ups_elt) {
310 				req->resolver->ups->ok (req->io->srv->ups_elt,
311 						req->resolver->ups->data);
312 			}
313 
314 			rdns_request_unschedule (req);
315 			req->state = RDNS_REQUEST_REPLIED;
316 			req->func (rep, req->arg);
317 			REF_RELEASE (req);
318 		}
319 	}
320 	else {
321 		/* Still want to increase uses */
322 		ioc->uses ++;
323 	}
324 }
325 
326 void
rdns_process_timer(void * arg)327 rdns_process_timer (void *arg)
328 {
329 	struct rdns_request *req = (struct rdns_request *)arg;
330 	struct rdns_reply *rep;
331 	int r;
332 	bool renew = false;
333 	struct rdns_resolver *resolver;
334 	struct rdns_server *serv = NULL;
335 	unsigned cnt;
336 
337 	req->retransmits --;
338 	resolver = req->resolver;
339 
340 	if (req->resolver->ups && req->io->srv->ups_elt) {
341 		req->resolver->ups->fail (req->io->srv->ups_elt,
342 				req->resolver->ups->data, "timeout waiting reply");
343 	}
344 	else {
345 		UPSTREAM_FAIL (req->io->srv, time (NULL));
346 	}
347 
348 	if (req->retransmits == 0) {
349 
350 		rep = rdns_make_reply (req, RDNS_RC_TIMEOUT);
351 		rdns_request_unschedule (req);
352 		req->state = RDNS_REQUEST_REPLIED;
353 		req->func (rep, req->arg);
354 		REF_RELEASE (req);
355 
356 		return;
357 	}
358 
359 	if (!req->io->active || req->retransmits == 1) {
360 
361 		if (resolver->ups) {
362 			cnt = resolver->ups->count (resolver->ups->data);
363 		}
364 		else {
365 			cnt = 0;
366 			UPSTREAM_FOREACH (resolver->servers, serv) {
367 				cnt ++;
368 			}
369 		}
370 
371 		if (!req->io->active || cnt > 1) {
372 			/* Do not reschedule IO requests on inactive sockets */
373 			rdns_debug ("reschedule request with id: %d", (int)req->id);
374 			rdns_request_unschedule (req);
375 			REF_RELEASE (req->io);
376 
377 			if (resolver->ups) {
378 				struct rdns_upstream_elt *elt;
379 
380 				elt = resolver->ups->select_retransmit (
381 						req->requested_names[0].name,
382 						req->requested_names[0].len,
383 						req->io->srv->ups_elt,
384 						resolver->ups->data);
385 
386 				if (elt) {
387 					serv = elt->server;
388 					serv->ups_elt = elt;
389 				}
390 				else {
391 					UPSTREAM_SELECT_ROUND_ROBIN (resolver->servers, serv);
392 				}
393 			}
394 			else {
395 				UPSTREAM_SELECT_ROUND_ROBIN (resolver->servers, serv);
396 			}
397 
398 			if (serv == NULL) {
399 				rdns_warn ("cannot find suitable server for request");
400 				rep = rdns_make_reply (req, RDNS_RC_SERVFAIL);
401 				req->state = RDNS_REQUEST_REPLIED;
402 				req->func (rep, req->arg);
403 				REF_RELEASE (req);
404 
405 				return;
406 			}
407 
408 			/* Select random IO channel */
409 			req->io = serv->io_channels[ottery_rand_uint32 () % serv->io_cnt];
410 			req->io->uses ++;
411 			REF_RETAIN (req->io);
412 			renew = true;
413 		}
414 	}
415 
416 	/*
417 	 * Note: when `renew` is true, then send_request deals with the
418 	 * timers and events itself
419 	 */
420 	r = rdns_send_request (req, req->io->sock, renew);
421 	if (r == 0) {
422 		/* Retransmit one more time */
423 		if (!renew) {
424 			req->async->del_timer (req->async->data,
425 					req->async_event);
426 			req->async_event = req->async->add_write (req->async->data,
427 					req->io->sock, req);
428 		}
429 
430 		req->state = RDNS_REQUEST_WAIT_SEND;
431 	}
432 	else if (r == -1) {
433 		if (req->resolver->ups && req->io->srv->ups_elt) {
434 			req->resolver->ups->fail (req->io->srv->ups_elt,
435 					req->resolver->ups->data, "cannot send retransmit after timeout");
436 		}
437 		else {
438 			UPSTREAM_FAIL (req->io->srv, time (NULL));
439 		}
440 
441 		if (!renew) {
442 			req->async->del_timer (req->async->data,
443 					req->async_event);
444 			req->async_event = NULL;
445 			HASH_DEL (req->io->requests, req);
446 		}
447 
448 		/* We have not scheduled timeout actually due to send error */
449 		rep = rdns_make_reply (req, RDNS_RC_NETERR);
450 		req->state = RDNS_REQUEST_REPLIED;
451 		req->func (rep, req->arg);
452 		REF_RELEASE (req);
453 	}
454 	else {
455 		req->async->repeat_timer (req->async->data, req->async_event);
456 		req->state = RDNS_REQUEST_WAIT_REPLY;
457 	}
458 }
459 
460 static void
rdns_process_periodic(void * arg)461 rdns_process_periodic (void *arg)
462 {
463 	struct rdns_resolver *resolver = (struct rdns_resolver*)arg;
464 
465 	UPSTREAM_RESCAN (resolver->servers, time (NULL));
466 }
467 
468 static void
rdns_process_ioc_refresh(void * arg)469 rdns_process_ioc_refresh (void *arg)
470 {
471 	struct rdns_resolver *resolver = (struct rdns_resolver*)arg;
472 	struct rdns_server *serv;
473 	struct rdns_io_channel *ioc, *nioc;
474 	unsigned int i;
475 
476 	if (resolver->max_ioc_uses > 0) {
477 		UPSTREAM_FOREACH (resolver->servers, serv) {
478 			for (i = 0; i < serv->io_cnt; i ++) {
479 				ioc = serv->io_channels[i];
480 				if (ioc->uses > resolver->max_ioc_uses) {
481 					/* Schedule IOC removing */
482 					nioc = calloc (1, sizeof (struct rdns_io_channel));
483 					if (nioc == NULL) {
484 						rdns_err ("calloc fails to allocate rdns_io_channel");
485 						continue;
486 					}
487 					nioc->sock = rdns_make_client_socket (serv->name, serv->port,
488 							SOCK_DGRAM, &nioc->saddr, &nioc->slen);
489 					if (nioc->sock == -1) {
490 						rdns_err ("cannot open socket to %s: %s", serv->name,
491 								strerror (errno));
492 						free (nioc);
493 						continue;
494 					}
495 					nioc->srv = serv;
496 					nioc->active = true;
497 					nioc->resolver = resolver;
498 					nioc->async_io = resolver->async->add_read (resolver->async->data,
499 							nioc->sock, nioc);
500 					REF_INIT_RETAIN (nioc, rdns_ioc_free);
501 					serv->io_channels[i] = nioc;
502 					rdns_debug ("scheduled io channel for server %s to be refreshed after "
503 							"%lu usages", serv->name, (unsigned long)ioc->uses);
504 					ioc->active = false;
505 					REF_RELEASE (ioc);
506 				}
507 			}
508 		}
509 	}
510 }
511 
512 void
rdns_process_retransmit(int fd,void * arg)513 rdns_process_retransmit (int fd, void *arg)
514 {
515 	struct rdns_request *req = (struct rdns_request *)arg;
516 	struct rdns_resolver *resolver;
517 	struct rdns_reply *rep;
518 	int r;
519 
520 	resolver = req->resolver;
521 
522 	resolver->async->del_write (resolver->async->data,
523 			req->async_event);
524 	req->async_event = NULL;
525 
526 	if (req->state == RDNS_REQUEST_FAKE) {
527 		/* Reply is ready */
528 		req->func (req->reply, req->arg);
529 		REF_RELEASE (req);
530 
531 		return;
532 	}
533 
534 	r = rdns_send_request (req, fd, false);
535 
536 	if (r == 0) {
537 		/* Retransmit one more time */
538 		req->async_event = req->async->add_write (req->async->data,
539 						fd, req);
540 		req->state = RDNS_REQUEST_WAIT_SEND;
541 	}
542 	else if (r == -1) {
543 		if (req->resolver->ups && req->io->srv->ups_elt) {
544 			req->resolver->ups->fail (req->io->srv->ups_elt,
545 					req->resolver->ups->data, "retransmit send failed");
546 		}
547 		else {
548 			UPSTREAM_FAIL (req->io->srv, time (NULL));
549 		}
550 
551 		rep = rdns_make_reply (req, RDNS_RC_NETERR);
552 		req->state = RDNS_REQUEST_REPLIED;
553 		req->func (rep, req->arg);
554 		REF_RELEASE (req);
555 	}
556 	else {
557 		req->async_event = req->async->add_timer (req->async->data,
558 			req->timeout, req);
559 		req->state = RDNS_REQUEST_WAIT_REPLY;
560 	}
561 }
562 
563 struct rdns_server *
rdns_select_request_upstream(struct rdns_resolver * resolver,struct rdns_request * req,bool is_retransmit,struct rdns_server * prev_serv)564 rdns_select_request_upstream (struct rdns_resolver *resolver,
565 							  struct rdns_request *req,
566 							  bool is_retransmit,
567 							  struct rdns_server *prev_serv)
568 {
569 	struct rdns_server *serv = NULL;
570 
571 	if (resolver->ups) {
572 		struct rdns_upstream_elt *elt;
573 
574 		if (is_retransmit && prev_serv) {
575 			elt = resolver->ups->select_retransmit (req->requested_names[0].name,
576 					req->requested_names[0].len,
577 					prev_serv->ups_elt,
578 					resolver->ups->data);
579 		}
580 		else {
581 			elt = resolver->ups->select (req->requested_names[0].name,
582 					req->requested_names[0].len, resolver->ups->data);
583 		}
584 
585 		if (elt) {
586 			serv = elt->server;
587 			serv->ups_elt = elt;
588 		}
589 		else {
590 			UPSTREAM_SELECT_ROUND_ROBIN (resolver->servers, serv);
591 		}
592 	}
593 	else {
594 		UPSTREAM_SELECT_ROUND_ROBIN (resolver->servers, serv);
595 	}
596 
597 	return serv;
598 }
599 
600 #define align_ptr(p, a)                                                   \
601     (guint8 *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
602 
603 struct rdns_request*
rdns_make_request_full(struct rdns_resolver * resolver,dns_callback_type cb,void * cbdata,double timeout,unsigned int repeats,unsigned int queries,...)604 rdns_make_request_full (
605 		struct rdns_resolver *resolver,
606 		dns_callback_type cb,
607 		void *cbdata,
608 		double timeout,
609 		unsigned int repeats,
610 		unsigned int queries,
611 		...
612 		)
613 {
614 	va_list args;
615 	struct rdns_request *req;
616 	struct rdns_server *serv;
617 	int r, type;
618 	unsigned int i, tlen = 0, clen = 0, cur;
619 	size_t olen;
620 	const char *cur_name, *last_name = NULL;
621 	struct rdns_compression_entry *comp = NULL;
622 	struct rdns_fake_reply *fake_rep = NULL;
623 	char fake_buf[MAX_FAKE_NAME + sizeof (struct rdns_fake_reply_idx) + 16];
624 	struct rdns_fake_reply_idx *idx;
625 
626 	if (resolver == NULL || !resolver->initialized) {
627 		if (resolver == NULL) {
628 			return NULL;
629 		}
630 
631 		rdns_err ("resolver is uninitialized");
632 
633 		return NULL;
634 	}
635 
636 	req = malloc (sizeof (struct rdns_request));
637 	if (req == NULL) {
638 		rdns_err ("failed to allocate memory for request: %s",
639 				strerror (errno));
640 		return NULL;
641 	}
642 
643 	req->resolver = resolver;
644 	req->func = cb;
645 	req->arg = cbdata;
646 	req->reply = NULL;
647 	req->qcount = queries;
648 	req->io = NULL;
649 	req->state = RDNS_REQUEST_NEW;
650 	req->packet = NULL;
651 	req->requested_names = calloc (queries, sizeof (struct rdns_request_name));
652 	req->async_event = NULL;
653 
654 	if (req->requested_names == NULL) {
655 		free (req);
656 		rdns_err ("failed to allocate memory for request data: %s",
657 				strerror (errno));
658 
659 		return NULL;
660 	}
661 
662 	req->type = 0;
663 #ifdef TWEETNACL
664 	req->curve_plugin_data = NULL;
665 #endif
666 	REF_INIT_RETAIN (req, rdns_request_free);
667 
668 	/* Calculate packet's total length based on records count */
669 	va_start (args, queries);
670 	for (i = 0; i < queries * 2; i += 2) {
671 		cur = i / 2;
672 		cur_name = va_arg (args, const char *);
673 		type = va_arg (args, int);
674 
675 		if (cur_name != NULL) {
676 			clen = strlen (cur_name);
677 
678 			if (clen == 0) {
679 				rdns_warn ("got empty name to resolve");
680 				rdns_request_free (req);
681 				return NULL;
682 			}
683 
684 			if (cur_name[0] == '.') {
685 				/* Skip dots at the begin */
686 				unsigned int ndots = strspn (cur_name, ".");
687 
688 				cur_name += ndots;
689 				clen -= ndots;
690 
691 				if (clen == 0) {
692 					rdns_warn ("got empty name to resolve");
693 					rdns_request_free (req);
694 					return NULL;
695 				}
696 			}
697 
698 			if (cur_name[clen - 1] == '.') {
699 				/* Skip trailing dots */
700 				while (clen >= 1 && cur_name[clen - 1] == '.') {
701 					clen --;
702 				}
703 
704 				if (clen == 0) {
705 					rdns_warn ("got empty name to resolve");
706 					rdns_request_free (req);
707 					return NULL;
708 				}
709 			}
710 
711 			if (last_name == NULL && queries == 1 && clen < MAX_FAKE_NAME) {
712 				/* We allocate structure in the static space */
713 				idx = (struct rdns_fake_reply_idx *)align_ptr (fake_buf, 16);
714 				idx->type = type;
715 				idx->len = clen;
716 				memcpy (idx->request, cur_name, clen);
717 				HASH_FIND (hh, resolver->fake_elts, idx, sizeof (*idx) + clen,
718 						fake_rep);
719 
720 				if (fake_rep) {
721 					/* We actually treat it as a short-circuit */
722 					req->reply = rdns_make_reply (req, fake_rep->rcode);
723 					req->reply->entries = fake_rep->result;
724 					req->state = RDNS_REQUEST_FAKE;
725 				}
726 			}
727 
728 			last_name = cur_name;
729 			tlen += clen;
730 		}
731 		else if (last_name == NULL) {
732 			rdns_err ("got NULL as the first name to resolve");
733 			rdns_request_free (req);
734 			return NULL;
735 		}
736 
737 		if (req->state != RDNS_REQUEST_FAKE) {
738 			if (!rdns_format_dns_name (resolver, last_name, clen,
739 					&req->requested_names[cur].name, &olen)) {
740 				rdns_err ("cannot format %s", last_name);
741 				rdns_request_free (req);
742 				return NULL;
743 			}
744 
745 			req->requested_names[cur].len = olen;
746 		}
747 		else {
748 			req->requested_names[cur].len = clen;
749 		}
750 
751 		req->requested_names[cur].type = type;
752 	}
753 
754 	va_end (args);
755 
756 	if (req->state != RDNS_REQUEST_FAKE) {
757 		rdns_allocate_packet (req, tlen);
758 		rdns_make_dns_header (req, queries);
759 
760 		for (i = 0; i < queries; i++) {
761 			cur_name = req->requested_names[i].name;
762 			clen = req->requested_names[i].len;
763 			type = req->requested_names[i].type;
764 			if (queries > 1) {
765 				if (!rdns_add_rr (req, cur_name, clen, type, &comp)) {
766 					rdns_err ("cannot add rr");
767 					REF_RELEASE (req);
768 					rnds_compression_free (comp);
769 					return NULL;
770 				}
771 			} else {
772 				if (!rdns_add_rr (req, cur_name, clen, type, NULL)) {
773 					rdns_err ("cannot add rr");
774 					REF_RELEASE (req);
775 					rnds_compression_free (comp);
776 					return NULL;
777 				}
778 			}
779 		}
780 
781 		rnds_compression_free (comp);
782 
783 		/* Add EDNS RR */
784 		rdns_add_edns0 (req);
785 
786 		req->retransmits = repeats ? repeats : 1;
787 		req->timeout = timeout;
788 		req->state = RDNS_REQUEST_NEW;
789 	}
790 
791 	req->async = resolver->async;
792 
793 	serv = rdns_select_request_upstream (resolver, req, false, NULL);
794 
795 	if (serv == NULL) {
796 		rdns_warn ("cannot find suitable server for request");
797 		REF_RELEASE (req);
798 		return NULL;
799 	}
800 
801 	/* Select random IO channel */
802 	req->io = serv->io_channels[ottery_rand_uint32 () % serv->io_cnt];
803 
804 	if (req->state == RDNS_REQUEST_FAKE) {
805 		req->async_event = resolver->async->add_write (resolver->async->data,
806 				req->io->sock, req);
807 	}
808 	else {
809 		/* Now send request to server */
810 		do {
811 			r = rdns_send_request (req, req->io->sock, true);
812 
813 			if (r == -1) {
814 				req->retransmits --; /* It must be > 0 */
815 
816 				if (req->retransmits > 0) {
817 					if (resolver->ups && serv->ups_elt) {
818 						resolver->ups->fail (serv->ups_elt, resolver->ups->data,
819 								"send IO error");
820 					}
821 					else {
822 						UPSTREAM_FAIL (serv, time (NULL));
823 					}
824 
825 					serv = rdns_select_request_upstream (resolver, req,
826 							true, serv);
827 
828 					if (serv == NULL) {
829 						rdns_warn ("cannot find suitable server for request");
830 						REF_RELEASE (req);
831 						return NULL;
832 					}
833 
834 					req->io = serv->io_channels[ottery_rand_uint32 () % serv->io_cnt];
835 				}
836 				else {
837 					rdns_info ("cannot send DNS request: %s", strerror (errno));
838 					REF_RELEASE (req);
839 
840 					if (resolver->ups && serv->ups_elt) {
841 						resolver->ups->fail (serv->ups_elt, resolver->ups->data,
842 								"send IO error");
843 					}
844 					else {
845 						UPSTREAM_FAIL (serv, time (NULL));
846 					}
847 
848 					return NULL;
849 				}
850 			}
851 			else {
852 				/* All good */
853 				req->io->uses++;
854 				break;
855 			}
856 		} while (req->retransmits > 0);
857 	}
858 
859 	REF_RETAIN (req->io);
860 	REF_RETAIN (req->resolver);
861 
862 	return req;
863 }
864 
865 bool
rdns_resolver_init(struct rdns_resolver * resolver)866 rdns_resolver_init (struct rdns_resolver *resolver)
867 {
868 	unsigned int i;
869 	struct rdns_server *serv;
870 	struct rdns_io_channel *ioc;
871 
872 	if (!resolver->async_binded) {
873 		rdns_err ("no async backend specified");
874 		return false;
875 	}
876 
877 	if (resolver->servers == NULL) {
878 		rdns_err ("no DNS servers defined");
879 		return false;
880 	}
881 
882 	/* Now init io channels to all servers */
883 	UPSTREAM_FOREACH (resolver->servers, serv) {
884 		serv->io_channels = calloc (serv->io_cnt, sizeof (struct rdns_io_channel *));
885 		for (i = 0; i < serv->io_cnt; i ++) {
886 			ioc = calloc (1, sizeof (struct rdns_io_channel));
887 			if (ioc == NULL) {
888 				rdns_err ("cannot allocate memory for the resolver IO channels");
889 				return false;
890 			}
891 
892 			ioc->sock = rdns_make_client_socket (serv->name, serv->port, SOCK_DGRAM,
893 					&ioc->saddr, &ioc->slen);
894 
895 			if (ioc->sock == -1) {
896 				ioc->active = false;
897 				rdns_err ("cannot open socket to %s:%d %s",
898 						serv->name, serv->port, strerror (errno));
899 				free (ioc);
900 				return false;
901 			}
902 			else {
903 				ioc->srv = serv;
904 				ioc->resolver = resolver;
905 				ioc->async_io = resolver->async->add_read (resolver->async->data,
906 						ioc->sock, ioc);
907 				REF_INIT_RETAIN (ioc, rdns_ioc_free);
908 				serv->io_channels[i] = ioc;
909 			}
910 		}
911 	}
912 
913 	if (resolver->async->add_periodic) {
914 		resolver->periodic = resolver->async->add_periodic (resolver->async->data,
915 				UPSTREAM_REVIVE_TIME, rdns_process_periodic, resolver);
916 	}
917 
918 	resolver->initialized = true;
919 
920 	return true;
921 }
922 
923 void
rdns_resolver_register_plugin(struct rdns_resolver * resolver,struct rdns_plugin * plugin)924 rdns_resolver_register_plugin (struct rdns_resolver *resolver,
925 		struct rdns_plugin *plugin)
926 {
927 	if (resolver != NULL && plugin != NULL) {
928 		/* XXX: support only network plugin now, and only a single one */
929 		if (plugin->type == RDNS_PLUGIN_CURVE) {
930 			resolver->curve_plugin = plugin;
931 		}
932 	}
933 }
934 
935 void *
rdns_resolver_add_server(struct rdns_resolver * resolver,const char * name,unsigned int port,int priority,unsigned int io_cnt)936 rdns_resolver_add_server (struct rdns_resolver *resolver,
937 		const char *name, unsigned int port,
938 		int priority, unsigned int io_cnt)
939 {
940 	struct rdns_server *serv;
941 	union {
942 		struct in_addr v4;
943 		struct in6_addr v6;
944 	} addr;
945 
946 	if (inet_pton (AF_INET, name, &addr) == 0 &&
947 		inet_pton (AF_INET6, name, &addr) == 0) {
948 		/* Invalid IP */
949 		return NULL;
950 	}
951 
952 	if (io_cnt == 0) {
953 		return NULL;
954 	}
955 	if (port == 0 || port > UINT16_MAX) {
956 		return NULL;
957 	}
958 
959 	serv = calloc (1, sizeof (struct rdns_server));
960 	if (serv == NULL) {
961 		return NULL;
962 	}
963 	serv->name = strdup (name);
964 	if (serv->name == NULL) {
965 		free (serv);
966 		return NULL;
967 	}
968 
969 	serv->io_cnt = io_cnt;
970 	serv->port = port;
971 
972 	UPSTREAM_ADD (resolver->servers, serv, priority);
973 
974 	return serv;
975 }
976 
977 void
rdns_resolver_set_logger(struct rdns_resolver * resolver,rdns_log_function logger,void * log_data)978 rdns_resolver_set_logger (struct rdns_resolver *resolver,
979 		rdns_log_function logger, void *log_data)
980 {
981 	resolver->logger = logger;
982 	resolver->log_data = log_data;
983 }
984 
985 void
rdns_resolver_set_log_level(struct rdns_resolver * resolver,enum rdns_log_level level)986 rdns_resolver_set_log_level (struct rdns_resolver *resolver,
987 		enum rdns_log_level level)
988 {
989 	resolver->log_level = level;
990 }
991 
992 void
rdns_resolver_set_upstream_lib(struct rdns_resolver * resolver,struct rdns_upstream_context * ups_ctx,void * ups_data)993 rdns_resolver_set_upstream_lib (struct rdns_resolver *resolver,
994 		struct rdns_upstream_context *ups_ctx,
995 		void *ups_data)
996 {
997 	resolver->ups = ups_ctx;
998 	resolver->ups->data = ups_data;
999 }
1000 
1001 
1002 void
rdns_resolver_set_max_io_uses(struct rdns_resolver * resolver,uint64_t max_ioc_uses,double check_time)1003 rdns_resolver_set_max_io_uses (struct rdns_resolver *resolver,
1004 		uint64_t max_ioc_uses, double check_time)
1005 {
1006 	if (resolver->refresh_ioc_periodic != NULL) {
1007 		resolver->async->del_periodic (resolver->async->data,
1008 				resolver->refresh_ioc_periodic);
1009 		resolver->refresh_ioc_periodic = NULL;
1010 	}
1011 
1012 	resolver->max_ioc_uses = max_ioc_uses;
1013 	if (check_time > 0.0 && resolver->async->add_periodic) {
1014 		resolver->refresh_ioc_periodic =
1015 				resolver->async->add_periodic (resolver->async->data,
1016 				check_time, rdns_process_ioc_refresh, resolver);
1017 	}
1018 }
1019 
1020 static void
rdns_resolver_free(struct rdns_resolver * resolver)1021 rdns_resolver_free (struct rdns_resolver *resolver)
1022 {
1023 	struct rdns_server *serv, *stmp;
1024 	struct rdns_io_channel *ioc;
1025 	unsigned int i;
1026 
1027 	if (resolver->initialized) {
1028 		if (resolver->periodic != NULL) {
1029 			resolver->async->del_periodic (resolver->async->data, resolver->periodic);
1030 		}
1031 		if (resolver->refresh_ioc_periodic != NULL) {
1032 			resolver->async->del_periodic (resolver->async->data,
1033 					resolver->refresh_ioc_periodic);
1034 		}
1035 		if (resolver->curve_plugin != NULL && resolver->curve_plugin->dtor != NULL) {
1036 			resolver->curve_plugin->dtor (resolver, resolver->curve_plugin->data);
1037 		}
1038 		/* Stop IO watch on all IO channels */
1039 		UPSTREAM_FOREACH_SAFE (resolver->servers, serv, stmp) {
1040 			for (i = 0; i < serv->io_cnt; i ++) {
1041 				ioc = serv->io_channels[i];
1042 				REF_RELEASE (ioc);
1043 			}
1044 			serv->io_cnt = 0;
1045 			UPSTREAM_DEL (resolver->servers, serv);
1046 			free (serv->io_channels);
1047 			free (serv->name);
1048 			free (serv);
1049 		}
1050 	}
1051 	free (resolver->async);
1052 	free (resolver);
1053 }
1054 
1055 
1056 struct rdns_resolver *
rdns_resolver_new(int flags)1057 rdns_resolver_new (int flags)
1058 {
1059 	struct rdns_resolver     *new_resolver;
1060 
1061 	new_resolver = calloc (1, sizeof (struct rdns_resolver));
1062 
1063 	REF_INIT_RETAIN (new_resolver, rdns_resolver_free);
1064 
1065 	new_resolver->logger = rdns_logger_internal;
1066 	new_resolver->log_data = new_resolver;
1067 	new_resolver->flags = flags;
1068 
1069 	return new_resolver;
1070 }
1071 
1072 void
rdns_resolver_async_bind(struct rdns_resolver * resolver,struct rdns_async_context * ctx)1073 rdns_resolver_async_bind (struct rdns_resolver *resolver,
1074 		struct rdns_async_context *ctx)
1075 {
1076 	if (resolver != NULL && ctx != NULL) {
1077 		resolver->async = ctx;
1078 		resolver->async_binded = true;
1079 	}
1080 }
1081 
1082 void
rdns_resolver_set_dnssec(struct rdns_resolver * resolver,bool enabled)1083 rdns_resolver_set_dnssec (struct rdns_resolver *resolver, bool enabled)
1084 {
1085 	if (resolver) {
1086 		resolver->enable_dnssec = enabled;
1087 	}
1088 }
1089 
1090 
rdns_resolver_set_fake_reply(struct rdns_resolver * resolver,const char * name,enum rdns_request_type type,enum dns_rcode rcode,struct rdns_reply_entry * reply)1091 void rdns_resolver_set_fake_reply (struct rdns_resolver *resolver,
1092 								   const char *name,
1093 								   enum rdns_request_type type,
1094 								   enum dns_rcode rcode,
1095 								   struct rdns_reply_entry *reply)
1096 {
1097 	struct rdns_fake_reply *fake_rep;
1098 	struct rdns_fake_reply_idx *srch;
1099 	unsigned len = strlen (name);
1100 
1101 	assert (len < MAX_FAKE_NAME);
1102 	srch = malloc (sizeof (*srch) + len);
1103 	srch->len = len;
1104 	srch->type = type;
1105 	memcpy (srch->request, name, len);
1106 
1107 	HASH_FIND (hh, resolver->fake_elts, srch, len + sizeof (*srch), fake_rep);
1108 
1109 	if (fake_rep) {
1110 		/* Append reply to the existing list */
1111 		fake_rep->rcode = rcode;
1112 
1113 		if (reply) {
1114 			DL_CONCAT (fake_rep->result, reply);
1115 		}
1116 	}
1117 	else {
1118 		fake_rep = calloc (1, sizeof (*fake_rep) + len);
1119 
1120 		if (fake_rep == NULL) {
1121 			abort ();
1122 		}
1123 
1124 		fake_rep->rcode = rcode;
1125 
1126 		memcpy (&fake_rep->key, srch, sizeof (*srch) + len);
1127 
1128 		if (reply) {
1129 			DL_CONCAT (fake_rep->result, reply);
1130 		}
1131 
1132 		HASH_ADD (hh, resolver->fake_elts, key, sizeof (*srch) + len, fake_rep);
1133 	}
1134 
1135 	free (srch);
1136 }
1137