1 /* sar.h - srvx asynchronous resolver
2 * Copyright 2005, 2007 Michael Poole <mdpoole@troilus.org>
4 * This file is part of srvx.
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 2 of the License, or
9 * (at your option) any later version.
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.
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.
27 static const char hexdigits[] = "0123456789abcdef";
30 struct sar_getaddr_state;
31 struct sar_getname_state;
33 struct sar_family_helper {
34 const char *localhost_addr;
35 const char *unspec_addr;
39 unsigned int (*ntop)(char *output, unsigned int out_size, const struct sockaddr *sa, unsigned int socklen);
40 unsigned int (*pton)(struct sockaddr *sa, unsigned int socklen, unsigned int *bits, const char *input);
41 int (*get_port)(const struct sockaddr *sa, unsigned int socklen);
42 int (*set_port)(struct sockaddr *sa, unsigned int socklen, unsigned short port);
43 unsigned int (*build_addr_request)(struct sar_request *req, const char *node, const char *srv_node, unsigned int flags);
44 void (*build_ptr_name)(struct sar_getname_state *state, const struct sockaddr *sa, unsigned int socklen);
45 int (*decode_addr)(struct sar_getaddr_state *state, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size);
47 struct sar_family_helper *next;
50 #define MAX_FAMILY AF_INET
51 static struct sar_family_helper sar_ipv4_helper;
54 # if AF_INET6 > MAX_FAMILY
56 # define MAX_FAMILY AF_INET6
58 static struct sar_family_helper sar_ipv6_helper;
61 static struct sar_family_helper *sar_helpers[MAX_FAMILY+1];
62 static struct sar_family_helper *sar_first_helper;
65 sar_ntop(char *output, unsigned int out_size, const struct sockaddr *sa, unsigned int socklen)
68 assert(output != NULL);
72 if (sa->sa_family <= MAX_FAMILY && sar_helpers[sa->sa_family]) {
73 pos = sar_helpers[sa->sa_family]->ntop(output, out_size, sa, socklen);
82 sar_pton(struct sockaddr *sa, unsigned int socklen, unsigned int *bits, const char *input)
84 struct sar_family_helper *helper;
88 assert(input != NULL);
90 memset(sa, 0, socklen);
93 for (helper = sar_first_helper; helper; helper = helper->next) {
94 if (socklen < helper->socklen)
96 len = helper->pton(sa, socklen, bits, input);
98 sa->sa_family = helper->family;
102 return 0; /* parse failed */
106 sar_get_port(const struct sockaddr *sa, unsigned int socklen)
108 if (sa->sa_family <= MAX_FAMILY
109 && sar_helpers[sa->sa_family]
110 && socklen >= sar_helpers[sa->sa_family]->socklen)
111 return sar_helpers[sa->sa_family]->get_port(sa, socklen);
116 sar_set_port(struct sockaddr *sa, unsigned int socklen, unsigned short port)
118 if (sa->sa_family <= MAX_FAMILY
119 && sar_helpers[sa->sa_family]
120 && socklen >= sar_helpers[sa->sa_family]->socklen)
121 return sar_helpers[sa->sa_family]->set_port(sa, socklen, port);
126 sar_strerror(enum sar_errcode errcode)
129 case SAI_SUCCESS: return "Resolution succeeded.";
130 case SAI_FAMILY: return "The requested address family is not supported.";
131 case SAI_SOCKTYPE: return "The requested socket type is not supported.";
132 case SAI_BADFLAGS: return "Invalid flags value.";
133 case SAI_NONAME: return "Unknown name or service.";
134 case SAI_SERVICE: return "The service is unavailable for that socket type.";
135 case SAI_ADDRFAMILY: return "The host has no address in the requested family.";
136 case SAI_NODATA: return "The host has no addresses at all.";
137 case SAI_MEMORY: return "Unable to allocate memory.";
138 case SAI_FAIL: return "The nameserver indicated a permanent error.";
139 case SAI_AGAIN: return "The nameserver indicated a temporary error.";
140 case SAI_MISMATCH: return "Mismatch between reverse and forward resolution.";
141 case SAI_SYSTEM: return strerror(errno);
142 default: return "Unknown resolver error code.";
147 sar_free(struct addrinfo *ai)
149 struct addrinfo *next;
150 for (; ai; ai = next) {
156 /** Global variables to support DNS name resolution. */
158 unsigned int sar_timeout;
159 unsigned int sar_retries;
160 unsigned int sar_ndots;
161 unsigned int sar_edns0;
162 char sar_localdomain[MAXLEN];
163 struct string_list *sar_search;
164 struct string_list *sar_nslist;
165 struct sockaddr_storage sar_bind_address;
167 static struct log_type *sar_log;
169 /* Except as otherwise noted, constants and formats are from RFC1035.
170 * This resolver is believed to implement the behaviors mandated (and
171 * in many cases those recommended) by these standards: RFC1035,
172 * RFC2671, RFC2782, RFC3596, RFC3597.
174 * Update queries (including RFC 2136) seems a likely candidate for
176 * DNSSEC (including RFCs 2535, 3007, 3655, etc) is less likely until
177 * a good application is found.
178 * Caching (RFC 2308) and redirection (RFC 2672) are much less likely,
179 * since most users will have a separate local, caching, recursive
181 * Other DNS extensions (at least through RFC 3755) are believed to be
182 * too rare or insufficiently useful to bother supporting.
184 * The following are useful Reasons For Concern:
185 * RFC1536, RFC1912, RFC2606, RFC3363, RFC3425, RFC3467
186 * http://www.iana.org/assignments/dns-parameters
187 * http://www.ietf.org/html.charters/dnsext-charter.html
190 struct sar_nameserver {
193 unsigned int req_sent;
194 unsigned int resp_used;
195 unsigned int resp_ignored;
196 unsigned int resp_servfail;
197 unsigned int resp_fallback;
198 unsigned int resp_failures;
199 unsigned int resp_scrambled;
201 struct sockaddr_storage ss;
204 /* EDNS0 uses 12 bit RCODEs, TSIG/TKEY use 16 bit RCODEs.
205 * Declare local RCODE failures here.*/
207 RCODE_TIMED_OUT = 65536,
208 RCODE_QUERY_TOO_LONG,
209 RCODE_LABEL_TOO_LONG,
210 RCODE_SOCKET_FAILURE,
214 #define DNS_NAME_LENGTH 256
216 #define RES_SIZE_FLAGS 0xc0
217 #define RES_SF_LABEL 0x00
218 #define RES_SF_POINTER 0xc0
220 static dict_t sar_requests;
221 static dict_t sar_nameservers;
222 static struct io_fd *sar_fd;
223 static int sar_fd_fd;
226 sar_rcode_text(unsigned int rcode)
229 case RCODE_NO_ERROR: return "No error";
230 case RCODE_FORMAT_ERROR: return "Format error";
231 case RCODE_SERVER_FAILURE: return "Server failure";
232 case RCODE_NAME_ERROR: return "Name error";
233 case RCODE_NOT_IMPLEMENTED: return "Feature not implemented";
234 case RCODE_REFUSED: return "Query refused";
235 case RCODE_BAD_OPT_VERSION: return "Unsupported EDNS option version";
236 case RCODE_TIMED_OUT: return "Request timed out";
237 case RCODE_QUERY_TOO_LONG: return "Query too long";
238 case RCODE_LABEL_TOO_LONG: return "Label too long";
239 case RCODE_SOCKET_FAILURE: return "Resolver socket failure";
240 case RCODE_DESTROYED: return "Request unexpectedly destroyed";
241 default: return "Unknown rcode";
246 sar_request_fail(struct sar_request *req, unsigned int rcode)
248 log_module(sar_log, LOG_DEBUG, "sar_request_fail({id=%d}, rcode=%d)", req->id, rcode);
251 req->cb_fail(req, rcode);
255 sar_request_abort(req);
258 static time_t next_sar_timeout;
261 sar_timeout_cb(void *data)
264 dict_iterator_t next;
265 time_t next_timeout = INT_MAX;
267 for (it = dict_first(sar_requests); it; it = next) {
268 struct sar_request *req;
271 next = iter_next(it);
272 if (req->expiry > next_timeout)
274 else if (req->expiry > now)
275 next_timeout = req->expiry;
276 else if (req->retries >= conf.sar_retries)
277 sar_request_fail(req, RCODE_TIMED_OUT);
279 sar_request_send(req);
281 if (next_timeout < INT_MAX) {
282 next_sar_timeout = next_timeout;
283 timeq_add(next_timeout, sar_timeout_cb, data);
288 sar_check_timeout(time_t when)
290 if (!next_sar_timeout || when < next_sar_timeout) {
291 timeq_del(0, sar_timeout_cb, NULL, TIMEQ_IGNORE_WHEN | TIMEQ_IGNORE_DATA);
292 timeq_add(when, sar_timeout_cb, NULL);
293 next_sar_timeout = when;
298 sar_request_cleanup(void *d)
300 struct sar_request *req = d;
301 log_module(sar_log, LOG_DEBUG, "sar_request_cleanup({id=%d})", req->id);
304 req->cb_fail(req, RCODE_DESTROYED);
309 sar_dns_init(const char *resolv_conf_path)
311 struct string_list *ns_sv;
312 struct string_list *ds_sv;
317 /* Initialize configuration defaults. */
318 conf.sar_localdomain[0] = '\0';
319 conf.sar_timeout = 3;
320 conf.sar_retries = 3;
323 ns_sv = alloc_string_list(4);
324 ds_sv = alloc_string_list(4);
326 /* Scan resolver configuration file. */
327 resolv_conf = fopen(resolv_conf_path, "r");
331 char linebuf[LINE_MAX], ch;
333 while (fgets(linebuf, sizeof(linebuf), resolv_conf)) {
334 ch = linebuf[len = strcspn(linebuf, " \t\r\n")];
336 arg = linebuf + len + 1;
337 if (!strcmp(linebuf, "nameserver")) {
339 ch = arg[len = strcspn(arg, " \t\r\n")];
341 string_list_append(ns_sv, strdup(arg));
344 } else if (!strcmp(linebuf, "domain")) {
346 safestrncpy(conf.sar_localdomain, arg, sizeof(conf.sar_localdomain));
348 } else if (!strcmp(linebuf, "search")) {
350 ch = arg[len = strcspn(arg, " \t\r\n")];
352 string_list_append(ds_sv, strdup(arg));
355 } else if (!strcmp(linebuf, "options")) {
357 ch = arg[len = strcspn(arg, " \t\r\n")];
359 opt = strchr(arg, ':');
362 if (!strcmp(arg, "timeout")) {
363 conf.sar_timeout = atoi(opt);
364 } else if (!strcmp(arg, "attempts")) {
365 conf.sar_retries = atoi(opt);
366 } else if (!strcmp(arg, "ndots")) {
367 conf.sar_ndots = atoi(opt);
368 } else if (!strcmp(arg, "edns0")) {
369 conf.sar_edns0 = atoi(opt);
371 } else if (!strcmp(arg, "edns0")) {
372 conf.sar_edns0 = 1440;
380 /* This is apparently what BIND defaults to using. */
381 string_list_append(ns_sv, "127.0.0.1");
384 /* Set default search path if domain is set. */
385 if (conf.sar_localdomain[0] != '\0' && ds_sv->used == 0)
386 string_list_append(ds_sv, strdup(conf.sar_localdomain));
388 /* Check configuration entries that might override resolv.conf. */
389 node = conf_get_data("modules/sar", RECDB_OBJECT);
392 struct string_list *slist;
394 str = database_get_data(node, "timeout", RECDB_QSTRING);
395 if (str) conf.sar_timeout = ParseInterval(str);
396 str = database_get_data(node, "retries", RECDB_QSTRING);
397 if (str) conf.sar_retries = atoi(str);
398 str = database_get_data(node, "ndots", RECDB_QSTRING);
399 if (str) conf.sar_ndots = atoi(str);
400 str = database_get_data(node, "edns0", RECDB_QSTRING);
401 if (str) conf.sar_edns0 = enabled_string(str);
402 str = database_get_data(node, "domain", RECDB_QSTRING);
403 if (str) safestrncpy(conf.sar_localdomain, str, sizeof(conf.sar_localdomain));
404 slist = database_get_data(node, "search", RECDB_STRING_LIST);
406 free_string_list(ds_sv);
407 ds_sv = string_list_copy(slist);
409 slist = database_get_data(node, "nameservers", RECDB_STRING_LIST);
411 free_string_list(ns_sv);
412 ns_sv = string_list_copy(slist);
414 sa = (struct sockaddr*)&conf.sar_bind_address;
415 memset(sa, 0, sizeof(conf.sar_bind_address));
416 str = database_get_data(node, "bind_address", RECDB_QSTRING);
417 if (str) sar_pton(sa, sizeof(conf.sar_bind_address), NULL, str);
418 str = database_get_data(node, "bind_port", RECDB_QSTRING);
420 if (sa->sa_family == AF_INET) {
421 struct sockaddr_in *sin = (struct sockaddr_in*)sa;
422 sin->sin_port = ntohs(atoi(str));
424 #if defined(AF_INET6)
425 else if (sa->sa_family == AF_INET6) {
426 struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
427 sin6->sin6_port = ntohs(atoi(str));
433 /* Replace config lists with their new values. */
434 free_string_list(conf.sar_search);
435 conf.sar_search = ds_sv;
436 free_string_list(conf.sar_nslist);
437 conf.sar_nslist = ns_sv;
441 sar_request_abort(struct sar_request *req)
445 assert(dict_find(sar_requests, req->id_text, NULL) == req);
446 log_module(sar_log, LOG_DEBUG, "sar_request_abort({id=%d})", req->id);
449 dict_remove(sar_requests, req->id_text);
452 static struct sar_nameserver *
453 sar_our_server(const struct sockaddr_storage *ss, unsigned int ss_len)
457 for (it = dict_first(sar_nameservers); it; it = iter_next(it)) {
458 struct sar_nameserver *ns;
461 if (ns->ss_len == ss_len && !memcmp(ss, &ns->ss, ss_len))
468 sar_extract_name(const unsigned char *buf, unsigned int size, unsigned int *ppos)
470 struct string_buffer cv;
471 unsigned int pos, jumped;
477 cv.list = calloc(1, cv.size);
485 cv.list[cv.used - 1] = '\0'; /* chop off terminating '.' */
487 string_buffer_append(&cv, '\0');
490 switch (buf[pos] & RES_SIZE_FLAGS) {
492 unsigned int len = buf[pos];
493 if (pos + len + 1 >= size)
495 string_buffer_append_substring(&cv, (char*)buf + pos + 1, len);
496 string_buffer_append(&cv, '.');
501 if ((pos + 1 >= size) || (cv.used >= size))
505 pos = (buf[pos] & ~RES_SIZE_FLAGS) << 8 | buf[pos+1];
518 sar_decode_answer(struct sar_request *req, struct dns_header *hdr, unsigned char *buf, unsigned int size)
521 unsigned int ii, rr_count, pos;
524 /* Skip over query section. */
525 for (ii = 0, pos = 12; ii < hdr->qdcount; ++ii) {
526 /* Skip over compressed names. */
532 switch (buf[pos] & RES_SIZE_FLAGS) {
539 pos = (buf[pos] & ~RES_SIZE_FLAGS) << 8 | buf[pos+1];
547 /* Skip over null terminator, type and class part of question. */
551 /* Parse each RR in the answer. */
552 rr_count = hdr->ancount + hdr->nscount + hdr->arcount;
553 rr = calloc(1, rr_count * sizeof(rr[0]));
554 for (ii = 0; ii < rr_count; ++ii) {
555 rr[ii].name = sar_extract_name(buf, size, &pos);
560 if (pos + 10 > size) {
564 rr[ii].type = buf[pos+0] << 8 | buf[pos+1];
565 rr[ii].class = buf[pos+2] << 8 | buf[pos+3];
566 rr[ii].ttl = buf[pos+4] << 24 | buf[pos+5] << 16 | buf[pos+6] << 8 | buf[pos+7];
567 rr[ii].rdlength = buf[pos+8] << 8 | buf[pos+9];
568 rr[ii].rd_start = pos + 10;
569 pos = pos + rr[ii].rdlength + 10;
577 req->cb_ok(req, hdr, rr, buf, size);
581 dict_remove(sar_requests, req->id_text);
591 static const unsigned char *
592 sar_extract_rdata(struct dns_rr *rr, unsigned int len, unsigned char *raw, unsigned int raw_size)
594 if (len > rr->rdlength)
596 if (rr->rd_start + len > raw_size)
598 return raw + rr->rd_start;
602 sar_fd_readable(struct io_fd *fd)
604 struct sockaddr_storage ss;
605 struct dns_header hdr;
606 struct sar_nameserver *ns;
607 struct sar_request *req;
610 int res, rcode, buf_len;
613 assert(sar_fd == fd);
614 buf_len = conf.sar_edns0;
617 buf = alloca(buf_len);
619 res = recvfrom(sar_fd_fd, buf, buf_len, 0, (struct sockaddr*)&ss, &ss_len);
620 if (res < 12 || !(ns = sar_our_server(&ss, ss_len)))
622 hdr.id = buf[0] << 8 | buf[1];
623 hdr.flags = buf[2] << 8 | buf[3];
624 hdr.qdcount = buf[4] << 8 | buf[5];
625 hdr.ancount = buf[6] << 8 | buf[7];
626 hdr.nscount = buf[8] << 8 | buf[9];
627 hdr.arcount = buf[10] << 8 | buf[11];
629 sprintf(id_text, "%d", hdr.id);
630 req = dict_find(sar_requests, id_text, NULL);
631 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", fd, hdr.id, hdr.flags, hdr.qdcount, hdr.ancount, hdr.nscount, hdr.arcount, req);
632 if (!req || !req->retries || !(hdr.flags & REQ_FLAG_QR)) {
636 rcode = hdr.flags & REQ_FLAG_RCODE_MASK;
637 if (rcode != RCODE_NO_ERROR) {
638 sar_request_fail(req, rcode);
639 } else if (sar_decode_answer(req, &hdr, (unsigned char*)buf, res)) {
640 ns->resp_scrambled++;
641 sar_request_fail(req, RCODE_FORMAT_ERROR);
646 sar_build_nslist(struct string_list *nslist)
648 dict_iterator_t it, next;
649 struct sar_nameserver *ns;
652 for (it = dict_first(sar_nameservers); it; it = iter_next(it)) {
657 for (ii = 0; ii < nslist->used; ++ii) {
660 name = nslist->list[ii];
661 ns = dict_find(sar_nameservers, name, NULL);
663 ns = calloc(1, sizeof(*ns) + strlen(name) + 1);
664 ns->name = (char*)(ns + 1);
665 strcpy(ns->name, name);
666 ns->ss_len = sizeof(ns->ss);
667 if (!sar_pton((struct sockaddr*)&ns->ss, sizeof(ns->ss), NULL, name)) {
671 sar_set_port((struct sockaddr*)&ns->ss, sizeof(ns->ss), 53);
672 ns->ss_len = sar_helpers[ns->ss.ss_family]->socklen;
673 dict_insert(sar_nameservers, ns->name, ns);
678 for (it = dict_first(sar_nameservers); it; it = next) {
679 next = iter_next(it);
682 dict_remove(sar_nameservers, ns->name);
691 /* Build list of nameservers. */
692 sar_build_nslist(conf.sar_nslist);
694 if (conf.sar_bind_address.ss_family != 0) {
697 ai = (struct addrinfo*)&conf.sar_bind_address;
698 sar_fd_fd = socket(ai->ai_family, SOCK_DGRAM, 0);
700 log_module(sar_log, LOG_FATAL, "Unable to create resolver socket: %s", strerror(errno));
704 res = bind(sar_fd_fd, ai->ai_addr, ai->ai_addrlen);
706 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));
709 struct sar_nameserver *ns;
711 it = dict_first(sar_nameservers);
713 sar_fd_fd = socket(ns->ss.ss_family, SOCK_DGRAM, 0);
715 log_module(sar_log, LOG_FATAL, "Unable to create resolver socket: %s", strerror(errno));
720 sar_fd = ioset_add(sar_fd_fd);
722 log_module(sar_log, LOG_FATAL, "Unable to register resolver socket with event loop.");
725 sar_fd->state = IO_CONNECTED;
726 sar_fd->readable_cb = sar_fd_readable;
736 set_compare_charp(const void *a_, const void *b_)
738 char * const *a = a_, * const *b = b_;
739 return strcasecmp(*a, *b);
743 string_buffer_reserve(struct string_buffer *cv, unsigned int min_length)
745 if (cv->size < min_length) {
747 new_buffer = realloc(cv->list, min_length);
749 cv->size = min_length;
750 cv->list = new_buffer;
755 /** Append \a name to \a cv in compressed form. */
757 sar_append_name(struct string_buffer *cv, const char *name, struct name_ofs *ofs, unsigned int *used, unsigned int alloc)
759 struct name_ofs *pofs;
763 pofs = bsearch(&name, ofs, *used, sizeof(ofs[0]), set_compare_charp);
765 string_buffer_reserve(cv, cv->used + 2);
766 cv->list[cv->used++] = RES_SF_POINTER | (pofs->ofs >> 8);
767 cv->list[cv->used++] = pofs->ofs & 255;
770 len = strcspn(name, ".");
774 ofs[*used].name = name;
775 ofs[*used].ofs = cv->used;
776 qsort(ofs, (*used)++, sizeof(ofs[0]), set_compare_charp);
778 string_buffer_reserve(cv, cv->used + len + 1);
779 cv->list[cv->used] = RES_SF_LABEL | len;
780 memcpy(cv->list + cv->used + 1, name, len);
782 if (name[len] == '.')
784 else if (name[len] == '\0')
787 string_buffer_append(cv, '\0');
791 /** Build a DNS question packet from a variable-length argument list.
792 * In \a args, there is at least one pari consisting of const char
793 * *name and unsigned int qtype. A null name argument terminates the
797 sar_request_vbuild(struct sar_request *req, va_list args)
799 struct name_ofs suffixes[32];
800 struct string_buffer cv;
802 unsigned int suf_used;
804 unsigned int qdcount;
808 cv.list = calloc(1, cv.size);
810 val = REQ_OPCODE_QUERY | REQ_FLAG_RD;
811 cv.list[0] = req->id >> 8;
812 cv.list[1] = req->id & 255;
813 cv.list[2] = val >> 8;
814 cv.list[3] = val & 255;
815 cv.list[6] = cv.list[7] = cv.list[8] = cv.list[9] = cv.list[10] = 0;
817 for (qdcount = 0; (name = va_arg(args, const char*)); ++qdcount) {
818 if (sar_append_name(&cv, name, suffixes, &suf_used, ArrayLength(suffixes))) {
819 string_buffer_clean(&cv);
822 string_buffer_reserve(&cv, cv.used + 4);
823 val = va_arg(args, unsigned int);
824 cv.list[cv.used++] = val >> 8;
825 cv.list[cv.used++] = val & 255;
826 cv.list[cv.used++] = REQ_CLASS_IN >> 8;
827 cv.list[cv.used++] = REQ_CLASS_IN & 255;
829 cv.list[4] = qdcount >> 8;
830 cv.list[5] = qdcount & 255;
831 val = conf.sar_edns0;
833 string_buffer_reserve(&cv, cv.used + 11);
834 cv.list[cv.used + 0] = '\0'; /* empty name */
835 cv.list[cv.used + 1] = REQ_TYPE_OPT >> 8;
836 cv.list[cv.used + 2] = REQ_TYPE_OPT & 255;
837 cv.list[cv.used + 3] = val >> 8;
838 cv.list[cv.used + 4] = val & 255;
839 cv.list[cv.used + 5] = 0; /* extended-rcode */
840 cv.list[cv.used + 6] = 0; /* version */
841 cv.list[cv.used + 7] = 0; /* reserved */
842 cv.list[cv.used + 8] = 0; /* reserved */
843 cv.list[cv.used + 9] = 0; /* msb rdlen */
844 cv.list[cv.used + 10] = 0; /* lsb rdlen */
846 cv.list[11] = 1; /* update arcount */
847 } else cv.list[11] = 0;
851 req->body = (unsigned char*)cv.list;
852 req->body_len = cv.used;
856 /** Build a DNS question packet. After \a req, there is at least one
857 * pair consisting of const char *name and unsigned int qtype. A null
858 * name argument terminates the list.
861 sar_request_build(struct sar_request *req, ...)
865 va_start(vargs, req);
866 ret = sar_request_vbuild(req, vargs);
872 sar_request_send(struct sar_request *req)
876 /* make sure we have our local socket */
877 if (!sar_fd && sar_open_fd()) {
878 sar_request_fail(req, RCODE_SOCKET_FAILURE);
882 log_module(sar_log, LOG_DEBUG, "sar_request_send({id=%d})", req->id);
884 /* send query to each configured nameserver */
885 for (it = dict_first(sar_nameservers); it; it = iter_next(it)) {
886 struct sar_nameserver *ns;
890 res = sendto(sar_fd_fd, req->body, req->body_len, 0, (struct sockaddr*)&ns->ss, ns->ss_len);
893 log_module(sar_log, LOG_DEBUG, "Sent %u bytes to %s.", res, ns->name);
895 log_module(sar_log, LOG_ERROR, "Unable to send %u bytes to nameserver %s: %s", req->body_len, ns->name, strerror(errno));
897 assert(0 && "resolver sendto() unexpectedly returned zero");
900 /* Check that query timeout is soon enough. */
901 req->expiry = now + (conf.sar_timeout << ++req->retries);
902 sar_check_timeout(req->expiry);
906 sar_request_alloc(unsigned int data_len, sar_request_ok_cb ok_cb, sar_request_fail_cb fail_cb)
908 struct sar_request *req;
910 req = calloc(1, sizeof(*req) + data_len);
912 req->cb_fail = fail_cb;
914 req->id = rand() & 0xffff;
915 sprintf(req->id_text, "%d", req->id);
916 } while (dict_find(sar_requests, req->id_text, NULL));
917 dict_insert(sar_requests, req->id_text, req);
918 log_module(sar_log, LOG_DEBUG, "sar_request_alloc(%d) -> {id=%d}", data_len, req->id);
923 sar_request_simple(unsigned int data_len, sar_request_ok_cb ok_cb, sar_request_fail_cb fail_cb, ...)
925 struct sar_request *req;
927 req = sar_request_alloc(data_len, ok_cb, fail_cb);
931 va_start(args, fail_cb);
932 sar_request_vbuild(req, args);
934 sar_request_send(req);
945 struct service_byname {
946 const char *name; /* service name */
948 /* note: if valid != 0, port == 0, check canonical entry */
949 struct service_byname *canon; /* if NULL, this is canonical */
951 unsigned int valid : 1;
952 unsigned int srv : 1;
953 } protos[SERVICE_NUM_PROTOS];
956 struct service_byport {
959 struct service_byname *byname[SERVICE_NUM_PROTOS];
962 static dict_t services_byname; /* contains struct service_byname */
963 static dict_t services_byport; /* contains struct service_byport */
965 static struct service_byname *
966 sar_service_byname(const char *name, int autocreate)
968 struct service_byname *byname;
970 byname = dict_find(services_byname, name, NULL);
971 if (!byname && autocreate) {
972 byname = calloc(1, sizeof(*byname) + strlen(name) + 1);
973 byname->name = strcpy((char*)(byname + 1), name);
974 dict_insert(services_byname, byname->name, byname);
979 static struct service_byport *
980 sar_service_byport(unsigned int port, int autocreate)
982 struct service_byport *byport;
985 sprintf(port_text, "%d", port);
986 byport = dict_find(services_byport, port_text, NULL);
987 if (!byport && autocreate) {
988 byport = calloc(1, sizeof(*byport));
990 sprintf(byport->port_text, "%d", port);
991 dict_insert(services_byport, byport->port_text, byport);
997 sar_services_load_file(const char *etc_services)
999 static const char *whitespace = " \t\r\n";
1000 struct service_byname *canon;
1001 struct service_byport *byport;
1002 char *name, *port, *alias, *ptr;
1005 enum service_proto proto;
1006 char linebuf[LINE_MAX];
1008 file = fopen(etc_services, "r");
1011 while (fgets(linebuf, sizeof(linebuf), file)) {
1012 ptr = strchr(linebuf, '#');
1015 /* Tokenize canonical service name and port number. */
1016 name = strtok_r(linebuf, whitespace, &ptr);
1019 port = strtok_r(NULL, whitespace, &ptr);
1022 pnum = strtoul(port, &port, 10);
1023 if (pnum == 0 || *port++ != '/')
1025 if (!strcmp(port, "udp"))
1026 proto = SERVICE_UDP;
1027 else if (!strcmp(port, "tcp"))
1028 proto = SERVICE_TCP;
1031 /* Set up canonical name-indexed service entry. */
1032 canon = sar_service_byname(name, 1);
1033 if (canon->protos[proto].valid) {
1034 log_module(sar_log, LOG_ERROR, "Service %s/%s listed twice.", name, port);
1037 canon->protos[proto].canon = NULL;
1038 canon->protos[proto].port = pnum;
1039 canon->protos[proto].valid = 1;
1041 /* Set up port-indexed service entry. */
1042 byport = sar_service_byport(pnum, 1);
1043 if (!byport->byname[proto])
1044 byport->byname[proto] = canon;
1046 /* Add alias entries. */
1047 while ((alias = strtok_r(NULL, whitespace, &ptr))) {
1048 struct service_byname *byname;
1050 byname = sar_service_byname(alias, 1);
1051 if (byname->protos[proto].valid) {
1052 /* We do not log this since there are a lot of
1053 * duplicate aliases, some only differing in case. */
1056 byname->protos[proto].canon = canon;
1057 byname->protos[proto].port = pnum;
1058 byname->protos[proto].valid = 1;
1065 sar_services_init(const char *etc_services)
1067 /* These are a portion of the services listed at
1068 * http://www.dns-sd.org/ServiceTypes.html.
1070 static const char *tcp_srvs[] = { "cvspserver", "distcc", "ftp", "http",
1071 "imap", "ipp", "irc", "ldap", "login", "nfs", "pop3", "postgresql",
1072 "rsync", "sftp-ssh", "soap", "ssh", "telnet", "webdav", "xmpp-client",
1073 "xmpp-server", "xul-http", NULL };
1074 static const char *udp_srvs[] = { "bootps", "dns-update", "domain", "nfs",
1075 "ntp", "tftp", NULL };
1076 struct service_byname *byname;
1079 sar_services_load_file(etc_services);
1081 for (ii = 0; tcp_srvs[ii]; ++ii) {
1082 byname = sar_service_byname(tcp_srvs[ii], 1);
1083 byname->protos[SERVICE_TCP].srv = 1;
1086 for (ii = 0; udp_srvs[ii]; ++ii) {
1087 byname = sar_service_byname(udp_srvs[ii], 1);
1088 byname->protos[SERVICE_UDP].srv = 1;
1093 sar_register_helper(struct sar_family_helper *helper)
1095 assert(helper->family <= MAX_FAMILY);
1096 sar_helpers[helper->family] = helper;
1097 helper->next = sar_first_helper;
1098 sar_first_helper = helper;
1102 sar_addrlen(const struct sockaddr *sa, UNUSED_ARG(unsigned int size))
1104 return sa->sa_family <= MAX_FAMILY && sar_helpers[sa->sa_family]
1105 ? sar_helpers[sa->sa_family]->socklen : 0;
1108 struct sar_getaddr_state {
1109 struct sar_family_helper *helper;
1110 struct addrinfo *ai_head;
1111 struct addrinfo *ai_tail;
1114 unsigned int search_pos;
1115 unsigned int flags, socktype, protocol, port;
1116 unsigned int srv_ofs;
1117 char full_name[DNS_NAME_LENGTH];
1121 sar_getaddr_append(struct sar_getaddr_state *state, struct addrinfo *ai, int copy)
1125 log_module(sar_log, LOG_DEBUG, "sar_getaddr_append({full_name=%s}, ai=%p, copy=%d)", state->full_name, ai, copy);
1127 /* Set the appropriate pointer to the new element(s). */
1129 state->ai_tail->ai_next = ai;
1131 state->ai_head = ai;
1133 /* Find the end of the list. */
1135 /* Make sure we copy fields for both the first and last entries. */
1138 if (!ai->ai_addrlen) {
1139 assert(sar_helpers[ai->ai_family]);
1140 ai->ai_addrlen = sar_helpers[ai->ai_family]->socklen;
1142 #if defined(HAVE_SOCKADDR_SA_LEN)
1143 ai->ai_addr->sa_len = ai->ai_addrlen;
1145 ai->ai_addr->sa_family = ai->ai_family;
1146 ai->ai_socktype = state->socktype;
1147 ai->ai_protocol = state->protocol;
1154 for (count = 1; ai->ai_next; ++count, ai = ai->ai_next)
1158 /* Set the tail pointer and return count of appended items. */
1159 state->ai_tail = ai;
1163 static struct sar_request *
1164 sar_getaddr_request(struct sar_request *req)
1166 struct sar_getaddr_state *state;
1168 char full_name[DNS_NAME_LENGTH];
1170 state = (struct sar_getaddr_state*)(req + 1);
1172 /* If we can and should, append the current search domain. */
1173 if (state->search_pos < conf.sar_search->used)
1174 snprintf(full_name, sizeof(full_name), "%s.%s", state->full_name, conf.sar_search->list[state->search_pos]);
1175 else if (state->search_pos == conf.sar_search->used)
1176 safestrncpy(full_name, state->full_name, sizeof(full_name));
1178 log_module(sar_log, LOG_DEBUG, "sar_getaddr_request({id=%d}): failed", req->id);
1179 state->cb(state->cb_ctx, NULL, SAI_NONAME);
1183 /* Build the appropriate request for DNS record(s). */
1184 if (state->flags & SAI_ALL)
1185 len = sar_request_build(req, full_name + state->srv_ofs, REQ_QTYPE_ALL, NULL);
1186 else if (state->srv_ofs)
1187 len = state->helper->build_addr_request(req, full_name + state->srv_ofs, full_name, state->flags);
1189 len = state->helper->build_addr_request(req, full_name, NULL, state->flags);
1191 log_module(sar_log, LOG_DEBUG, "sar_getaddr_request({id=%d}): full_name=%s, srv_ofs=%d", req->id, full_name, state->srv_ofs);
1193 /* Check that the request could be built. */
1195 state->cb(state->cb_ctx, NULL, SAI_NODATA);
1199 /* Send the request. */
1200 sar_request_send(req);
1205 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)
1207 struct sar_getaddr_state *state;
1209 unsigned int jj, pos, hit;
1211 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);
1212 state = (struct sar_getaddr_state*)(req + 1);
1214 switch (rr[rr_idx].type) {
1216 if (state->flags & SAI_ALL)
1217 return sar_ipv4_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1218 #if defined(AF_INET6)
1219 else if (state->flags & SAI_V4MAPPED)
1220 return sar_ipv6_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1222 return state->helper->decode_addr(state, rr + rr_idx, raw, raw_size);
1225 #if defined(AF_INET6)
1226 if (state->flags & SAI_ALL)
1227 return sar_ipv6_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1228 return state->helper->decode_addr(state, rr + rr_idx, raw, raw_size);
1233 case REQ_TYPE_CNAME:
1234 /* there should be the canonical name next */
1235 pos = rr[rr_idx].rd_start;
1236 cname = sar_extract_name(raw, raw_size, &pos);
1238 return 0; /* XXX: eventually log the unhandled body */
1239 /* and it should correspond to some other answer in the response */
1240 for (jj = hit = 0; jj < hdr->ancount; ++jj) {
1241 if (strcasecmp(cname, rr[jj].name))
1243 hit += sar_getaddr_decode(req, hdr, rr, raw, raw_size, jj);
1245 /* XXX: if (!hit) handle or log the incomplete recursion; */
1249 /* TODO: decode the SRV record */
1257 sar_getaddr_ok(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1259 struct sar_getaddr_state *state;
1262 state = (struct sar_getaddr_state*)(req + 1);
1264 log_module(sar_log, LOG_DEBUG, "sar_getaddr_ok({id=%d}, {id=%d}, <rr>, <data>, %u)", req->id, hdr->id, raw_size);
1265 for (ii = 0; ii < hdr->ancount; ++ii)
1266 sar_getaddr_decode(req, hdr, rr, raw, raw_size, ii);
1268 /* If we found anything, report it, else try again. */
1270 state->cb(state->cb_ctx, state->ai_head, SAI_SUCCESS);
1272 sar_getaddr_request(req);
1276 sar_getaddr_fail(struct sar_request *req, UNUSED_ARG(unsigned int rcode))
1278 struct sar_getaddr_state *state;
1280 log_module(sar_log, LOG_DEBUG, "sar_getaddr_fail({id=%d}, rcode=%u)", req->id, rcode);
1281 state = (struct sar_getaddr_state*)(req + 1);
1282 state->cb(state->cb_ctx, NULL, SAI_FAIL);
1285 struct sar_request *
1286 sar_getaddr(const char *node, const char *service, const struct addrinfo *hints_, sar_addr_cb cb, void *cb_ctx)
1288 struct sockaddr_storage ss;
1289 struct addrinfo hints;
1290 struct sar_family_helper *helper;
1291 struct service_byname *svc;
1293 unsigned int portnum;
1295 enum service_proto proto;
1297 if (!node && !service) {
1298 cb(cb_ctx, NULL, SAI_NONAME);
1302 /* Initialize local hints structure. */
1304 memcpy(&hints, hints_, sizeof(hints));
1306 memset(&hints, 0, sizeof(hints));
1308 /* Translate socket type to internal protocol. */
1309 switch (hints.ai_socktype) {
1310 case 0: hints.ai_socktype = SOCK_STREAM; /* and fall through */
1311 case SOCK_STREAM: proto = SERVICE_TCP; break;
1312 case SOCK_DGRAM: proto = SERVICE_UDP; break;
1314 cb(cb_ctx, NULL, SAI_SOCKTYPE);
1318 /* Figure out preferred socket size. */
1319 if (hints.ai_family == AF_UNSPEC)
1320 hints.ai_family = AF_INET;
1321 if (hints.ai_family > MAX_FAMILY
1322 || !(helper = sar_helpers[hints.ai_family])) {
1323 cb(cb_ctx, NULL, SAI_FAMILY);
1326 hints.ai_addrlen = helper->socklen;
1328 /* If \a node is NULL, figure out the correct default from the
1329 * requested family and SAI_PASSIVE flag.
1332 node = (hints.ai_flags & SAI_PASSIVE) ? helper->unspec_addr : helper->localhost_addr;
1334 /* Try to parse (failing that, look up) \a service. */
1336 portnum = 0, svc = NULL;
1337 else if ((portnum = strtoul(service, &end, 10)), *end == '\0')
1339 else if ((svc = sar_service_byname(service, 0)) != NULL)
1340 portnum = svc->protos[proto].port;
1342 cb(cb_ctx, NULL, SAI_SERVICE);
1346 /* Try to parse \a node as a numeric hostname.*/
1347 pos = sar_pton((struct sockaddr*)&ss, sizeof(ss), NULL, node);
1348 if (pos && node[pos] == '\0') {
1349 struct addrinfo *ai;
1350 char canonname[SAR_NTOP_MAX];
1352 /* we have a valid address; use it */
1353 sar_set_port((struct sockaddr*)&ss, sizeof(ss), portnum);
1354 hints.ai_addrlen = sar_addrlen((struct sockaddr*)&ss, sizeof(ss));
1355 if (!hints.ai_addrlen) {
1356 cb(cb_ctx, NULL, SAI_FAMILY);
1359 pos = sar_ntop(canonname, sizeof(canonname), (struct sockaddr*)&ss, hints.ai_addrlen);
1361 /* allocate and fill in the addrinfo response */
1362 ai = calloc(1, sizeof(*ai) + hints.ai_addrlen + pos + 1);
1363 ai->ai_family = ss.ss_family;
1364 ai->ai_socktype = hints.ai_socktype;
1365 ai->ai_protocol = hints.ai_protocol;
1366 ai->ai_addrlen = hints.ai_addrlen;
1367 ai->ai_addr = memcpy(ai + 1, &ss, ai->ai_addrlen);
1368 ai->ai_canonname = strcpy((char*)ai->ai_addr + ai->ai_addrlen, canonname);
1369 cb(cb_ctx, ai, SAI_SUCCESS);
1371 } else if (hints.ai_flags & SAI_NUMERICHOST) {
1372 cb(cb_ctx, NULL, SAI_NONAME);
1375 struct sar_request *req;
1376 struct sar_getaddr_state *state;
1377 unsigned int len, ii;
1379 req = sar_request_alloc(sizeof(*state), sar_getaddr_ok, sar_getaddr_fail);
1381 state = (struct sar_getaddr_state*)(req + 1);
1382 state->helper = helper;
1383 state->ai_head = state->ai_tail = NULL;
1385 state->cb_ctx = cb_ctx;
1386 state->flags = hints.ai_flags;
1387 state->socktype = hints.ai_socktype;
1388 state->protocol = hints.ai_protocol;
1389 state->port = portnum;
1391 if ((state->flags & SAI_NOSRV) || !svc)
1393 else if (svc->protos[proto].srv)
1394 state->srv_ofs = snprintf(state->full_name, sizeof(state->full_name), "_%s._%s.", svc->name, (proto == SERVICE_UDP ? "udp" : "tcp"));
1395 else if (state->flags & SAI_FORCESRV)
1396 state->srv_ofs = snprintf(state->full_name, sizeof(state->full_name), "_%s._%s.", service, (proto == SERVICE_UDP ? "udp" : "tcp"));
1400 if (state->srv_ofs < sizeof(state->full_name))
1401 safestrncpy(state->full_name + state->srv_ofs, node, sizeof(state->full_name) - state->srv_ofs);
1403 for (ii = len = 0; node[ii]; ++ii)
1404 if (node[ii] == '.')
1406 if (len >= conf.sar_ndots)
1407 state->search_pos = conf.sar_search->used;
1409 state->search_pos = 0;
1411 /* XXX: fill in *state with any other fields needed to parse responses. */
1413 if (!sar_getaddr_request(req)) {
1421 struct sar_getname_state {
1426 unsigned int family;
1427 enum service_proto proto;
1428 unsigned short port;
1429 unsigned int doing_arpa : 1; /* checking .ip6.arpa vs .ip6.int */
1430 unsigned char original[16]; /* original address data */
1431 /* name must be long enough to hold "0.0.<etc>.ip6.arpa" */
1436 sar_getname_fail(struct sar_request *req, UNUSED_ARG(unsigned int rcode))
1438 struct sar_getname_state *state;
1441 state = (struct sar_getname_state*)(req + 1);
1442 if (state->doing_arpa) {
1443 len = strlen(state->name);
1445 strcpy(state->name + len - 4, "int");
1446 len = sar_request_build(req, state->name, REQ_TYPE_PTR, NULL);
1448 sar_request_send(req);
1452 state->cb(state->cb_ctx, NULL, NULL, SAI_FAIL);
1453 free(state->hostname);
1456 static const char *sar_getname_port(unsigned int port, unsigned int flags, char *tmpbuf, unsigned int tmpbuf_len)
1458 struct service_byport *service;
1459 enum service_proto proto;
1462 sprintf(port_text, "%d", port);
1463 proto = (flags & SNI_DGRAM) ? SERVICE_UDP : SERVICE_TCP;
1464 if (!(flags & SNI_NUMERICSERV)
1465 && (service = dict_find(services_byport, port_text, NULL))
1466 && service->byname[proto])
1467 return service->byname[proto]->name;
1468 snprintf(tmpbuf, tmpbuf_len, "%d", port);
1473 sar_getname_confirm(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1475 struct sar_getname_state *state;
1476 const unsigned char *data;
1477 const char *portname;
1479 unsigned int ii, nbr;
1481 state = (struct sar_getname_state*)(req + 1);
1482 for (ii = 0; ii < hdr->ancount; ++ii) {
1483 /* Is somebody confused or trying to play games? */
1484 if (rr[ii].class != REQ_CLASS_IN
1485 || strcasecmp(state->hostname, rr[ii].name))
1487 switch (rr[ii].type) {
1488 case REQ_TYPE_A: nbr = 4; break;
1489 case REQ_TYPE_AAAA: nbr = 16; break;
1492 data = sar_extract_rdata(rr, nbr, raw, raw_size);
1493 if (data && !memcmp(data, state->original, nbr)) {
1494 portname = sar_getname_port(state->port, state->flags, servbuf, sizeof(servbuf));
1495 state->cb(state->cb_ctx, state->hostname, portname, SAI_SUCCESS);
1496 free(state->hostname);
1500 state->cb(state->cb_ctx, NULL, NULL, SAI_MISMATCH);
1501 free(state->hostname);
1505 sar_getname_ok(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1507 struct sar_getname_state *state;
1508 const char *portname;
1509 unsigned int ii, pos;
1512 state = (struct sar_getname_state*)(req + 1);
1513 for (ii = 0; ii < hdr->ancount; ++ii) {
1514 if (rr[ii].type != REQ_TYPE_PTR
1515 || rr[ii].class != REQ_CLASS_IN
1516 || strcasecmp(rr[ii].name, state->name))
1518 pos = rr[ii].rd_start;
1519 state->hostname = sar_extract_name(raw, raw_size, &pos);
1523 if (!state->hostname) {
1524 state->cb(state->cb_ctx, NULL, NULL, SAI_NONAME);
1528 if (state->flags & SNI_PARANOID) {
1529 req->cb_ok = sar_getname_confirm;
1530 pos = sar_helpers[state->family]->build_addr_request(req, state->hostname, NULL, 0);
1532 sar_request_send(req);
1534 free(state->hostname);
1535 state->cb(state->cb_ctx, NULL, NULL, SAI_FAIL);
1540 portname = sar_getname_port(state->port, state->flags, servbuf, sizeof(servbuf));
1541 state->cb(state->cb_ctx, state->hostname, portname, SAI_SUCCESS);
1542 free(state->hostname);
1545 struct sar_request *
1546 sar_getname(const struct sockaddr *sa, unsigned int salen, int flags, sar_name_cb cb, void *cb_ctx)
1548 struct sar_family_helper *helper;
1549 struct sar_request *req;
1550 struct sar_getname_state *state;
1554 if (sa->sa_family > MAX_FAMILY
1555 || !(helper = sar_helpers[sa->sa_family])) {
1556 cb(cb_ctx, NULL, NULL, SAI_FAMILY);
1560 port = helper->get_port(sa, salen);
1562 if (flags & SNI_NUMERICHOST) {
1563 const char *servname;
1565 char host[SAR_NTOP_MAX], servbuf[16];
1567 /* If appropriate, try to look up service name. */
1568 servname = sar_getname_port(port, flags, servbuf, sizeof(servbuf));
1569 len = sar_ntop(host, sizeof(host), sa, salen);
1571 cb(cb_ctx, host, servname, SAI_SUCCESS);
1575 req = sar_request_alloc(sizeof(*state), sar_getname_ok, sar_getname_fail);
1577 state = (struct sar_getname_state*)(req + 1);
1579 state->cb_ctx = cb_ctx;
1580 state->flags = flags;
1581 state->family = sa->sa_family;
1584 helper->build_ptr_name(state, sa, salen);
1585 assert(strlen(state->name) < sizeof(state->name));
1586 len = sar_request_build(req, state->name, REQ_TYPE_PTR, NULL);
1588 cb(cb_ctx, NULL, NULL, SAI_NODATA);
1593 sar_request_send(req);
1598 ipv4_ntop(char *output, unsigned int out_size, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1600 struct sockaddr_in *sin;
1601 unsigned int ip4, pos;
1603 sin = (struct sockaddr_in*)sa;
1604 ip4 = ntohl(sin->sin_addr.s_addr);
1605 pos = snprintf(output, out_size, "%u.%u.%u.%u", (ip4 >> 24), (ip4 >> 16) & 255, (ip4 >> 8) & 255, ip4 & 255);
1606 return (pos < out_size) ? pos : 0;
1610 sar_pton_ip4(const char *input, unsigned int *bits, uint32_t *output)
1612 unsigned int dots = 0, pos = 0, part = 0, ip = 0;
1614 /* Intentionally no support for bizarre IPv4 formats (plain
1615 * integers, octal or hex components) -- only vanilla dotted
1616 * decimal quads, optionally with trailing /nn.
1618 if (input[0] == '.')
1621 if (isdigit(input[pos])) {
1622 part = part * 10 + input[pos++] - '0';
1625 if ((dots == 3) && !isdigit(input[pos])) {
1626 *output = htonl(ip | part);
1629 } else if (input[pos] == '.') {
1630 if (input[++pos] == '.')
1632 ip |= part << (24 - 8 * dots++);
1634 } else if (bits && input[pos] == '/' && isdigit(input[pos + 1])) {
1638 len = strtoul(input + pos + 1, &term, 10);
1639 if (term <= input + pos + 1)
1644 return term - input;
1650 ipv4_pton(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned int *bits, const char *input)
1654 pos = sar_pton_ip4(input, bits, &((struct sockaddr_in*)sa)->sin_addr.s_addr);
1657 sa->sa_family = AF_INET;
1662 ipv4_get_port(const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1664 return ntohs(((const struct sockaddr_in*)sa)->sin_port);
1668 ipv4_set_port(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned short port)
1670 ((struct sockaddr_in*)sa)->sin_port = htons(port);
1675 ipv4_addr_request(struct sar_request *req, const char *node, const char *srv_node, UNUSED_ARG(unsigned int flags))
1679 len = sar_request_build(req, node, REQ_TYPE_A, srv_node, REQ_TYPE_SRV, NULL);
1681 len = sar_request_build(req, node, REQ_TYPE_A, NULL);
1686 ipv4_ptr_name(struct sar_getname_state *state, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1688 const uint8_t *bytes;
1690 bytes = (uint8_t*)&((struct sockaddr_in*)sa)->sin_addr.s_addr;
1691 memcpy(state->original, bytes, 4);
1692 snprintf(state->name, sizeof(state->name),
1693 "%u.%u.%u.%u.in-addr.arpa",
1694 bytes[3], bytes[2], bytes[1], bytes[0]);
1698 ipv4_decode(struct sar_getaddr_state *state, struct dns_rr *rr, unsigned char *raw, UNUSED_ARG(unsigned int raw_size))
1700 struct sockaddr_in *sa;
1701 struct addrinfo *ai;
1703 if (rr->rdlength != 4)
1706 if (state->flags & SAI_CANONNAME) {
1707 ai = calloc(1, sizeof(*ai) + sizeof(*sa) + strlen(rr->name) + 1);
1708 sa = (struct sockaddr_in*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1709 ai->ai_canonname = strcpy((char*)(sa + 1), rr->name);
1711 ai = calloc(1, sizeof(*ai) + sizeof(*sa));
1712 sa = (struct sockaddr_in*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1713 ai->ai_canonname = NULL;
1716 ai->ai_family = AF_INET;
1717 sa->sin_port = htons(state->port);
1718 memcpy(&sa->sin_addr.s_addr, raw + rr->rd_start, 4);
1719 return sar_getaddr_append(state, ai, 1);
1722 static struct sar_family_helper sar_ipv4_helper = {
1725 sizeof(struct sockaddr_in),
1737 #if defined(AF_INET6)
1740 ipv6_ntop(char *output, unsigned int out_size, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1742 struct sockaddr_in6 *sin6;
1743 unsigned int pos, part, max_start, max_zeros, curr_zeros, ii;
1744 unsigned short addr16;
1746 sin6 = (struct sockaddr_in6*)sa;
1747 /* Find longest run of zeros. */
1748 for (max_start = max_zeros = curr_zeros = ii = 0; ii < 8; ++ii) {
1749 addr16 = (sin6->sin6_addr.s6_addr[ii * 2] << 8) | sin6->sin6_addr.s6_addr[ii * 2 + 1];
1752 else if (curr_zeros > max_zeros) {
1753 max_start = ii - curr_zeros;
1754 max_zeros = curr_zeros;
1758 if (curr_zeros > max_zeros) {
1759 max_start = ii - curr_zeros;
1760 max_zeros = curr_zeros;
1763 /* Print out address. */
1764 #define APPEND(CH) do { output[pos++] = (CH); if (pos >= out_size) return 0; } while (0)
1765 for (pos = 0, ii = 0; ii < 8; ++ii) {
1766 if ((max_zeros > 0) && (ii == max_start)) {
1770 ii += max_zeros - 1;
1773 part = (sin6->sin6_addr.s6_addr[ii * 2] << 8) | sin6->sin6_addr.s6_addr[ii * 2 + 1];
1775 APPEND(hexdigits[part >> 12]);
1777 APPEND(hexdigits[(part >> 8) & 15]);
1779 APPEND(hexdigits[(part >> 4) & 15]);
1780 APPEND(hexdigits[part & 15]);
1790 static const unsigned char xdigit_value[256] = {
1791 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1792 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1793 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1794 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
1795 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1796 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1797 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1801 ipv6_pton(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned int *bits, const char *input)
1803 const char *part_start = NULL;
1804 struct sockaddr_in6 *sin6;
1807 unsigned int part = 0, pos = 0, ii = 0, cpos = 8;
1809 if (!(colon = strchr(input, ':')))
1811 dot = strchr(input, '.');
1812 if (dot && dot < colon)
1814 sin6 = (struct sockaddr_in6*)sa;
1815 /* Parse IPv6, possibly like ::127.0.0.1.
1816 * This is pretty straightforward; the only trick is borrowed
1817 * from Paul Vixie (BIND): when it sees a "::" continue as if
1818 * it were a single ":", but note where it happened, and fill
1819 * with zeros afterwards.
1821 if (input[pos] == ':') {
1822 if ((input[pos+1] != ':') || (input[pos+2] == ':'))
1826 part_start = input + pos;
1829 if (isxdigit(input[pos])) {
1830 part = (part << 4) | xdigit_value[(unsigned char)input[pos]];
1834 } else if (input[pos] == ':') {
1835 part_start = input + ++pos;
1836 if (input[pos] == '.')
1838 sin6->sin6_addr.s6_addr[ii * 2] = part >> 8;
1839 sin6->sin6_addr.s6_addr[ii * 2 + 1] = part & 255;
1842 if (input[pos] == ':') {
1848 } else if (input[pos] == '.') {
1851 len = sar_pton_ip4(part_start, bits, &ip4);
1852 if (!len || (ii > 6))
1854 memcpy(sin6->sin6_addr.s6_addr + ii * 2, &ip4, sizeof(ip4));
1858 pos = part_start + len - input;
1860 } else if (bits && input[pos] == '/' && isdigit(input[pos + 1])) {
1864 len = strtoul(input + pos + 1, &term, 10);
1865 if (term <= input + pos + 1)
1873 } else if (cpos <= 8) {
1874 sin6->sin6_addr.s6_addr[ii * 2] = part >> 8;
1875 sin6->sin6_addr.s6_addr[ii * 2 + 1] = part & 255;
1880 /* Shift stuff after "::" up and fill middle with zeros. */
1885 for (jj = 0; jj < ii - cpos; jj++)
1886 sin6->sin6_addr.s6_addr[15 - jj] = sin6->sin6_addr.s6_addr[ii - jj - 1];
1887 for (jj = 0; jj < 16 - ii; jj++)
1888 sin6->sin6_addr.s6_addr[cpos + jj] = 0;
1890 sa->sa_family = AF_INET6;
1895 ipv6_get_port(const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1897 return ntohs(((const struct sockaddr_in6*)sa)->sin6_port);
1901 ipv6_set_port(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned short port)
1903 ((struct sockaddr_in6*)sa)->sin6_port = htons(port);
1908 ipv6_addr_request(struct sar_request *req, const char *node, const char *srv_node, unsigned int flags)
1911 if (flags & SAI_V4MAPPED) {
1913 len = sar_request_build(req, node, REQ_TYPE_AAAA, node, REQ_TYPE_A, srv_node, REQ_TYPE_SRV, NULL);
1915 len = sar_request_build(req, node, REQ_TYPE_AAAA, node, REQ_TYPE_A, NULL);
1918 len = sar_request_build(req, node, REQ_TYPE_AAAA, srv_node, REQ_TYPE_SRV, NULL);
1920 len = sar_request_build(req, node, REQ_TYPE_AAAA, NULL);
1926 ipv6_ptr_name(struct sar_getname_state *state, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1928 const uint8_t *bytes;
1929 unsigned int ii, jj;
1931 bytes = ((struct sockaddr_in6*)sa)->sin6_addr.s6_addr;
1932 memcpy(state->original, bytes, 16);
1933 for (jj = 0, ii = 16; ii > 0; ) {
1934 state->name[jj++] = hexdigits[bytes[--ii] & 15];
1935 state->name[jj++] = hexdigits[bytes[ii] >> 4];
1936 state->name[jj++] = '.';
1938 strcpy(state->name + jj, ".ip6.arpa");
1939 state->doing_arpa = 1;
1943 ipv6_decode(struct sar_getaddr_state *state, struct dns_rr *rr, unsigned char *raw, UNUSED_ARG(unsigned int raw_size))
1945 struct sockaddr_in6 *sa;
1946 struct addrinfo *ai;
1948 if (state->flags & SAI_CANONNAME) {
1949 ai = calloc(1, sizeof(*ai) + sizeof(*sa) + strlen(rr->name) + 1);
1950 sa = (struct sockaddr_in6*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1951 ai->ai_canonname = strcpy((char*)(sa + 1), rr->name);
1953 ai = calloc(1, sizeof(*ai) + sizeof(*sa));
1954 sa = (struct sockaddr_in6*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1955 ai->ai_canonname = NULL;
1958 if (rr->rdlength == 4) {
1959 sa->sin6_addr.s6_addr[10] = sa->sin6_addr.s6_addr[11] = 0xff;
1960 memcpy(sa->sin6_addr.s6_addr + 12, raw + rr->rd_start, 4);
1961 } else if (rr->rdlength == 16) {
1962 memcpy(sa->sin6_addr.s6_addr, raw + rr->rd_start, 16);
1968 ai->ai_family = AF_INET6;
1969 sa->sin6_port = htons(state->port);
1970 return sar_getaddr_append(state, ai, 1);
1973 static struct sar_family_helper sar_ipv6_helper = {
1976 sizeof(struct sockaddr_in6),
1988 #endif /* defined(AF_INET6) */
1993 ioset_close(sar_fd, 1);
1994 dict_delete(services_byname);
1995 dict_delete(services_byport);
1996 dict_delete(sar_nameservers);
1997 dict_delete(sar_requests);
2001 sar_conf_reload(void)
2004 const char *resolv_conf = "/etc/resolv.conf";
2005 const char *services = "/etc/services";
2008 node = conf_get_data("modules/sar", RECDB_OBJECT);
2010 str = database_get_data(node, "resolv_conf", RECDB_QSTRING);
2011 if (str) resolv_conf = str;
2012 str = database_get_data(node, "services", RECDB_QSTRING);
2013 if (str) services = str;
2015 sar_dns_init(resolv_conf);
2016 sar_services_init(services);
2022 reg_exit_func(sar_cleanup);
2023 sar_log = log_register_type("sar", NULL);
2025 sar_requests = dict_new();
2026 dict_set_free_data(sar_requests, sar_request_cleanup);
2028 sar_nameservers = dict_new();
2029 dict_set_free_data(sar_nameservers, free);
2031 services_byname = dict_new();
2032 dict_set_free_data(services_byname, free);
2034 services_byport = dict_new();
2035 dict_set_free_data(services_byport, free);
2037 sar_register_helper(&sar_ipv4_helper);
2038 #if defined(AF_INET6)
2039 sar_register_helper(&sar_ipv6_helper);
2042 conf_register_reload(sar_conf_reload);