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