]> jfr.im git - irc/evilnet/x3.git/blob - src/sar.c
fix a couple oversights in building ldap add structs
[irc/evilnet/x3.git] / src / sar.c
1 /* sar.h - srvx asynchronous resolver
2 * Copyright 2005, 2007 Michael Poole <mdpoole@troilus.org>
3 *
4 * This file is part of srvx.
5 *
6 * srvx is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with srvx; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
19 */
20
21 #include "sar.h"
22 #include "conf.h"
23 #include "ioset.h"
24 #include "log.h"
25 #include "timeq.h"
26
27 #if defined(HAVE_NETINET_IN_H)
28 # include <netinet/in.h> /* sockaddr_in6 on some BSDs */
29 #endif
30
31 static const char hexdigits[] = "0123456789abcdef";
32
33 struct dns_rr;
34 struct sar_getaddr_state;
35 struct sar_getname_state;
36
37 struct sar_family_helper {
38 const char *localhost_addr;
39 const char *unspec_addr;
40 unsigned int socklen;
41 unsigned int family;
42
43 unsigned int (*ntop)(char *output, unsigned int out_size, const struct sockaddr *sa, unsigned int socklen);
44 unsigned int (*pton)(struct sockaddr *sa, unsigned int socklen, unsigned int *bits, const char *input);
45 int (*get_port)(const struct sockaddr *sa, unsigned int socklen);
46 int (*set_port)(struct sockaddr *sa, unsigned int socklen, unsigned short port);
47 unsigned int (*build_addr_request)(struct sar_request *req, const char *node, const char *srv_node, unsigned int flags);
48 void (*build_ptr_name)(struct sar_getname_state *state, const struct sockaddr *sa, unsigned int socklen);
49 int (*decode_addr)(struct sar_getaddr_state *state, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size);
50
51 struct sar_family_helper *next;
52 };
53
54 #define MAX_FAMILY AF_INET
55 static struct sar_family_helper sar_ipv4_helper;
56
57 #if defined(AF_INET6)
58 # if AF_INET6 > MAX_FAMILY
59 # undef MAX_FAMILY
60 # define MAX_FAMILY AF_INET6
61 # endif
62 static struct sar_family_helper sar_ipv6_helper;
63 #endif
64
65 static struct sar_family_helper *sar_helpers[MAX_FAMILY+1];
66 static struct sar_family_helper *sar_first_helper;
67
68 unsigned int
69 sar_ntop(char *output, unsigned int out_size, const struct sockaddr *sa, unsigned int socklen)
70 {
71 unsigned int pos;
72 assert(output != NULL);
73 assert(sa != NULL);
74 assert(out_size > 0);
75
76 if (sa->sa_family <= MAX_FAMILY && sar_helpers[sa->sa_family]) {
77 pos = sar_helpers[sa->sa_family]->ntop(output, out_size, sa, socklen);
78 if (pos)
79 return pos;
80 }
81 *output = '\0';
82 return 0;
83 }
84
85 unsigned int
86 sar_pton(struct sockaddr *sa, unsigned int socklen, unsigned int *bits, const char *input)
87 {
88 struct sar_family_helper *helper;
89 unsigned int len;
90
91 assert(sa != NULL);
92 assert(input != NULL);
93
94 memset(sa, 0, socklen);
95 if (bits)
96 *bits = ~0;
97 for (helper = sar_first_helper; helper; helper = helper->next) {
98 if (socklen < helper->socklen)
99 continue;
100 len = helper->pton(sa, socklen, bits, input);
101 if (len) {
102 sa->sa_family = helper->family;
103 return len;
104 }
105 }
106 return 0; /* parse failed */
107 }
108
109 int
110 sar_get_port(const struct sockaddr *sa, unsigned int socklen)
111 {
112 if (sa->sa_family <= MAX_FAMILY
113 && sar_helpers[sa->sa_family]
114 && socklen >= sar_helpers[sa->sa_family]->socklen)
115 return sar_helpers[sa->sa_family]->get_port(sa, socklen);
116 else return -1;
117 }
118
119 int
120 sar_set_port(struct sockaddr *sa, unsigned int socklen, unsigned short port)
121 {
122 if (sa->sa_family <= MAX_FAMILY
123 && sar_helpers[sa->sa_family]
124 && socklen >= sar_helpers[sa->sa_family]->socklen)
125 return sar_helpers[sa->sa_family]->set_port(sa, socklen, port);
126 else return 1;
127 }
128
129 const char *
130 sar_strerror(enum sar_errcode errcode)
131 {
132 switch (errcode) {
133 case SAI_SUCCESS: return "Resolution succeeded.";
134 case SAI_FAMILY: return "The requested address family is not supported.";
135 case SAI_SOCKTYPE: return "The requested socket type is not supported.";
136 case SAI_BADFLAGS: return "Invalid flags value.";
137 case SAI_NONAME: return "Unknown name or service.";
138 case SAI_SERVICE: return "The service is unavailable for that socket type.";
139 case SAI_ADDRFAMILY: return "The host has no address in the requested family.";
140 case SAI_NODATA: return "The host has no addresses at all.";
141 case SAI_MEMORY: return "Unable to allocate memory.";
142 case SAI_FAIL: return "The nameserver indicated a permanent error.";
143 case SAI_AGAIN: return "The nameserver indicated a temporary error.";
144 case SAI_MISMATCH: return "Mismatch between reverse and forward resolution.";
145 case SAI_SYSTEM: return strerror(errno);
146 default: return "Unknown resolver error code.";
147 }
148 }
149
150 void
151 sar_free(struct addrinfo *ai)
152 {
153 struct addrinfo *next;
154 for (; ai; ai = next) {
155 next = ai->ai_next;
156 free(ai);
157 }
158 }
159
160 /** Global variables to support DNS name resolution. */
161 static struct {
162 unsigned int sar_timeout;
163 unsigned int sar_retries;
164 unsigned int sar_ndots;
165 unsigned int sar_edns0;
166 char sar_localdomain[MAXLEN];
167 struct string_list *sar_search;
168 struct string_list *sar_nslist;
169 struct sockaddr_storage sar_bind_address;
170 } conf;
171 static struct log_type *sar_log;
172
173 /* Except as otherwise noted, constants and formats are from RFC1035.
174 * This resolver is believed to implement the behaviors mandated (and
175 * in many cases those recommended) by these standards: RFC1035,
176 * RFC2671, RFC2782, RFC3596, RFC3597.
177 *
178 * Update queries (including RFC 2136) seems a likely candidate for
179 * future support.
180 * DNSSEC (including RFCs 2535, 3007, 3655, etc) is less likely until
181 * a good application is found.
182 * Caching (RFC 2308) and redirection (RFC 2672) are much less likely,
183 * since most users will have a separate local, caching, recursive
184 * nameserver.
185 * Other DNS extensions (at least through RFC 3755) are believed to be
186 * too rare or insufficiently useful to bother supporting.
187 *
188 * The following are useful Reasons For Concern:
189 * RFC1536, RFC1912, RFC2606, RFC3363, RFC3425, RFC3467
190 * http://www.iana.org/assignments/dns-parameters
191 * http://www.ietf.org/html.charters/dnsext-charter.html
192 */
193
194 struct sar_nameserver {
195 char *name;
196 unsigned int valid;
197 unsigned int req_sent;
198 unsigned int resp_used;
199 unsigned int resp_ignored;
200 unsigned int resp_servfail;
201 unsigned int resp_fallback;
202 unsigned int resp_failures;
203 unsigned int resp_scrambled;
204 unsigned int ss_len;
205 struct sockaddr_storage ss;
206 };
207
208 /* EDNS0 uses 12 bit RCODEs, TSIG/TKEY use 16 bit RCODEs.
209 * Declare local RCODE failures here.*/
210 enum {
211 RCODE_TIMED_OUT = 65536,
212 RCODE_QUERY_TOO_LONG,
213 RCODE_LABEL_TOO_LONG,
214 RCODE_SOCKET_FAILURE,
215 RCODE_DESTROYED,
216 };
217
218 #define DNS_NAME_LENGTH 256
219
220 #define RES_SIZE_FLAGS 0xc0
221 #define RES_SF_LABEL 0x00
222 #define RES_SF_POINTER 0xc0
223
224 static dict_t sar_requests;
225 static dict_t sar_nameservers;
226 static struct io_fd *sar_fd;
227 static int sar_fd_fd;
228
229 const char *
230 sar_rcode_text(unsigned int rcode)
231 {
232 switch (rcode) {
233 case RCODE_NO_ERROR: return "No error";
234 case RCODE_FORMAT_ERROR: return "Format error";
235 case RCODE_SERVER_FAILURE: return "Server failure";
236 case RCODE_NAME_ERROR: return "Name error";
237 case RCODE_NOT_IMPLEMENTED: return "Feature not implemented";
238 case RCODE_REFUSED: return "Query refused";
239 case RCODE_BAD_OPT_VERSION: return "Unsupported EDNS option version";
240 case RCODE_TIMED_OUT: return "Request timed out";
241 case RCODE_QUERY_TOO_LONG: return "Query too long";
242 case RCODE_LABEL_TOO_LONG: return "Label too long";
243 case RCODE_SOCKET_FAILURE: return "Resolver socket failure";
244 case RCODE_DESTROYED: return "Request unexpectedly destroyed";
245 default: return "Unknown rcode";
246 }
247 }
248
249 static void
250 sar_request_fail(struct sar_request *req, unsigned int rcode)
251 {
252 log_module(sar_log, LOG_DEBUG, "sar_request_fail({id=%d}, rcode=%d)", req->id, rcode);
253 req->expiry = 0;
254 if (req->cb_fail) {
255 req->cb_fail(req, rcode);
256 if (req->expiry)
257 return;
258 }
259 sar_request_abort(req);
260 }
261
262 static unsigned long next_sar_timeout;
263
264 static void
265 sar_timeout_cb(void *data)
266 {
267 dict_iterator_t it;
268 dict_iterator_t next;
269 time_t next_timeout = INT_MAX;
270
271 for (it = dict_first(sar_requests); it; it = next) {
272 struct sar_request *req;
273
274 req = iter_data(it);
275 next = iter_next(it);
276 if (req->expiry > next_timeout)
277 continue;
278 else if (req->expiry > now)
279 next_timeout = req->expiry;
280 else if (req->retries >= conf.sar_retries)
281 sar_request_fail(req, RCODE_TIMED_OUT);
282 else
283 sar_request_send(req);
284 }
285 if (next_timeout < INT_MAX) {
286 next_sar_timeout = next_timeout;
287 timeq_add(next_timeout, sar_timeout_cb, data);
288 }
289 }
290
291 static void
292 sar_check_timeout(unsigned long when)
293 {
294 if (!next_sar_timeout || when < next_sar_timeout) {
295 timeq_del(0, sar_timeout_cb, NULL, TIMEQ_IGNORE_WHEN | TIMEQ_IGNORE_DATA);
296 timeq_add(when, sar_timeout_cb, NULL);
297 next_sar_timeout = when;
298 }
299 }
300
301 static void
302 sar_request_cleanup(void *d)
303 {
304 struct sar_request *req = d;
305 log_module(sar_log, LOG_DEBUG, "sar_request_cleanup({id=%d})", req->id);
306 free(req->body);
307 if (req->cb_fail)
308 req->cb_fail(req, RCODE_DESTROYED);
309 free(req);
310 }
311
312 static void
313 sar_dns_init(const char *resolv_conf_path)
314 {
315 struct string_list *ns_sv;
316 struct string_list *ds_sv;
317 FILE *resolv_conf;
318 dict_t node;
319 const char *str;
320
321 /* Initialize configuration defaults. */
322 conf.sar_localdomain[0] = '\0';
323 conf.sar_timeout = 3;
324 conf.sar_retries = 3;
325 conf.sar_ndots = 1;
326 conf.sar_edns0 = 0;
327 ns_sv = alloc_string_list(4);
328 ds_sv = alloc_string_list(4);
329
330 /* Scan resolver configuration file. */
331 resolv_conf = fopen(resolv_conf_path, "r");
332 if (resolv_conf) {
333 char *arg, *opt;
334 unsigned int len;
335 char linebuf[LINE_MAX], ch;
336
337 while (fgets(linebuf, sizeof(linebuf), resolv_conf)) {
338 ch = linebuf[len = strcspn(linebuf, " \t\r\n")];
339 linebuf[len] = '\0';
340 arg = linebuf + len + 1;
341 if (!strcmp(linebuf, "nameserver")) {
342 while (ch == ' ') {
343 ch = arg[len = strcspn(arg, " \t\r\n")];
344 arg[len] = '\0';
345 string_list_append(ns_sv, strdup(arg));
346 arg += len + 1;
347 }
348 } else if (!strcmp(linebuf, "domain")) {
349 if (ch == ' ') {
350 safestrncpy(conf.sar_localdomain, arg, sizeof(conf.sar_localdomain));
351 }
352 } else if (!strcmp(linebuf, "search")) {
353 while (ch == ' ') {
354 ch = arg[len = strcspn(arg, " \t\r\n")];
355 arg[len] = '\0';
356 string_list_append(ds_sv, strdup(arg));
357 arg += len + 1;
358 }
359 } else if (!strcmp(linebuf, "options")) {
360 while (ch == ' ') {
361 ch = arg[len = strcspn(arg, " \t\r\n")];
362 arg[len] = '\0';
363 opt = strchr(arg, ':');
364 if (opt) {
365 *opt++ = '\0';
366 if (!strcmp(arg, "timeout")) {
367 conf.sar_timeout = atoi(opt);
368 } else if (!strcmp(arg, "attempts")) {
369 conf.sar_retries = atoi(opt);
370 } else if (!strcmp(arg, "ndots")) {
371 conf.sar_ndots = atoi(opt);
372 } else if (!strcmp(arg, "edns0")) {
373 conf.sar_edns0 = atoi(opt);
374 }
375 } else if (!strcmp(arg, "edns0")) {
376 conf.sar_edns0 = 1440;
377 }
378 arg += len + 1;
379 }
380 }
381 }
382 fclose(resolv_conf);
383 } else {
384 /* This is apparently what BIND defaults to using. */
385 string_list_append(ns_sv, "127.0.0.1");
386 }
387
388 /* Set default search path if domain is set. */
389 if (conf.sar_localdomain[0] != '\0' && ds_sv->used == 0)
390 string_list_append(ds_sv, strdup(conf.sar_localdomain));
391
392 /* Check configuration entries that might override resolv.conf. */
393 node = conf_get_data("modules/sar", RECDB_OBJECT);
394 if (node) {
395 struct sockaddr *sa;
396 struct string_list *slist;
397
398 str = database_get_data(node, "timeout", RECDB_QSTRING);
399 if (str) conf.sar_timeout = ParseInterval(str);
400 str = database_get_data(node, "retries", RECDB_QSTRING);
401 if (str) conf.sar_retries = atoi(str);
402 str = database_get_data(node, "ndots", RECDB_QSTRING);
403 if (str) conf.sar_ndots = atoi(str);
404 str = database_get_data(node, "edns0", RECDB_QSTRING);
405 if (str) conf.sar_edns0 = enabled_string(str);
406 str = database_get_data(node, "domain", RECDB_QSTRING);
407 if (str) safestrncpy(conf.sar_localdomain, str, sizeof(conf.sar_localdomain));
408 slist = database_get_data(node, "search", RECDB_STRING_LIST);
409 if (slist) {
410 free_string_list(ds_sv);
411 ds_sv = string_list_copy(slist);
412 }
413 slist = database_get_data(node, "nameservers", RECDB_STRING_LIST);
414 if (slist) {
415 free_string_list(ns_sv);
416 ns_sv = string_list_copy(slist);
417 }
418 sa = (struct sockaddr*)&conf.sar_bind_address;
419 memset(sa, 0, sizeof(conf.sar_bind_address));
420 str = database_get_data(node, "bind_address", RECDB_QSTRING);
421 if (str) sar_pton(sa, sizeof(conf.sar_bind_address), NULL, str);
422 str = database_get_data(node, "bind_port", RECDB_QSTRING);
423 if (str != NULL) {
424 if (sa->sa_family == AF_INET) {
425 struct sockaddr_in *sin = (struct sockaddr_in*)sa;
426 sin->sin_port = ntohs(atoi(str));
427 }
428 #if defined(AF_INET6)
429 else if (sa->sa_family == AF_INET6) {
430 struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
431 sin6->sin6_port = ntohs(atoi(str));
432 }
433 #endif
434 }
435 }
436
437 /* Replace config lists with their new values. */
438 free_string_list(conf.sar_search);
439 conf.sar_search = ds_sv;
440 free_string_list(conf.sar_nslist);
441 conf.sar_nslist = ns_sv;
442 }
443
444 void
445 sar_request_abort(struct sar_request *req)
446 {
447 if (!req)
448 return;
449 assert(dict_find(sar_requests, req->id_text, NULL) == req);
450 log_module(sar_log, LOG_DEBUG, "sar_request_abort({id=%d})", req->id);
451 req->cb_ok = NULL;
452 req->cb_fail = NULL;
453 dict_remove(sar_requests, req->id_text);
454 }
455
456 static struct sar_nameserver *
457 sar_our_server(const struct sockaddr_storage *ss, unsigned int ss_len)
458 {
459 dict_iterator_t it;
460
461 for (it = dict_first(sar_nameservers); it; it = iter_next(it)) {
462 struct sar_nameserver *ns;
463
464 ns = iter_data(it);
465 if (ns->ss_len == ss_len && !memcmp(ss, &ns->ss, ss_len))
466 return ns;
467 }
468 return NULL;
469 }
470
471 char *
472 sar_extract_name(const unsigned char *buf, unsigned int size, unsigned int *ppos)
473 {
474 struct string_buffer cv;
475 unsigned int pos, jumped;
476
477 pos = *ppos;
478 jumped = 0;
479 cv.used = 0;
480 cv.size = 64;
481 cv.list = calloc(1, cv.size);
482 while (1) {
483 if (pos >= size)
484 goto fail;
485 if (!buf[pos]) {
486 if (!jumped)
487 *ppos = pos + 1;
488 if (cv.used)
489 cv.list[cv.used - 1] = '\0'; /* chop off terminating '.' */
490 else
491 string_buffer_append(&cv, '\0');
492 return cv.list;
493 }
494 switch (buf[pos] & RES_SIZE_FLAGS) {
495 case RES_SF_LABEL: {
496 unsigned int len = buf[pos];
497 if (pos + len + 1 >= size)
498 goto fail;
499 string_buffer_append_substring(&cv, (char*)buf + pos + 1, len);
500 string_buffer_append(&cv, '.');
501 pos += buf[pos] + 1;
502 break;
503 }
504 case RES_SF_POINTER:
505 if ((pos + 1 >= size) || (cv.used >= size))
506 goto fail;
507 if (!jumped)
508 *ppos = pos + 2;
509 pos = (buf[pos] & ~RES_SIZE_FLAGS) << 8 | buf[pos+1];
510 jumped = 1;
511 break;
512 default:
513 goto fail;
514 }
515 }
516 fail:
517 free(cv.list);
518 return NULL;
519 }
520
521 static int
522 sar_decode_answer(struct sar_request *req, struct dns_header *hdr, unsigned char *buf, unsigned int size)
523 {
524 struct dns_rr *rr;
525 unsigned int ii, rr_count, pos;
526 int res;
527
528 /* Skip over query section. */
529 for (ii = 0, pos = 12; ii < hdr->qdcount; ++ii) {
530 /* Skip over compressed names. */
531 while (1) {
532 if (pos >= size)
533 return 2;
534 if (!buf[pos])
535 break;
536 switch (buf[pos] & RES_SIZE_FLAGS) {
537 case RES_SF_LABEL:
538 pos += buf[pos] + 1;
539 break;
540 case RES_SF_POINTER:
541 if (pos + 1 >= size)
542 return 2;
543 pos = (buf[pos] & ~RES_SIZE_FLAGS) << 8 | buf[pos+1];
544 if (pos >= size)
545 return 3;
546 break;
547 default:
548 return 4;
549 }
550 }
551 /* Skip over null terminator, type and class part of question. */
552 pos += 5;
553 }
554
555 /* Parse each RR in the answer. */
556 rr_count = hdr->ancount + hdr->nscount + hdr->arcount;
557 rr = calloc(1, rr_count * sizeof(rr[0]));
558 for (ii = 0; ii < rr_count; ++ii) {
559 rr[ii].name = sar_extract_name(buf, size, &pos);
560 if (!rr[ii].name) {
561 res = 5;
562 goto out;
563 }
564 if (pos + 10 > size) {
565 res = 6;
566 goto out;
567 }
568 rr[ii].type = buf[pos+0] << 8 | buf[pos+1];
569 rr[ii].class = buf[pos+2] << 8 | buf[pos+3];
570 rr[ii].ttl = buf[pos+4] << 24 | buf[pos+5] << 16 | buf[pos+6] << 8 | buf[pos+7];
571 rr[ii].rdlength = buf[pos+8] << 8 | buf[pos+9];
572 rr[ii].rd_start = pos + 10;
573 pos = pos + rr[ii].rdlength + 10;
574 if (pos > size) {
575 res = 7;
576 goto out;
577 }
578 }
579 res = 0;
580 req->expiry = 0;
581 req->cb_ok(req, hdr, rr, buf, size);
582 if (!req->expiry) {
583 req->cb_ok = NULL;
584 req->cb_fail = NULL;
585 dict_remove(sar_requests, req->id_text);
586 }
587
588 out:
589 while (ii > 0)
590 free(rr[--ii].name);
591 free(rr);
592 return res;
593 }
594
595 static const unsigned char *
596 sar_extract_rdata(struct dns_rr *rr, unsigned int len, unsigned char *raw, unsigned int raw_size)
597 {
598 if (len > rr->rdlength)
599 return NULL;
600 if (rr->rd_start + len > raw_size)
601 return NULL;
602 return raw + rr->rd_start;
603 }
604
605 static void
606 sar_fd_readable(struct io_fd *fd)
607 {
608 struct sockaddr_storage ss;
609 struct dns_header hdr;
610 struct sar_nameserver *ns;
611 struct sar_request *req;
612 unsigned char *buf;
613 socklen_t ss_len;
614 int res, rcode, buf_len;
615 char id_text[6];
616
617 assert(sar_fd == fd);
618 buf_len = conf.sar_edns0;
619 if (!buf_len)
620 buf_len = 512;
621 buf = alloca(buf_len);
622 ss_len = sizeof(ss);
623 res = recvfrom(sar_fd_fd, buf, buf_len, 0, (struct sockaddr*)&ss, &ss_len);
624 if (res < 12 || !(ns = sar_our_server(&ss, ss_len)))
625 return;
626 hdr.id = buf[0] << 8 | buf[1];
627 hdr.flags = buf[2] << 8 | buf[3];
628 hdr.qdcount = buf[4] << 8 | buf[5];
629 hdr.ancount = buf[6] << 8 | buf[7];
630 hdr.nscount = buf[8] << 8 | buf[9];
631 hdr.arcount = buf[10] << 8 | buf[11];
632
633 sprintf(id_text, "%d", hdr.id);
634 req = dict_find(sar_requests, id_text, NULL);
635 log_module(sar_log, LOG_DEBUG, "sar_fd_readable(%p): hdr {id=%d, flags=0x%x, qdcount=%d, ancount=%d, nscount=%d, arcount=%d} -> req %p", (void*)fd, hdr.id, hdr.flags, hdr.qdcount, hdr.ancount, hdr.nscount, hdr.arcount, (void*)req);
636 if (!req || !req->retries || !(hdr.flags & REQ_FLAG_QR)) {
637 ns->resp_ignored++;
638 return;
639 }
640 rcode = hdr.flags & REQ_FLAG_RCODE_MASK;
641 if (rcode != RCODE_NO_ERROR) {
642 sar_request_fail(req, rcode);
643 } else if (sar_decode_answer(req, &hdr, (unsigned char*)buf, res)) {
644 ns->resp_scrambled++;
645 sar_request_fail(req, RCODE_FORMAT_ERROR);
646 }
647 }
648
649 static void
650 sar_build_nslist(struct string_list *nslist)
651 {
652 dict_iterator_t it, next;
653 struct sar_nameserver *ns;
654 unsigned int ii;
655
656 for (it = dict_first(sar_nameservers); it; it = iter_next(it)) {
657 ns = iter_data(it);
658 ns->valid = 0;
659 }
660
661 for (ii = 0; ii < nslist->used; ++ii) {
662 const char *name;
663
664 name = nslist->list[ii];
665 ns = dict_find(sar_nameservers, name, NULL);
666 if (!ns) {
667 ns = calloc(1, sizeof(*ns) + strlen(name) + 1);
668 ns->name = (char*)(ns + 1);
669 strcpy(ns->name, name);
670 ns->ss_len = sizeof(ns->ss);
671 if (!sar_pton((struct sockaddr*)&ns->ss, sizeof(ns->ss), NULL, name)) {
672 free(it);
673 continue;
674 }
675 sar_set_port((struct sockaddr*)&ns->ss, sizeof(ns->ss), 53);
676 ns->ss_len = sar_helpers[ns->ss.ss_family]->socklen;
677 dict_insert(sar_nameservers, ns->name, ns);
678 }
679 ns->valid = 1;
680 }
681
682 for (it = dict_first(sar_nameservers); it; it = next) {
683 next = iter_next(it);
684 ns = iter_data(it);
685 if (!ns->valid)
686 dict_remove(sar_nameservers, ns->name);
687 }
688 }
689
690 static int
691 sar_open_fd(void)
692 {
693 int res;
694
695 /* Build list of nameservers. */
696 sar_build_nslist(conf.sar_nslist);
697
698 if (conf.sar_bind_address.ss_family != 0) {
699 struct addrinfo *ai;
700
701 ai = (struct addrinfo*)&conf.sar_bind_address;
702 sar_fd_fd = socket(ai->ai_family, SOCK_DGRAM, 0);
703 if (sar_fd_fd < 0) {
704 log_module(sar_log, LOG_FATAL, "Unable to create resolver socket: %s", strerror(errno));
705 return 1;
706 }
707
708 res = bind(sar_fd_fd, ai->ai_addr, ai->ai_addrlen);
709 if (res < 0)
710 log_module(sar_log, LOG_ERROR, "Unable to bind resolver socket to address [%s]:%s: %s", (char*)conf_get_data("modules/sar/bind_address", RECDB_QSTRING), (char*)conf_get_data("modules/sar/bind_port", RECDB_QSTRING), strerror(errno));
711 } else {
712 dict_iterator_t it;
713 struct sar_nameserver *ns;
714
715 it = dict_first(sar_nameservers);
716 ns = iter_data(it);
717 sar_fd_fd = socket(ns->ss.ss_family, SOCK_DGRAM, 0);
718 if (sar_fd_fd < 0) {
719 log_module(sar_log, LOG_FATAL, "Unable to create resolver socket: %s", strerror(errno));
720 return 1;
721 }
722 }
723
724 sar_fd = ioset_add(sar_fd_fd);
725 if (!sar_fd) {
726 log_module(sar_log, LOG_FATAL, "Unable to register resolver socket with event loop.");
727 return 1;
728 }
729 sar_fd->state = IO_CONNECTED;
730 sar_fd->readable_cb = sar_fd_readable;
731 return 0;
732 }
733
734 struct name_ofs {
735 const char *name;
736 unsigned int ofs;
737 };
738
739 static int
740 set_compare_charp(const void *a_, const void *b_)
741 {
742 char * const *a = a_, * const *b = b_;
743 return strcasecmp(*a, *b);
744 }
745
746 static void
747 string_buffer_reserve(struct string_buffer *cv, unsigned int min_length)
748 {
749 if (cv->size < min_length) {
750 char *new_buffer;
751 new_buffer = realloc(cv->list, min_length);
752 if (new_buffer) {
753 cv->size = min_length;
754 cv->list = new_buffer;
755 }
756 }
757 }
758
759 /** Append \a name to \a cv in compressed form. */
760 static int
761 sar_append_name(struct string_buffer *cv, const char *name, struct name_ofs *ofs, unsigned int *used, unsigned int alloc)
762 {
763 struct name_ofs *pofs;
764 unsigned int len;
765
766 while (1) {
767 pofs = bsearch(&name, ofs, *used, sizeof(ofs[0]), set_compare_charp);
768 if (pofs) {
769 string_buffer_reserve(cv, cv->used + 2);
770 cv->list[cv->used++] = RES_SF_POINTER | (pofs->ofs >> 8);
771 cv->list[cv->used++] = pofs->ofs & 255;
772 return 0;
773 }
774 len = strcspn(name, ".");
775 if (len > 63)
776 return 1;
777 if (*used < alloc) {
778 ofs[*used].name = name;
779 ofs[*used].ofs = cv->used;
780 qsort(ofs, (*used)++, sizeof(ofs[0]), set_compare_charp);
781 }
782 string_buffer_reserve(cv, cv->used + len + 1);
783 cv->list[cv->used] = RES_SF_LABEL | len;
784 memcpy(cv->list + cv->used + 1, name, len);
785 cv->used += len + 1;
786 if (name[len] == '.')
787 name += len + 1;
788 else if (name[len] == '\0')
789 break;
790 }
791 string_buffer_append(cv, '\0');
792 return 0;
793 }
794
795 /** Build a DNS question packet from a variable-length argument list.
796 * In \a args, there is at least one pari consisting of const char
797 * *name and unsigned int qtype. A null name argument terminates the
798 * list.
799 */
800 unsigned int
801 sar_request_vbuild(struct sar_request *req, va_list args)
802 {
803 struct name_ofs suffixes[32];
804 struct string_buffer cv;
805 const char *name;
806 unsigned int suf_used;
807 unsigned int val;
808 unsigned int qdcount;
809
810 cv.used = 0;
811 cv.size = 512;
812 cv.list = calloc(1, cv.size);
813 suf_used = 0;
814 val = REQ_OPCODE_QUERY | REQ_FLAG_RD;
815 cv.list[0] = req->id >> 8;
816 cv.list[1] = req->id & 255;
817 cv.list[2] = val >> 8;
818 cv.list[3] = val & 255;
819 cv.list[6] = cv.list[7] = cv.list[8] = cv.list[9] = cv.list[10] = 0;
820 cv.used = 12;
821 for (qdcount = 0; (name = va_arg(args, const char*)); ++qdcount) {
822 if (sar_append_name(&cv, name, suffixes, &suf_used, ArrayLength(suffixes))) {
823 string_buffer_clean(&cv);
824 goto out;
825 }
826 string_buffer_reserve(&cv, cv.used + 4);
827 val = va_arg(args, unsigned int);
828 cv.list[cv.used++] = val >> 8;
829 cv.list[cv.used++] = val & 255;
830 cv.list[cv.used++] = REQ_CLASS_IN >> 8;
831 cv.list[cv.used++] = REQ_CLASS_IN & 255;
832 }
833 cv.list[4] = qdcount >> 8;
834 cv.list[5] = qdcount & 255;
835 val = conf.sar_edns0;
836 if (val) {
837 string_buffer_reserve(&cv, cv.used + 11);
838 cv.list[cv.used + 0] = '\0'; /* empty name */
839 cv.list[cv.used + 1] = REQ_TYPE_OPT >> 8;
840 cv.list[cv.used + 2] = REQ_TYPE_OPT & 255;
841 cv.list[cv.used + 3] = val >> 8;
842 cv.list[cv.used + 4] = val & 255;
843 cv.list[cv.used + 5] = 0; /* extended-rcode */
844 cv.list[cv.used + 6] = 0; /* version */
845 cv.list[cv.used + 7] = 0; /* reserved */
846 cv.list[cv.used + 8] = 0; /* reserved */
847 cv.list[cv.used + 9] = 0; /* msb rdlen */
848 cv.list[cv.used + 10] = 0; /* lsb rdlen */
849 cv.used += 11;
850 cv.list[11] = 1; /* update arcount */
851 } else cv.list[11] = 0;
852
853 out:
854 free(req->body);
855 req->body = (unsigned char*)cv.list;
856 req->body_len = cv.used;
857 return cv.used;
858 }
859
860 /** Build a DNS question packet. After \a req, there is at least one
861 * pair consisting of const char *name and unsigned int qtype. A null
862 * name argument terminates the list.
863 */
864 unsigned int
865 sar_request_build(struct sar_request *req, ...)
866 {
867 va_list vargs;
868 unsigned int ret;
869 va_start(vargs, req);
870 ret = sar_request_vbuild(req, vargs);
871 va_end(vargs);
872 return ret;
873 }
874
875 void
876 sar_request_send(struct sar_request *req)
877 {
878 dict_iterator_t it;
879
880 /* make sure we have our local socket */
881 if (!sar_fd && sar_open_fd()) {
882 sar_request_fail(req, RCODE_SOCKET_FAILURE);
883 return;
884 }
885
886 log_module(sar_log, LOG_DEBUG, "sar_request_send({id=%d})", req->id);
887
888 /* send query to each configured nameserver */
889 for (it = dict_first(sar_nameservers); it; it = iter_next(it)) {
890 struct sar_nameserver *ns;
891 int res;
892
893 ns = iter_data(it);
894 res = sendto(sar_fd_fd, req->body, req->body_len, 0, (struct sockaddr*)&ns->ss, ns->ss_len);
895 if (res > 0) {
896 ns->req_sent++;
897 log_module(sar_log, LOG_DEBUG, "Sent %u bytes to %s.", res, ns->name);
898 } else if (res < 0)
899 log_module(sar_log, LOG_ERROR, "Unable to send %u bytes to nameserver %s: %s", req->body_len, ns->name, strerror(errno));
900 else /* res == 0 */
901 assert(0 && "resolver sendto() unexpectedly returned zero");
902 }
903
904 /* Check that query timeout is soon enough. */
905 req->expiry = now + (conf.sar_timeout << ++req->retries);
906 sar_check_timeout(req->expiry);
907 }
908
909 struct sar_request *
910 sar_request_alloc(unsigned int data_len, sar_request_ok_cb ok_cb, sar_request_fail_cb fail_cb)
911 {
912 struct sar_request *req;
913
914 req = calloc(1, sizeof(*req) + data_len);
915 req->cb_ok = ok_cb;
916 req->cb_fail = fail_cb;
917 do {
918 req->id = rand() & 0xffff;
919 sprintf(req->id_text, "%d", req->id);
920 } while (dict_find(sar_requests, req->id_text, NULL));
921 dict_insert(sar_requests, req->id_text, req);
922 log_module(sar_log, LOG_DEBUG, "sar_request_alloc(%d) -> {id=%d}", data_len, req->id);
923 return req;
924 }
925
926 struct sar_request *
927 sar_request_simple(unsigned int data_len, sar_request_ok_cb ok_cb, sar_request_fail_cb fail_cb, ...)
928 {
929 struct sar_request *req;
930
931 req = sar_request_alloc(data_len, ok_cb, fail_cb);
932 if (req) {
933 va_list args;
934
935 va_start(args, fail_cb);
936 sar_request_vbuild(req, args);
937 va_end(args);
938 sar_request_send(req);
939 }
940 return req;
941 }
942
943 enum service_proto {
944 SERVICE_UDP,
945 SERVICE_TCP,
946 SERVICE_NUM_PROTOS
947 };
948
949 struct service_byname {
950 const char *name; /* service name */
951 struct {
952 /* note: if valid != 0, port == 0, check canonical entry */
953 struct service_byname *canon; /* if NULL, this is canonical */
954 uint16_t port;
955 unsigned int valid : 1;
956 unsigned int srv : 1;
957 } protos[SERVICE_NUM_PROTOS];
958 };
959
960 struct service_byport {
961 unsigned int port;
962 char port_text[6];
963 struct service_byname *byname[SERVICE_NUM_PROTOS];
964 };
965
966 static dict_t services_byname; /* contains struct service_byname */
967 static dict_t services_byport; /* contains struct service_byport */
968
969 static struct service_byname *
970 sar_service_byname(const char *name, int autocreate)
971 {
972 struct service_byname *byname;
973
974 byname = dict_find(services_byname, name, NULL);
975 if (!byname && autocreate) {
976 byname = calloc(1, sizeof(*byname) + strlen(name) + 1);
977 byname->name = strcpy((char*)(byname + 1), name);
978 dict_insert(services_byname, byname->name, byname);
979 }
980 return byname;
981 }
982
983 static struct service_byport *
984 sar_service_byport(unsigned int port, int autocreate)
985 {
986 struct service_byport *byport;
987 char port_text[12];
988
989 sprintf(port_text, "%d", port);
990 byport = dict_find(services_byport, port_text, NULL);
991 if (!byport && autocreate) {
992 byport = calloc(1, sizeof(*byport));
993 byport->port = port;
994 sprintf(byport->port_text, "%d", port);
995 dict_insert(services_byport, byport->port_text, byport);
996 }
997 return byport;
998 }
999
1000 static void
1001 sar_services_load_file(const char *etc_services)
1002 {
1003 static const char *whitespace = " \t\r\n";
1004 struct service_byname *canon;
1005 struct service_byport *byport;
1006 char *name, *port, *alias, *ptr;
1007 FILE *file;
1008 unsigned int pnum;
1009 enum service_proto proto;
1010 char linebuf[LINE_MAX];
1011
1012 file = fopen(etc_services, "r");
1013 if (!file)
1014 return;
1015 while (fgets(linebuf, sizeof(linebuf), file)) {
1016 ptr = strchr(linebuf, '#');
1017 if (ptr)
1018 *ptr = '\0';
1019 /* Tokenize canonical service name and port number. */
1020 name = strtok_r(linebuf, whitespace, &ptr);
1021 if (name == NULL)
1022 continue;
1023 port = strtok_r(NULL, whitespace, &ptr);
1024 if (port == NULL)
1025 continue;
1026 pnum = strtoul(port, &port, 10);
1027 if (pnum == 0 || *port++ != '/')
1028 continue;
1029 if (!strcmp(port, "udp"))
1030 proto = SERVICE_UDP;
1031 else if (!strcmp(port, "tcp"))
1032 proto = SERVICE_TCP;
1033 else continue;
1034
1035 /* Set up canonical name-indexed service entry. */
1036 canon = sar_service_byname(name, 1);
1037 if (canon->protos[proto].valid) {
1038 /* log_module(sar_log, LOG_ERROR, "Service %s/%s listed twice.", name, port); who cares? */
1039 continue;
1040 }
1041 canon->protos[proto].canon = NULL;
1042 canon->protos[proto].port = pnum;
1043 canon->protos[proto].valid = 1;
1044
1045 /* Set up port-indexed service entry. */
1046 byport = sar_service_byport(pnum, 1);
1047 if (!byport->byname[proto])
1048 byport->byname[proto] = canon;
1049
1050 /* Add alias entries. */
1051 while ((alias = strtok_r(NULL, whitespace, &ptr))) {
1052 struct service_byname *byname;
1053
1054 byname = sar_service_byname(alias, 1);
1055 if (byname->protos[proto].valid) {
1056 /* We do not log this since there are a lot of
1057 * duplicate aliases, some only differing in case. */
1058 continue;
1059 }
1060 byname->protos[proto].canon = canon;
1061 byname->protos[proto].port = pnum;
1062 byname->protos[proto].valid = 1;
1063 }
1064 }
1065 fclose(file);
1066 }
1067
1068 static void
1069 sar_services_init(const char *etc_services)
1070 {
1071 /* These are a portion of the services listed at
1072 * http://www.dns-sd.org/ServiceTypes.html.
1073 */
1074 static const char *tcp_srvs[] = { "cvspserver", "distcc", "ftp", "http",
1075 "imap", "ipp", "irc", "ldap", "login", "nfs", "pop3", "postgresql",
1076 "rsync", "sftp-ssh", "soap", "ssh", "telnet", "webdav", "xmpp-client",
1077 "xmpp-server", "xul-http", NULL };
1078 static const char *udp_srvs[] = { "bootps", "dns-update", "domain", "nfs",
1079 "ntp", "tftp", NULL };
1080 struct service_byname *byname;
1081 unsigned int ii;
1082
1083 /* Forget old services dicts and allocate new ones. */
1084 dict_delete(services_byname);
1085 services_byname = dict_new();
1086 dict_set_free_data(services_byname, free);
1087
1088 dict_delete(services_byport);
1089 services_byport = dict_new();
1090 dict_set_free_data(services_byport, free);
1091
1092 /* Load the list from the services file. */
1093 sar_services_load_file(etc_services);
1094
1095 /* Mark well-known services as using DNS-SD SRV records. */
1096 for (ii = 0; tcp_srvs[ii]; ++ii) {
1097 byname = sar_service_byname(tcp_srvs[ii], 1);
1098 byname->protos[SERVICE_TCP].srv = 1;
1099 }
1100
1101 for (ii = 0; udp_srvs[ii]; ++ii) {
1102 byname = sar_service_byname(udp_srvs[ii], 1);
1103 byname->protos[SERVICE_UDP].srv = 1;
1104 }
1105 }
1106
1107 static void
1108 sar_register_helper(struct sar_family_helper *helper)
1109 {
1110 assert(helper->family <= MAX_FAMILY);
1111 sar_helpers[helper->family] = helper;
1112 helper->next = sar_first_helper;
1113 sar_first_helper = helper;
1114 }
1115
1116 static unsigned int
1117 sar_addrlen(const struct sockaddr *sa, UNUSED_ARG(unsigned int size))
1118 {
1119 return sa->sa_family <= MAX_FAMILY && sar_helpers[sa->sa_family]
1120 ? sar_helpers[sa->sa_family]->socklen : 0;
1121 }
1122
1123 struct sar_getaddr_state {
1124 struct sar_family_helper *helper;
1125 struct addrinfo *ai_head;
1126 struct addrinfo *ai_tail;
1127 sar_addr_cb cb;
1128 void *cb_ctx;
1129 unsigned int search_pos;
1130 unsigned int flags, socktype, protocol, port;
1131 unsigned int srv_ofs;
1132 char full_name[DNS_NAME_LENGTH];
1133 };
1134
1135 static unsigned int
1136 sar_getaddr_append(struct sar_getaddr_state *state, struct addrinfo *ai, int copy)
1137 {
1138 unsigned int count;
1139
1140 log_module(sar_log, LOG_DEBUG, "sar_getaddr_append({full_name=%s}, ai=%p, copy=%d)", state->full_name, (void*)ai, copy);
1141
1142 /* Set the appropriate pointer to the new element(s). */
1143 if (state->ai_tail)
1144 state->ai_tail->ai_next = ai;
1145 else
1146 state->ai_head = ai;
1147
1148 /* Find the end of the list. */
1149 if (copy) {
1150 /* Make sure we copy fields for both the first and last entries. */
1151 count = 1;
1152 while (1) {
1153 if (!ai->ai_addrlen) {
1154 assert(sar_helpers[ai->ai_family]);
1155 ai->ai_addrlen = sar_helpers[ai->ai_family]->socklen;
1156 }
1157 #if defined(HAVE_SOCKADDR_SA_LEN)
1158 ai->ai_addr->sa_len = ai->ai_addrlen;
1159 #endif
1160 ai->ai_addr->sa_family = ai->ai_family;
1161 ai->ai_socktype = state->socktype;
1162 ai->ai_protocol = state->protocol;
1163 if (!ai->ai_next)
1164 break;
1165 count++;
1166 ai = ai->ai_next;
1167 }
1168 } else {
1169 for (count = 1; ai->ai_next; ++count, ai = ai->ai_next)
1170 ;
1171 }
1172
1173 /* Set the tail pointer and return count of appended items. */
1174 state->ai_tail = ai;
1175 return count;
1176 }
1177
1178 static struct sar_request *
1179 sar_getaddr_request(struct sar_request *req)
1180 {
1181 struct sar_getaddr_state *state;
1182 unsigned int len;
1183 char full_name[DNS_NAME_LENGTH];
1184
1185 state = (struct sar_getaddr_state*)(req + 1);
1186
1187 /* If we can and should, append the current search domain. */
1188 if (state->search_pos < conf.sar_search->used)
1189 snprintf(full_name, sizeof(full_name), "%s.%s", state->full_name, conf.sar_search->list[state->search_pos]);
1190 else if (state->search_pos == conf.sar_search->used)
1191 safestrncpy(full_name, state->full_name, sizeof(full_name));
1192 else {
1193 log_module(sar_log, LOG_DEBUG, "sar_getaddr_request({id=%d}): failed", req->id);
1194 state->cb(state->cb_ctx, NULL, SAI_NONAME);
1195 return NULL;
1196 }
1197
1198 /* Build the appropriate request for DNS record(s). */
1199 if (state->flags & SAI_ALL)
1200 len = sar_request_build(req, full_name + state->srv_ofs, REQ_QTYPE_ALL, NULL);
1201 else if (state->srv_ofs)
1202 len = state->helper->build_addr_request(req, full_name + state->srv_ofs, full_name, state->flags);
1203 else
1204 len = state->helper->build_addr_request(req, full_name, NULL, state->flags);
1205
1206 log_module(sar_log, LOG_DEBUG, "sar_getaddr_request({id=%d}): full_name=%s, srv_ofs=%d", req->id, full_name, state->srv_ofs);
1207
1208 /* Check that the request could be built. */
1209 if (!len) {
1210 state->cb(state->cb_ctx, NULL, SAI_NODATA);
1211 return NULL;
1212 }
1213
1214 /* Send the request. */
1215 sar_request_send(req);
1216 return req;
1217 }
1218
1219 static int
1220 sar_getaddr_decode(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size, unsigned int rr_idx)
1221 {
1222 struct sar_getaddr_state *state;
1223 char *cname;
1224 unsigned int jj, pos, hit;
1225
1226 log_module(sar_log, LOG_DEBUG, " sar_getaddr_decode(id=%d, <hdr>, {type=%d, rdlength=%d, name=%s}, <data>, %u, <idx>)", hdr->id, rr[rr_idx].type, rr[rr_idx].rdlength, rr[rr_idx].name, raw_size);
1227 state = (struct sar_getaddr_state*)(req + 1);
1228
1229 switch (rr[rr_idx].type) {
1230 case REQ_TYPE_A:
1231 if (state->flags & SAI_ALL)
1232 return sar_ipv4_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1233 #if defined(AF_INET6)
1234 else if (state->flags & SAI_V4MAPPED)
1235 return sar_ipv6_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1236 #endif
1237 return state->helper->decode_addr(state, rr + rr_idx, raw, raw_size);
1238
1239 case REQ_TYPE_AAAA:
1240 #if defined(AF_INET6)
1241 if (state->flags & SAI_ALL)
1242 return sar_ipv6_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1243 return state->helper->decode_addr(state, rr + rr_idx, raw, raw_size);
1244 #else
1245 return 0;
1246 #endif
1247
1248 case REQ_TYPE_CNAME:
1249 /* there should be the canonical name next */
1250 pos = rr[rr_idx].rd_start;
1251 cname = sar_extract_name(raw, raw_size, &pos);
1252 if (!cname)
1253 return 0; /* XXX: eventually log the unhandled body */
1254 /* and it should correspond to some other answer in the response */
1255 for (jj = hit = 0; jj < hdr->ancount; ++jj) {
1256 if (strcasecmp(cname, rr[jj].name))
1257 continue;
1258 hit += sar_getaddr_decode(req, hdr, rr, raw, raw_size, jj);
1259 }
1260 /* XXX: if (!hit) handle or log the incomplete recursion; */
1261 return hit;
1262
1263 case REQ_TYPE_SRV:
1264 /* TODO: decode the SRV record */
1265
1266 default:
1267 return 0;
1268 }
1269 }
1270
1271 static void
1272 sar_getaddr_ok(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1273 {
1274 struct sar_getaddr_state *state;
1275 unsigned int ii;
1276
1277 state = (struct sar_getaddr_state*)(req + 1);
1278
1279 log_module(sar_log, LOG_DEBUG, "sar_getaddr_ok({id=%d}, {id=%d}, <rr>, <data>, %u)", req->id, hdr->id, raw_size);
1280 for (ii = 0; ii < hdr->ancount; ++ii)
1281 sar_getaddr_decode(req, hdr, rr, raw, raw_size, ii);
1282
1283 /* If we found anything, report it, else try again. */
1284 if (state->ai_head)
1285 state->cb(state->cb_ctx, state->ai_head, SAI_SUCCESS);
1286 else
1287 sar_getaddr_request(req);
1288 }
1289
1290 static void
1291 sar_getaddr_fail(struct sar_request *req, UNUSED_ARG(unsigned int rcode))
1292 {
1293 struct sar_getaddr_state *state;
1294
1295 log_module(sar_log, LOG_DEBUG, "sar_getaddr_fail({id=%d}, rcode=%u)", req->id, rcode);
1296 state = (struct sar_getaddr_state*)(req + 1);
1297 state->cb(state->cb_ctx, NULL, SAI_FAIL);
1298 }
1299
1300 struct sar_request *
1301 sar_getaddr(const char *node, const char *service, const struct addrinfo *hints_, sar_addr_cb cb, void *cb_ctx)
1302 {
1303 struct sockaddr_storage ss;
1304 struct addrinfo hints;
1305 struct sar_family_helper *helper;
1306 struct service_byname *svc;
1307 char *end;
1308 unsigned int portnum;
1309 unsigned int pos;
1310 enum service_proto proto;
1311
1312 if (!node && !service) {
1313 cb(cb_ctx, NULL, SAI_NONAME);
1314 return NULL;
1315 }
1316
1317 /* Initialize local hints structure. */
1318 if (hints_)
1319 memcpy(&hints, hints_, sizeof(hints));
1320 else
1321 memset(&hints, 0, sizeof(hints));
1322
1323 /* Translate socket type to internal protocol. */
1324 switch (hints.ai_socktype) {
1325 case 0: hints.ai_socktype = SOCK_STREAM; /* and fall through */
1326 case SOCK_STREAM: proto = SERVICE_TCP; break;
1327 case SOCK_DGRAM: proto = SERVICE_UDP; break;
1328 default:
1329 cb(cb_ctx, NULL, SAI_SOCKTYPE);
1330 return NULL;
1331 }
1332
1333 /* Figure out preferred socket size. */
1334 if (hints.ai_family == AF_UNSPEC)
1335 hints.ai_family = AF_INET;
1336 if (hints.ai_family > MAX_FAMILY
1337 || !(helper = sar_helpers[hints.ai_family])) {
1338 cb(cb_ctx, NULL, SAI_FAMILY);
1339 return NULL;
1340 }
1341 hints.ai_addrlen = helper->socklen;
1342
1343 /* If \a node is NULL, figure out the correct default from the
1344 * requested family and SAI_PASSIVE flag.
1345 */
1346 if (node == NULL)
1347 node = (hints.ai_flags & SAI_PASSIVE) ? helper->unspec_addr : helper->localhost_addr;
1348
1349 /* Try to parse (failing that, look up) \a service. */
1350 if (!service)
1351 portnum = 0, svc = NULL;
1352 else if ((portnum = strtoul(service, &end, 10)), *end == '\0')
1353 svc = NULL;
1354 else if ((svc = sar_service_byname(service, 0)) != NULL)
1355 portnum = svc->protos[proto].port;
1356 else {
1357 cb(cb_ctx, NULL, SAI_SERVICE);
1358 return NULL;
1359 }
1360
1361 /* Try to parse \a node as a numeric hostname.*/
1362 pos = sar_pton((struct sockaddr*)&ss, sizeof(ss), NULL, node);
1363 if (pos && node[pos] == '\0') {
1364 struct addrinfo *ai;
1365 char canonname[SAR_NTOP_MAX];
1366
1367 /* we have a valid address; use it */
1368 sar_set_port((struct sockaddr*)&ss, sizeof(ss), portnum);
1369 hints.ai_addrlen = sar_addrlen((struct sockaddr*)&ss, sizeof(ss));
1370 if (!hints.ai_addrlen) {
1371 cb(cb_ctx, NULL, SAI_FAMILY);
1372 return NULL;
1373 }
1374 pos = sar_ntop(canonname, sizeof(canonname), (struct sockaddr*)&ss, hints.ai_addrlen);
1375
1376 /* allocate and fill in the addrinfo response */
1377 ai = calloc(1, sizeof(*ai) + hints.ai_addrlen + pos + 1);
1378 ai->ai_family = ss.ss_family;
1379 ai->ai_socktype = hints.ai_socktype;
1380 ai->ai_protocol = hints.ai_protocol;
1381 ai->ai_addrlen = hints.ai_addrlen;
1382 ai->ai_addr = memcpy(ai + 1, &ss, ai->ai_addrlen);
1383 ai->ai_canonname = strcpy((char*)ai->ai_addr + ai->ai_addrlen, canonname);
1384 cb(cb_ctx, ai, SAI_SUCCESS);
1385 return NULL;
1386 } else if (hints.ai_flags & SAI_NUMERICHOST) {
1387 cb(cb_ctx, NULL, SAI_NONAME);
1388 return NULL;
1389 } else {
1390 struct sar_request *req;
1391 struct sar_getaddr_state *state;
1392 unsigned int len, ii;
1393
1394 req = sar_request_alloc(sizeof(*state), sar_getaddr_ok, sar_getaddr_fail);
1395
1396 state = (struct sar_getaddr_state*)(req + 1);
1397 state->helper = helper;
1398 state->ai_head = state->ai_tail = NULL;
1399 state->cb = cb;
1400 state->cb_ctx = cb_ctx;
1401 state->flags = hints.ai_flags;
1402 state->socktype = hints.ai_socktype;
1403 state->protocol = hints.ai_protocol;
1404 state->port = portnum;
1405
1406 if ((state->flags & SAI_NOSRV) || !svc)
1407 state->srv_ofs = 0;
1408 else if (svc->protos[proto].srv)
1409 state->srv_ofs = snprintf(state->full_name, sizeof(state->full_name), "_%s._%s.", svc->name, (proto == SERVICE_UDP ? "udp" : "tcp"));
1410 else if (state->flags & SAI_FORCESRV)
1411 state->srv_ofs = snprintf(state->full_name, sizeof(state->full_name), "_%s._%s.", service, (proto == SERVICE_UDP ? "udp" : "tcp"));
1412 else
1413 state->srv_ofs = 0;
1414
1415 if (state->srv_ofs < sizeof(state->full_name))
1416 safestrncpy(state->full_name + state->srv_ofs, node, sizeof(state->full_name) - state->srv_ofs);
1417
1418 for (ii = len = 0; node[ii]; ++ii)
1419 if (node[ii] == '.')
1420 len++;
1421 if (len >= conf.sar_ndots)
1422 state->search_pos = conf.sar_search->used;
1423 else
1424 state->search_pos = 0;
1425
1426 /* XXX: fill in *state with any other fields needed to parse responses. */
1427
1428 if (!sar_getaddr_request(req)) {
1429 free(req);
1430 return NULL;
1431 }
1432 return req;
1433 }
1434 }
1435
1436 struct sar_getname_state {
1437 sar_name_cb cb;
1438 void *cb_ctx;
1439 char *hostname;
1440 unsigned int flags;
1441 unsigned int family;
1442 enum service_proto proto;
1443 unsigned short port;
1444 unsigned int doing_arpa : 1; /* checking .ip6.arpa vs .ip6.int */
1445 unsigned char original[16]; /* original address data */
1446 /* name must be long enough to hold "0.0.<etc>.ip6.arpa" */
1447 char name[74];
1448 };
1449
1450 static void
1451 sar_getname_fail(struct sar_request *req, UNUSED_ARG(unsigned int rcode))
1452 {
1453 struct sar_getname_state *state;
1454 unsigned int len;
1455
1456 state = (struct sar_getname_state*)(req + 1);
1457 if (state->doing_arpa) {
1458 len = strlen(state->name);
1459 assert(len == 73);
1460 strcpy(state->name + len - 4, "int");
1461 len = sar_request_build(req, state->name, REQ_TYPE_PTR, NULL);
1462 if (len) {
1463 sar_request_send(req);
1464 return;
1465 }
1466 }
1467 state->cb(state->cb_ctx, NULL, NULL, SAI_FAIL);
1468 free(state->hostname);
1469 }
1470
1471 static const char *sar_getname_port(unsigned int port, unsigned int flags, char *tmpbuf, unsigned int tmpbuf_len)
1472 {
1473 struct service_byport *service;
1474 enum service_proto proto;
1475 char port_text[12];
1476
1477 sprintf(port_text, "%d", port);
1478 proto = (flags & SNI_DGRAM) ? SERVICE_UDP : SERVICE_TCP;
1479 if (!(flags & SNI_NUMERICSERV)
1480 && (service = dict_find(services_byport, port_text, NULL))
1481 && service->byname[proto])
1482 return service->byname[proto]->name;
1483 snprintf(tmpbuf, tmpbuf_len, "%d", port);
1484 return tmpbuf;
1485 }
1486
1487 static void
1488 sar_getname_confirm(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1489 {
1490 struct sar_getname_state *state;
1491 const unsigned char *data;
1492 const char *portname;
1493 char servbuf[16];
1494 unsigned int ii, nbr;
1495
1496 state = (struct sar_getname_state*)(req + 1);
1497 for (ii = 0; ii < hdr->ancount; ++ii) {
1498 /* Is somebody confused or trying to play games? */
1499 if (rr[ii].class != REQ_CLASS_IN
1500 || strcasecmp(state->hostname, rr[ii].name))
1501 continue;
1502 switch (rr[ii].type) {
1503 case REQ_TYPE_A: nbr = 4; break;
1504 case REQ_TYPE_AAAA: nbr = 16; break;
1505 default: continue;
1506 }
1507 data = sar_extract_rdata(rr, nbr, raw, raw_size);
1508 if (data && !memcmp(data, state->original, nbr)) {
1509 portname = sar_getname_port(state->port, state->flags, servbuf, sizeof(servbuf));
1510 state->cb(state->cb_ctx, state->hostname, portname, SAI_SUCCESS);
1511 free(state->hostname);
1512 return;
1513 }
1514 }
1515 state->cb(state->cb_ctx, NULL, NULL, SAI_MISMATCH);
1516 free(state->hostname);
1517 }
1518
1519 static void
1520 sar_getname_ok(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1521 {
1522 struct sar_getname_state *state;
1523 const char *portname;
1524 unsigned int ii, pos;
1525 char servbuf[16];
1526
1527 state = (struct sar_getname_state*)(req + 1);
1528 for (ii = 0; ii < hdr->ancount; ++ii) {
1529 if (rr[ii].type != REQ_TYPE_PTR
1530 || rr[ii].class != REQ_CLASS_IN
1531 || strcasecmp(rr[ii].name, state->name))
1532 continue;
1533 pos = rr[ii].rd_start;
1534 state->hostname = sar_extract_name(raw, raw_size, &pos);
1535 break;
1536 }
1537
1538 if (!state->hostname) {
1539 state->cb(state->cb_ctx, NULL, NULL, SAI_NONAME);
1540 return;
1541 }
1542
1543 if (state->flags & SNI_PARANOID) {
1544 req->cb_ok = sar_getname_confirm;
1545 pos = sar_helpers[state->family]->build_addr_request(req, state->hostname, NULL, 0);
1546 if (pos)
1547 sar_request_send(req);
1548 else {
1549 free(state->hostname);
1550 state->cb(state->cb_ctx, NULL, NULL, SAI_FAIL);
1551 }
1552 return;
1553 }
1554
1555 portname = sar_getname_port(state->port, state->flags, servbuf, sizeof(servbuf));
1556 state->cb(state->cb_ctx, state->hostname, portname, SAI_SUCCESS);
1557 free(state->hostname);
1558 }
1559
1560 struct sar_request *
1561 sar_getname(const struct sockaddr *sa, unsigned int salen, int flags, sar_name_cb cb, void *cb_ctx)
1562 {
1563 struct sar_family_helper *helper;
1564 struct sar_request *req;
1565 struct sar_getname_state *state;
1566 unsigned int len;
1567 int port;
1568
1569 if (sa->sa_family > MAX_FAMILY
1570 || !(helper = sar_helpers[sa->sa_family])) {
1571 cb(cb_ctx, NULL, NULL, SAI_FAMILY);
1572 return NULL;
1573 }
1574
1575 port = helper->get_port(sa, salen);
1576
1577 if (flags & SNI_NUMERICHOST) {
1578 const char *servname;
1579 char host[SAR_NTOP_MAX], servbuf[16];
1580
1581 /* If appropriate, try to look up service name. */
1582 servname = sar_getname_port(port, flags, servbuf, sizeof(servbuf));
1583 len = sar_ntop(host, sizeof(host), sa, salen);
1584 assert(len != 0);
1585 cb(cb_ctx, host, servname, SAI_SUCCESS);
1586 return NULL;
1587 }
1588
1589 req = sar_request_alloc(sizeof(*state), sar_getname_ok, sar_getname_fail);
1590
1591 state = (struct sar_getname_state*)(req + 1);
1592 state->cb = cb;
1593 state->cb_ctx = cb_ctx;
1594 state->flags = flags;
1595 state->family = sa->sa_family;
1596 state->port = port;
1597
1598 helper->build_ptr_name(state, sa, salen);
1599 assert(strlen(state->name) < sizeof(state->name));
1600 len = sar_request_build(req, state->name, REQ_TYPE_PTR, NULL);
1601 if (!len) {
1602 cb(cb_ctx, NULL, NULL, SAI_NODATA);
1603 free(req);
1604 return NULL;
1605 }
1606
1607 sar_request_send(req);
1608 return req;
1609 }
1610
1611 static unsigned int
1612 ipv4_ntop(char *output, unsigned int out_size, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1613 {
1614 struct sockaddr_in *sin;
1615 unsigned int ip4, pos;
1616
1617 sin = (struct sockaddr_in*)sa;
1618 ip4 = ntohl(sin->sin_addr.s_addr);
1619 pos = snprintf(output, out_size, "%u.%u.%u.%u", (ip4 >> 24), (ip4 >> 16) & 255, (ip4 >> 8) & 255, ip4 & 255);
1620 return (pos < out_size) ? pos : 0;
1621 }
1622
1623 static unsigned int
1624 sar_pton_ip4(const char *input, unsigned int *bits, uint32_t *output)
1625 {
1626 unsigned int dots = 0, pos = 0, part = 0, ip = 0;
1627
1628 /* Intentionally no support for bizarre IPv4 formats (plain
1629 * integers, octal or hex components) -- only vanilla dotted
1630 * decimal quads, optionally with trailing /nn.
1631 */
1632 if (input[0] == '.')
1633 return 0;
1634 while (1) {
1635 if (isdigit(input[pos])) {
1636 part = part * 10 + input[pos++] - '0';
1637 if (part > 255)
1638 return 0;
1639 if ((dots == 3) && !isdigit(input[pos])) {
1640 *output = htonl(ip | part);
1641 return pos;
1642 }
1643 } else if (input[pos] == '.') {
1644 if (input[++pos] == '.')
1645 return 0;
1646 ip |= part << (24 - 8 * dots++);
1647 part = 0;
1648 } else if (bits && input[pos] == '/' && isdigit(input[pos + 1])) {
1649 unsigned int len;
1650 char *term;
1651
1652 len = strtoul(input + pos + 1, &term, 10);
1653 if (term <= input + pos + 1)
1654 return pos;
1655 else if (len > 32)
1656 return 0;
1657 *bits = len;
1658 return term - input;
1659 } else return 0;
1660 }
1661 }
1662
1663 static unsigned int
1664 ipv4_pton(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned int *bits, const char *input)
1665 {
1666 unsigned int pos;
1667
1668 pos = sar_pton_ip4(input, bits, &((struct sockaddr_in*)sa)->sin_addr.s_addr);
1669 if (!pos)
1670 return 0;
1671 sa->sa_family = AF_INET;
1672 #if defined(HAVE_SOCKADDR_SA_LEN)
1673 sa->sa_len = sizeof(struct sockaddr_in);
1674 #endif
1675 return pos;
1676 }
1677
1678 static int
1679 ipv4_get_port(const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1680 {
1681 return ntohs(((const struct sockaddr_in*)sa)->sin_port);
1682 }
1683
1684 static int
1685 ipv4_set_port(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned short port)
1686 {
1687 ((struct sockaddr_in*)sa)->sin_port = htons(port);
1688 return 0;
1689 }
1690
1691 static unsigned int
1692 ipv4_addr_request(struct sar_request *req, const char *node, const char *srv_node, UNUSED_ARG(unsigned int flags))
1693 {
1694 unsigned int len;
1695 if (srv_node)
1696 len = sar_request_build(req, node, REQ_TYPE_A, srv_node, REQ_TYPE_SRV, NULL);
1697 else
1698 len = sar_request_build(req, node, REQ_TYPE_A, NULL);
1699 return len;
1700 }
1701
1702 static void
1703 ipv4_ptr_name(struct sar_getname_state *state, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1704 {
1705 const uint8_t *bytes;
1706
1707 bytes = (uint8_t*)&((struct sockaddr_in*)sa)->sin_addr.s_addr;
1708 memcpy(state->original, bytes, 4);
1709 snprintf(state->name, sizeof(state->name),
1710 "%u.%u.%u.%u.in-addr.arpa",
1711 bytes[3], bytes[2], bytes[1], bytes[0]);
1712 }
1713
1714 static int
1715 ipv4_decode(struct sar_getaddr_state *state, struct dns_rr *rr, unsigned char *raw, UNUSED_ARG(unsigned int raw_size))
1716 {
1717 struct sockaddr_in *sa;
1718 struct addrinfo *ai;
1719
1720 if (rr->rdlength != 4)
1721 return 0;
1722
1723 if (state->flags & SAI_CANONNAME) {
1724 ai = calloc(1, sizeof(*ai) + sizeof(*sa) + strlen(rr->name) + 1);
1725 sa = (struct sockaddr_in*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1726 ai->ai_canonname = strcpy((char*)(sa + 1), rr->name);
1727 } else {
1728 ai = calloc(1, sizeof(*ai) + sizeof(*sa));
1729 sa = (struct sockaddr_in*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1730 ai->ai_canonname = NULL;
1731 }
1732
1733 ai->ai_family = AF_INET;
1734 sa->sin_port = htons(state->port);
1735 memcpy(&sa->sin_addr.s_addr, raw + rr->rd_start, 4);
1736 return sar_getaddr_append(state, ai, 1);
1737 }
1738
1739 static struct sar_family_helper sar_ipv4_helper = {
1740 "127.0.0.1",
1741 "0.0.0.0",
1742 sizeof(struct sockaddr_in),
1743 AF_INET,
1744 ipv4_ntop,
1745 ipv4_pton,
1746 ipv4_get_port,
1747 ipv4_set_port,
1748 ipv4_addr_request,
1749 ipv4_ptr_name,
1750 ipv4_decode,
1751 NULL
1752 };
1753
1754 #if defined(AF_INET6)
1755
1756 static unsigned int
1757 ipv6_ntop(char *output, unsigned int out_size, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1758 {
1759 struct sockaddr_in6 *sin6;
1760 unsigned int pos, part, max_start, max_zeros, curr_zeros, ii;
1761 unsigned short addr16;
1762
1763 sin6 = (struct sockaddr_in6*)sa;
1764 /* Find longest run of zeros. */
1765 for (max_start = max_zeros = curr_zeros = ii = 0; ii < 8; ++ii) {
1766 addr16 = (sin6->sin6_addr.s6_addr[ii * 2] << 8) | sin6->sin6_addr.s6_addr[ii * 2 + 1];
1767 if (!addr16)
1768 curr_zeros++;
1769 else if (curr_zeros > max_zeros) {
1770 max_start = ii - curr_zeros;
1771 max_zeros = curr_zeros;
1772 curr_zeros = 0;
1773 }
1774 }
1775 if (curr_zeros > max_zeros) {
1776 max_start = ii - curr_zeros;
1777 max_zeros = curr_zeros;
1778 }
1779
1780 /* Print out address. */
1781 #define APPEND(CH) do { output[pos++] = (CH); if (pos >= out_size) return 0; } while (0)
1782 for (pos = 0, ii = 0; ii < 8; ++ii) {
1783 if ((max_zeros > 0) && (ii == max_start)) {
1784 if (ii == 0)
1785 APPEND(':');
1786 APPEND(':');
1787 ii += max_zeros - 1;
1788 continue;
1789 }
1790 part = (sin6->sin6_addr.s6_addr[ii * 2] << 8) | sin6->sin6_addr.s6_addr[ii * 2 + 1];
1791 if (part >= 0x1000)
1792 APPEND(hexdigits[part >> 12]);
1793 if (part >= 0x100)
1794 APPEND(hexdigits[(part >> 8) & 15]);
1795 if (part >= 0x10)
1796 APPEND(hexdigits[(part >> 4) & 15]);
1797 APPEND(hexdigits[part & 15]);
1798 if (ii < 7)
1799 APPEND(':');
1800 }
1801 APPEND('\0');
1802 #undef APPEND
1803
1804 return pos;
1805 }
1806
1807 static const unsigned char xdigit_value[256] = {
1808 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1811 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
1812 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1814 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1815 };
1816
1817 static unsigned int
1818 ipv6_pton(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned int *bits, const char *input)
1819 {
1820 const char *part_start = NULL;
1821 struct sockaddr_in6 *sin6;
1822 char *colon;
1823 char *dot;
1824 unsigned int part = 0, pos = 0, ii = 0, cpos = 8;
1825
1826 if (!(colon = strchr(input, ':')))
1827 return 0;
1828 dot = strchr(input, '.');
1829 if (dot && dot < colon)
1830 return 0;
1831 sin6 = (struct sockaddr_in6*)sa;
1832 /* Parse IPv6, possibly like ::127.0.0.1.
1833 * This is pretty straightforward; the only trick is borrowed
1834 * from Paul Vixie (BIND): when it sees a "::" continue as if
1835 * it were a single ":", but note where it happened, and fill
1836 * with zeros afterwards.
1837 */
1838 if (input[pos] == ':') {
1839 if ((input[pos+1] != ':') || (input[pos+2] == ':'))
1840 return 0;
1841 cpos = 0;
1842 pos += 2;
1843 part_start = input + pos;
1844 }
1845 while (ii < 8) {
1846 if (isxdigit(input[pos])) {
1847 part = (part << 4) | xdigit_value[(unsigned char)input[pos]];
1848 if (part > 0xffff)
1849 return 0;
1850 pos++;
1851 } else if (input[pos] == ':') {
1852 part_start = input + ++pos;
1853 if (input[pos] == '.')
1854 return 0;
1855 sin6->sin6_addr.s6_addr[ii * 2] = part >> 8;
1856 sin6->sin6_addr.s6_addr[ii * 2 + 1] = part & 255;
1857 ii++;
1858 part = 0;
1859 if (input[pos] == ':') {
1860 if (cpos < 8)
1861 return 0;
1862 cpos = ii;
1863 pos++;
1864 }
1865 } else if (input[pos] == '.') {
1866 uint32_t ip4;
1867 unsigned int len;
1868 len = sar_pton_ip4(part_start, bits, &ip4);
1869 if (!len || (ii > 6))
1870 return 0;
1871 memcpy(sin6->sin6_addr.s6_addr + ii * 2, &ip4, sizeof(ip4));
1872 if (bits)
1873 *bits += ii * 16;
1874 ii += 2;
1875 pos = part_start + len - input;
1876 break;
1877 } else if (bits && input[pos] == '/' && isdigit(input[pos + 1])) {
1878 unsigned int len;
1879 char *term;
1880
1881 len = strtoul(input + pos + 1, &term, 10);
1882 if (term <= input + pos + 1)
1883 break;
1884 else if (len > 128)
1885 return 0;
1886 if (bits)
1887 *bits = len;
1888 pos = term - input;
1889 break;
1890 } else if (cpos <= 8) {
1891 sin6->sin6_addr.s6_addr[ii * 2] = part >> 8;
1892 sin6->sin6_addr.s6_addr[ii * 2 + 1] = part & 255;
1893 ii++;
1894 break;
1895 } else return 0;
1896 }
1897 /* Shift stuff after "::" up and fill middle with zeros. */
1898 if (cpos < 8) {
1899 unsigned int jj;
1900 ii <<= 1;
1901 cpos <<= 1;
1902 for (jj = 0; jj < ii - cpos; jj++)
1903 sin6->sin6_addr.s6_addr[15 - jj] = sin6->sin6_addr.s6_addr[ii - jj - 1];
1904 for (jj = 0; jj < 16 - ii; jj++)
1905 sin6->sin6_addr.s6_addr[cpos + jj] = 0;
1906 }
1907 sa->sa_family = AF_INET6;
1908 #if defined(HAVE_SOCKADDR_SA_LEN)
1909 sa->sa_len = sizeof(struct sockaddr_in6);
1910 #endif
1911 return pos;
1912 }
1913
1914 static int
1915 ipv6_get_port(const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1916 {
1917 return ntohs(((const struct sockaddr_in6*)sa)->sin6_port);
1918 }
1919
1920 static int
1921 ipv6_set_port(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned short port)
1922 {
1923 ((struct sockaddr_in6*)sa)->sin6_port = htons(port);
1924 return 0;
1925 }
1926
1927 static unsigned int
1928 ipv6_addr_request(struct sar_request *req, const char *node, const char *srv_node, unsigned int flags)
1929 {
1930 unsigned int len;
1931 if (flags & SAI_V4MAPPED) {
1932 if (srv_node)
1933 len = sar_request_build(req, node, REQ_TYPE_AAAA, node, REQ_TYPE_A, srv_node, REQ_TYPE_SRV, NULL);
1934 else
1935 len = sar_request_build(req, node, REQ_TYPE_AAAA, node, REQ_TYPE_A, NULL);
1936 } else {
1937 if (srv_node)
1938 len = sar_request_build(req, node, REQ_TYPE_AAAA, srv_node, REQ_TYPE_SRV, NULL);
1939 else
1940 len = sar_request_build(req, node, REQ_TYPE_AAAA, NULL);
1941 }
1942 return len;
1943 }
1944
1945 static void
1946 ipv6_ptr_name(struct sar_getname_state *state, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1947 {
1948 const uint8_t *bytes;
1949 unsigned int ii, jj;
1950
1951 bytes = ((struct sockaddr_in6*)sa)->sin6_addr.s6_addr;
1952 memcpy(state->original, bytes, 16);
1953 for (jj = 0, ii = 16; ii > 0; ) {
1954 state->name[jj++] = hexdigits[bytes[--ii] & 15];
1955 state->name[jj++] = hexdigits[bytes[ii] >> 4];
1956 state->name[jj++] = '.';
1957 }
1958 strcpy(state->name + jj, ".ip6.arpa");
1959 state->doing_arpa = 1;
1960 }
1961
1962 static int
1963 ipv6_decode(struct sar_getaddr_state *state, struct dns_rr *rr, unsigned char *raw, UNUSED_ARG(unsigned int raw_size))
1964 {
1965 struct sockaddr_in6 *sa;
1966 struct addrinfo *ai;
1967
1968 if (state->flags & SAI_CANONNAME) {
1969 ai = calloc(1, sizeof(*ai) + sizeof(*sa) + strlen(rr->name) + 1);
1970 sa = (struct sockaddr_in6*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1971 ai->ai_canonname = strcpy((char*)(sa + 1), rr->name);
1972 } else {
1973 ai = calloc(1, sizeof(*ai) + sizeof(*sa));
1974 sa = (struct sockaddr_in6*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1975 ai->ai_canonname = NULL;
1976 }
1977
1978 if (rr->rdlength == 4) {
1979 sa->sin6_addr.s6_addr[10] = sa->sin6_addr.s6_addr[11] = 0xff;
1980 memcpy(sa->sin6_addr.s6_addr + 12, raw + rr->rd_start, 4);
1981 } else if (rr->rdlength == 16) {
1982 memcpy(sa->sin6_addr.s6_addr, raw + rr->rd_start, 16);
1983 } else {
1984 free(ai);
1985 return 0;
1986 }
1987
1988 ai->ai_family = AF_INET6;
1989 sa->sin6_port = htons(state->port);
1990 return sar_getaddr_append(state, ai, 1);
1991 }
1992
1993 static struct sar_family_helper sar_ipv6_helper = {
1994 "::1",
1995 "::",
1996 sizeof(struct sockaddr_in6),
1997 AF_INET6,
1998 ipv6_ntop,
1999 ipv6_pton,
2000 ipv6_get_port,
2001 ipv6_set_port,
2002 ipv6_addr_request,
2003 ipv6_ptr_name,
2004 ipv6_decode,
2005 NULL
2006 };
2007
2008 #endif /* defined(AF_INET6) */
2009
2010 static void
2011 sar_cleanup(UNUSED_ARG(void *extra))
2012 {
2013 ioset_close(sar_fd, 1);
2014 dict_delete(services_byname);
2015 dict_delete(services_byport);
2016 dict_delete(sar_nameservers);
2017 dict_delete(sar_requests);
2018 free_string_list(conf.sar_search);
2019 free_string_list(conf.sar_nslist);
2020 }
2021
2022 static void
2023 sar_conf_reload(void)
2024 {
2025 dict_t node;
2026 const char *resolv_conf = "/etc/resolv.conf";
2027 const char *services = "/etc/services";
2028 const char *str;
2029
2030 node = conf_get_data("modules/sar", RECDB_OBJECT);
2031 if (node != NULL) {
2032 str = database_get_data(node, "resolv_conf", RECDB_QSTRING);
2033 if (str) resolv_conf = str;
2034 str = database_get_data(node, "services", RECDB_QSTRING);
2035 if (str) services = str;
2036 }
2037 sar_dns_init(resolv_conf);
2038 sar_services_init(services);
2039 }
2040
2041 void
2042 sar_init(void)
2043 {
2044 reg_exit_func(sar_cleanup, NULL);
2045 sar_log = log_register_type("sar", NULL);
2046
2047 sar_requests = dict_new();
2048 dict_set_free_data(sar_requests, sar_request_cleanup);
2049
2050 sar_nameservers = dict_new();
2051 dict_set_free_data(sar_nameservers, free);
2052
2053 sar_register_helper(&sar_ipv4_helper);
2054 #if defined(AF_INET6)
2055 sar_register_helper(&sar_ipv6_helper);
2056 #endif
2057
2058 conf_register_reload(sar_conf_reload);
2059 }