Fix sar.c build on FreeBSD 5.5.
[srvx.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 2 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 time_t 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(time_t 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", fd, hdr.id, hdr.flags, hdr.qdcount, hdr.ancount, hdr.nscount, hdr.arcount, 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);
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     sar_services_load_file(etc_services);
1084
1085     for (ii = 0; tcp_srvs[ii]; ++ii) {
1086         byname = sar_service_byname(tcp_srvs[ii], 1);
1087         byname->protos[SERVICE_TCP].srv = 1;
1088     }
1089
1090     for (ii = 0; udp_srvs[ii]; ++ii) {
1091         byname = sar_service_byname(udp_srvs[ii], 1);
1092         byname->protos[SERVICE_UDP].srv = 1;
1093     }
1094 }
1095
1096 static void
1097 sar_register_helper(struct sar_family_helper *helper)
1098 {
1099     assert(helper->family <= MAX_FAMILY);
1100     sar_helpers[helper->family] = helper;
1101     helper->next = sar_first_helper;
1102     sar_first_helper = helper;
1103 }
1104
1105 static unsigned int
1106 sar_addrlen(const struct sockaddr *sa, UNUSED_ARG(unsigned int size))
1107 {
1108     return sa->sa_family <= MAX_FAMILY && sar_helpers[sa->sa_family]
1109         ? sar_helpers[sa->sa_family]->socklen : 0;
1110 }
1111
1112 struct sar_getaddr_state {
1113     struct sar_family_helper *helper;
1114     struct addrinfo *ai_head;
1115     struct addrinfo *ai_tail;
1116     sar_addr_cb cb;
1117     void *cb_ctx;
1118     unsigned int search_pos;
1119     unsigned int flags, socktype, protocol, port;
1120     unsigned int srv_ofs;
1121     char full_name[DNS_NAME_LENGTH];
1122 };
1123
1124 static unsigned int
1125 sar_getaddr_append(struct sar_getaddr_state *state, struct addrinfo *ai, int copy)
1126 {
1127     unsigned int count;
1128
1129     log_module(sar_log, LOG_DEBUG, "sar_getaddr_append({full_name=%s}, ai=%p, copy=%d)", state->full_name, ai, copy);
1130
1131     /* Set the appropriate pointer to the new element(s). */
1132     if (state->ai_tail)
1133         state->ai_tail->ai_next = ai;
1134     else
1135         state->ai_head = ai;
1136
1137     /* Find the end of the list. */
1138     if (copy) {
1139         /* Make sure we copy fields for both the first and last entries. */
1140         count = 1;
1141         while (1) {
1142             if (!ai->ai_addrlen) {
1143                 assert(sar_helpers[ai->ai_family]);
1144                 ai->ai_addrlen = sar_helpers[ai->ai_family]->socklen;
1145             }
1146 #if defined(HAVE_SOCKADDR_SA_LEN)
1147             ai->ai_addr->sa_len = ai->ai_addrlen;
1148 #endif
1149             ai->ai_addr->sa_family = ai->ai_family;
1150             ai->ai_socktype = state->socktype;
1151             ai->ai_protocol = state->protocol;
1152             if (!ai->ai_next)
1153                 break;
1154             count++;
1155             ai = ai->ai_next;
1156         }
1157     } else {
1158         for (count = 1; ai->ai_next; ++count, ai = ai->ai_next)
1159             ;
1160     }
1161
1162     /* Set the tail pointer and return count of appended items. */
1163     state->ai_tail = ai;
1164     return count;
1165 }
1166
1167 static struct sar_request *
1168 sar_getaddr_request(struct sar_request *req)
1169 {
1170     struct sar_getaddr_state *state;
1171     unsigned int len;
1172     char full_name[DNS_NAME_LENGTH];
1173
1174     state = (struct sar_getaddr_state*)(req + 1);
1175
1176     /* If we can and should, append the current search domain. */
1177     if (state->search_pos < conf.sar_search->used)
1178         snprintf(full_name, sizeof(full_name), "%s.%s", state->full_name, conf.sar_search->list[state->search_pos]);
1179     else if (state->search_pos == conf.sar_search->used)
1180         safestrncpy(full_name, state->full_name, sizeof(full_name));
1181     else {
1182         log_module(sar_log, LOG_DEBUG, "sar_getaddr_request({id=%d}): failed", req->id);
1183         state->cb(state->cb_ctx, NULL, SAI_NONAME);
1184         return NULL;
1185     }
1186
1187     /* Build the appropriate request for DNS record(s). */
1188     if (state->flags & SAI_ALL)
1189         len = sar_request_build(req, full_name + state->srv_ofs, REQ_QTYPE_ALL, NULL);
1190     else if (state->srv_ofs)
1191         len = state->helper->build_addr_request(req, full_name + state->srv_ofs, full_name, state->flags);
1192     else
1193         len = state->helper->build_addr_request(req, full_name, NULL, state->flags);
1194
1195     log_module(sar_log, LOG_DEBUG, "sar_getaddr_request({id=%d}): full_name=%s, srv_ofs=%d", req->id, full_name, state->srv_ofs);
1196
1197     /* Check that the request could be built. */
1198     if (!len) {
1199         state->cb(state->cb_ctx, NULL, SAI_NODATA);
1200         return NULL;
1201     }
1202
1203     /* Send the request. */
1204     sar_request_send(req);
1205     return req;
1206 }
1207
1208 static int
1209 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)
1210 {
1211     struct sar_getaddr_state *state;
1212     char *cname;
1213     unsigned int jj, pos, hit;
1214
1215     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);
1216     state = (struct sar_getaddr_state*)(req + 1);
1217
1218     switch (rr[rr_idx].type) {
1219     case REQ_TYPE_A:
1220         if (state->flags & SAI_ALL)
1221             return sar_ipv4_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1222 #if defined(AF_INET6)
1223         else if (state->flags & SAI_V4MAPPED)
1224             return sar_ipv6_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1225 #endif
1226         return state->helper->decode_addr(state, rr + rr_idx, raw, raw_size);
1227
1228     case REQ_TYPE_AAAA:
1229 #if defined(AF_INET6)
1230         if (state->flags & SAI_ALL)
1231             return sar_ipv6_helper.decode_addr(state, rr + rr_idx, raw, raw_size);
1232         return state->helper->decode_addr(state, rr + rr_idx, raw, raw_size);
1233 #else
1234         return 0;
1235 #endif
1236
1237     case REQ_TYPE_CNAME:
1238         /* there should be the canonical name next */
1239         pos = rr[rr_idx].rd_start;
1240         cname = sar_extract_name(raw, raw_size, &pos);
1241         if (!cname)
1242             return 0; /* XXX: eventually log the unhandled body */
1243         /* and it should correspond to some other answer in the response */
1244         for (jj = hit = 0; jj < hdr->ancount; ++jj) {
1245             if (strcasecmp(cname, rr[jj].name))
1246                 continue;
1247             hit += sar_getaddr_decode(req, hdr, rr, raw, raw_size, jj);
1248         }
1249         /* XXX: if (!hit) handle or log the incomplete recursion; */
1250         return hit;
1251
1252     case REQ_TYPE_SRV:
1253         /* TODO: decode the SRV record */
1254
1255     default:
1256         return 0;
1257     }
1258 }
1259
1260 static void
1261 sar_getaddr_ok(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1262 {
1263     struct sar_getaddr_state *state;
1264     unsigned int ii;
1265
1266     state = (struct sar_getaddr_state*)(req + 1);
1267
1268     log_module(sar_log, LOG_DEBUG, "sar_getaddr_ok({id=%d}, {id=%d}, <rr>, <data>, %u)", req->id, hdr->id, raw_size);
1269     for (ii = 0; ii < hdr->ancount; ++ii)
1270         sar_getaddr_decode(req, hdr, rr, raw, raw_size, ii);
1271
1272     /* If we found anything, report it, else try again. */
1273     if (state->ai_head)
1274         state->cb(state->cb_ctx, state->ai_head, SAI_SUCCESS);
1275     else
1276         sar_getaddr_request(req);
1277 }
1278
1279 static void
1280 sar_getaddr_fail(struct sar_request *req, UNUSED_ARG(unsigned int rcode))
1281 {
1282     struct sar_getaddr_state *state;
1283
1284     log_module(sar_log, LOG_DEBUG, "sar_getaddr_fail({id=%d}, rcode=%u)", req->id, rcode);
1285     state = (struct sar_getaddr_state*)(req + 1);
1286     state->cb(state->cb_ctx, NULL, SAI_FAIL);
1287 }
1288
1289 struct sar_request *
1290 sar_getaddr(const char *node, const char *service, const struct addrinfo *hints_, sar_addr_cb cb, void *cb_ctx)
1291 {
1292     struct sockaddr_storage ss;
1293     struct addrinfo hints;
1294     struct sar_family_helper *helper;
1295     struct service_byname *svc;
1296     char *end;
1297     unsigned int portnum;
1298     unsigned int pos;
1299     enum service_proto proto;
1300
1301     if (!node && !service) {
1302         cb(cb_ctx, NULL, SAI_NONAME);
1303         return NULL;
1304     }
1305
1306     /* Initialize local hints structure. */
1307     if (hints_)
1308         memcpy(&hints, hints_, sizeof(hints));
1309     else
1310         memset(&hints, 0, sizeof(hints));
1311
1312     /* Translate socket type to internal protocol. */
1313     switch (hints.ai_socktype) {
1314     case 0: hints.ai_socktype = SOCK_STREAM; /* and fall through */
1315     case SOCK_STREAM: proto = SERVICE_TCP; break;
1316     case SOCK_DGRAM: proto = SERVICE_UDP; break;
1317     default:
1318         cb(cb_ctx, NULL, SAI_SOCKTYPE);
1319         return NULL;
1320     }
1321
1322     /* Figure out preferred socket size. */
1323     if (hints.ai_family == AF_UNSPEC)
1324         hints.ai_family = AF_INET;
1325     if (hints.ai_family > MAX_FAMILY
1326         || !(helper = sar_helpers[hints.ai_family])) {
1327         cb(cb_ctx, NULL, SAI_FAMILY);
1328         return NULL;
1329     }
1330     hints.ai_addrlen = helper->socklen;
1331
1332     /* If \a node is NULL, figure out the correct default from the
1333      * requested family and SAI_PASSIVE flag.
1334      */
1335     if (node == NULL)
1336         node = (hints.ai_flags & SAI_PASSIVE) ? helper->unspec_addr : helper->localhost_addr;
1337
1338     /* Try to parse (failing that, look up) \a service. */
1339     if (!service)
1340         portnum = 0, svc = NULL;
1341     else if ((portnum = strtoul(service, &end, 10)), *end == '\0')
1342         svc = NULL;
1343     else if ((svc = sar_service_byname(service, 0)) != NULL)
1344         portnum = svc->protos[proto].port;
1345     else {
1346         cb(cb_ctx, NULL, SAI_SERVICE);
1347         return NULL;
1348     }
1349
1350     /* Try to parse \a node as a numeric hostname.*/
1351     pos = sar_pton((struct sockaddr*)&ss, sizeof(ss), NULL, node);
1352     if (pos && node[pos] == '\0') {
1353         struct addrinfo *ai;
1354         char canonname[SAR_NTOP_MAX];
1355
1356         /* we have a valid address; use it */
1357         sar_set_port((struct sockaddr*)&ss, sizeof(ss), portnum);
1358         hints.ai_addrlen = sar_addrlen((struct sockaddr*)&ss, sizeof(ss));
1359         if (!hints.ai_addrlen) {
1360             cb(cb_ctx, NULL, SAI_FAMILY);
1361             return NULL;
1362         }
1363         pos = sar_ntop(canonname, sizeof(canonname), (struct sockaddr*)&ss, hints.ai_addrlen);
1364
1365         /* allocate and fill in the addrinfo response */
1366         ai = calloc(1, sizeof(*ai) + hints.ai_addrlen + pos + 1);
1367         ai->ai_family = ss.ss_family;
1368         ai->ai_socktype = hints.ai_socktype;
1369         ai->ai_protocol = hints.ai_protocol;
1370         ai->ai_addrlen = hints.ai_addrlen;
1371         ai->ai_addr = memcpy(ai + 1, &ss, ai->ai_addrlen);
1372         ai->ai_canonname = strcpy((char*)ai->ai_addr + ai->ai_addrlen, canonname);
1373         cb(cb_ctx, ai, SAI_SUCCESS);
1374         return NULL;
1375     } else if (hints.ai_flags & SAI_NUMERICHOST) {
1376         cb(cb_ctx, NULL, SAI_NONAME);
1377         return NULL;
1378     } else {
1379         struct sar_request *req;
1380         struct sar_getaddr_state *state;
1381         unsigned int len, ii;
1382
1383         req = sar_request_alloc(sizeof(*state), sar_getaddr_ok, sar_getaddr_fail);
1384
1385         state = (struct sar_getaddr_state*)(req + 1);
1386         state->helper = helper;
1387         state->ai_head = state->ai_tail = NULL;
1388         state->cb = cb;
1389         state->cb_ctx = cb_ctx;
1390         state->flags = hints.ai_flags;
1391         state->socktype = hints.ai_socktype;
1392         state->protocol = hints.ai_protocol;
1393         state->port = portnum;
1394
1395         if ((state->flags & SAI_NOSRV) || !svc)
1396             state->srv_ofs = 0;
1397         else if (svc->protos[proto].srv)
1398             state->srv_ofs = snprintf(state->full_name, sizeof(state->full_name), "_%s._%s.", svc->name, (proto == SERVICE_UDP ? "udp" : "tcp"));
1399         else if (state->flags & SAI_FORCESRV)
1400             state->srv_ofs = snprintf(state->full_name, sizeof(state->full_name), "_%s._%s.", service, (proto == SERVICE_UDP ? "udp" : "tcp"));
1401         else
1402             state->srv_ofs = 0;
1403
1404         if (state->srv_ofs < sizeof(state->full_name))
1405             safestrncpy(state->full_name + state->srv_ofs, node, sizeof(state->full_name) - state->srv_ofs);
1406
1407         for (ii = len = 0; node[ii]; ++ii)
1408             if (node[ii] == '.')
1409                 len++;
1410         if (len >= conf.sar_ndots)
1411             state->search_pos = conf.sar_search->used;
1412         else
1413             state->search_pos = 0;
1414
1415         /* XXX: fill in *state with any other fields needed to parse responses. */
1416
1417         if (!sar_getaddr_request(req)) {
1418             free(req);
1419             return NULL;
1420         }
1421         return req;
1422     }
1423 }
1424
1425 struct sar_getname_state {
1426     sar_name_cb cb;
1427     void *cb_ctx;
1428     char *hostname;
1429     unsigned int flags;
1430     unsigned int family;
1431     enum service_proto proto;
1432     unsigned short port;
1433     unsigned int doing_arpa : 1; /* checking .ip6.arpa vs .ip6.int */
1434     unsigned char original[16]; /* original address data */
1435     /* name must be long enough to hold "0.0.<etc>.ip6.arpa" */
1436     char name[74];
1437 };
1438
1439 static void
1440 sar_getname_fail(struct sar_request *req, UNUSED_ARG(unsigned int rcode))
1441 {
1442     struct sar_getname_state *state;
1443     unsigned int len;
1444
1445     state = (struct sar_getname_state*)(req + 1);
1446     if (state->doing_arpa) {
1447         len = strlen(state->name);
1448         assert(len == 73);
1449         strcpy(state->name + len - 4, "int");
1450         len = sar_request_build(req, state->name, REQ_TYPE_PTR, NULL);
1451         if (len) {
1452             sar_request_send(req);
1453             return;
1454         }
1455     }
1456     state->cb(state->cb_ctx, NULL, NULL, SAI_FAIL);
1457     free(state->hostname);
1458 }
1459
1460 static const char *sar_getname_port(unsigned int port, unsigned int flags, char *tmpbuf, unsigned int tmpbuf_len)
1461 {
1462     struct service_byport *service;
1463     enum service_proto proto;
1464     char port_text[12];
1465
1466     sprintf(port_text, "%d", port);
1467     proto = (flags & SNI_DGRAM) ? SERVICE_UDP : SERVICE_TCP;
1468     if (!(flags & SNI_NUMERICSERV)
1469         && (service = dict_find(services_byport, port_text, NULL))
1470         && service->byname[proto])
1471         return service->byname[proto]->name;
1472     snprintf(tmpbuf, tmpbuf_len, "%d", port);
1473     return tmpbuf;
1474 }
1475
1476 static void
1477 sar_getname_confirm(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1478 {
1479     struct sar_getname_state *state;
1480     const unsigned char *data;
1481     const char *portname;
1482     char servbuf[16];
1483     unsigned int ii, nbr;
1484
1485     state = (struct sar_getname_state*)(req + 1);
1486     for (ii = 0; ii < hdr->ancount; ++ii) {
1487         /* Is somebody confused or trying to play games? */
1488         if (rr[ii].class != REQ_CLASS_IN
1489             || strcasecmp(state->hostname, rr[ii].name))
1490             continue;
1491         switch (rr[ii].type) {
1492         case REQ_TYPE_A: nbr = 4; break;
1493         case REQ_TYPE_AAAA: nbr = 16; break;
1494         default: continue;
1495         }
1496         data = sar_extract_rdata(rr, nbr, raw, raw_size);
1497         if (data && !memcmp(data, state->original, nbr)) {
1498             portname = sar_getname_port(state->port, state->flags, servbuf, sizeof(servbuf));
1499             state->cb(state->cb_ctx, state->hostname, portname, SAI_SUCCESS);
1500             free(state->hostname);
1501             return;
1502         }
1503     }
1504     state->cb(state->cb_ctx, NULL, NULL, SAI_MISMATCH);
1505     free(state->hostname);
1506 }
1507
1508 static void
1509 sar_getname_ok(struct sar_request *req, struct dns_header *hdr, struct dns_rr *rr, unsigned char *raw, unsigned int raw_size)
1510 {
1511     struct sar_getname_state *state;
1512     const char *portname;
1513     unsigned int ii, pos;
1514     char servbuf[16];
1515
1516     state = (struct sar_getname_state*)(req + 1);
1517     for (ii = 0; ii < hdr->ancount; ++ii) {
1518         if (rr[ii].type != REQ_TYPE_PTR
1519             || rr[ii].class != REQ_CLASS_IN
1520             || strcasecmp(rr[ii].name, state->name))
1521             continue;
1522         pos = rr[ii].rd_start;
1523         state->hostname = sar_extract_name(raw, raw_size, &pos);
1524         break;
1525     }
1526
1527     if (!state->hostname) {
1528         state->cb(state->cb_ctx, NULL, NULL, SAI_NONAME);
1529         return;
1530     }
1531
1532     if (state->flags & SNI_PARANOID) {
1533         req->cb_ok = sar_getname_confirm;
1534         pos = sar_helpers[state->family]->build_addr_request(req, state->hostname, NULL, 0);
1535         if (pos)
1536             sar_request_send(req);
1537         else {
1538             free(state->hostname);
1539             state->cb(state->cb_ctx, NULL, NULL, SAI_FAIL);
1540         }
1541         return;
1542     }
1543
1544     portname = sar_getname_port(state->port, state->flags, servbuf, sizeof(servbuf));
1545     state->cb(state->cb_ctx, state->hostname, portname, SAI_SUCCESS);
1546     free(state->hostname);
1547 }
1548
1549 struct sar_request *
1550 sar_getname(const struct sockaddr *sa, unsigned int salen, int flags, sar_name_cb cb, void *cb_ctx)
1551 {
1552     struct sar_family_helper *helper;
1553     struct sar_request *req;
1554     struct sar_getname_state *state;
1555     unsigned int len;
1556     int port;
1557
1558     if (sa->sa_family > MAX_FAMILY
1559         || !(helper = sar_helpers[sa->sa_family])) {
1560         cb(cb_ctx, NULL, NULL, SAI_FAMILY);
1561         return NULL;
1562     }
1563
1564     port = helper->get_port(sa, salen);
1565
1566     if (flags & SNI_NUMERICHOST) {
1567         const char *servname;
1568         unsigned int len;
1569         char host[SAR_NTOP_MAX], servbuf[16];
1570
1571         /* If appropriate, try to look up service name. */
1572         servname = sar_getname_port(port, flags, servbuf, sizeof(servbuf));
1573         len = sar_ntop(host, sizeof(host), sa, salen);
1574         assert(len != 0);
1575         cb(cb_ctx, host, servname, SAI_SUCCESS);
1576         return NULL;
1577     }
1578
1579     req = sar_request_alloc(sizeof(*state), sar_getname_ok, sar_getname_fail);
1580
1581     state = (struct sar_getname_state*)(req + 1);
1582     state->cb = cb;
1583     state->cb_ctx = cb_ctx;
1584     state->flags = flags;
1585     state->family = sa->sa_family;
1586     state->port = port;
1587
1588     helper->build_ptr_name(state, sa, salen);
1589     assert(strlen(state->name) < sizeof(state->name));
1590     len = sar_request_build(req, state->name, REQ_TYPE_PTR, NULL);
1591     if (!len) {
1592         cb(cb_ctx, NULL, NULL, SAI_NODATA);
1593         free(req);
1594         return NULL;
1595     }
1596
1597     sar_request_send(req);
1598     return req;
1599 }
1600
1601 static unsigned int
1602 ipv4_ntop(char *output, unsigned int out_size, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1603 {
1604     struct sockaddr_in *sin;
1605     unsigned int ip4, pos;
1606
1607     sin = (struct sockaddr_in*)sa;
1608     ip4 = ntohl(sin->sin_addr.s_addr);
1609     pos = snprintf(output, out_size, "%u.%u.%u.%u", (ip4 >> 24), (ip4 >> 16) & 255, (ip4 >> 8) & 255, ip4 & 255);
1610     return (pos < out_size) ? pos : 0;
1611 }
1612
1613 static unsigned int
1614 sar_pton_ip4(const char *input, unsigned int *bits, uint32_t *output)
1615 {
1616     unsigned int dots = 0, pos = 0, part = 0, ip = 0;
1617
1618     /* Intentionally no support for bizarre IPv4 formats (plain
1619      * integers, octal or hex components) -- only vanilla dotted
1620      * decimal quads, optionally with trailing /nn.
1621      */
1622     if (input[0] == '.')
1623         return 0;
1624     while (1) {
1625         if (isdigit(input[pos])) {
1626             part = part * 10 + input[pos++] - '0';
1627             if (part > 255)
1628                 return 0;
1629             if ((dots == 3) && !isdigit(input[pos])) {
1630                 *output = htonl(ip | part);
1631                 return pos;
1632             }
1633         } else if (input[pos] == '.') {
1634             if (input[++pos] == '.')
1635                 return 0;
1636             ip |= part << (24 - 8 * dots++);
1637             part = 0;
1638         } else if (bits && input[pos] == '/' && isdigit(input[pos + 1])) {
1639             unsigned int len;
1640             char *term;
1641
1642             len = strtoul(input + pos + 1, &term, 10);
1643             if (term <= input + pos + 1)
1644                 return pos;
1645             else if (len > 32)
1646                 return 0;
1647             *bits = len;
1648             return term - input;
1649         } else return 0;
1650     }
1651 }
1652
1653 static unsigned int
1654 ipv4_pton(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned int *bits, const char *input)
1655 {
1656     unsigned int pos;
1657
1658     pos = sar_pton_ip4(input, bits, &((struct sockaddr_in*)sa)->sin_addr.s_addr);
1659     if (!pos)
1660         return 0;
1661     sa->sa_family = AF_INET;
1662     return pos;
1663 }
1664
1665 static int
1666 ipv4_get_port(const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1667 {
1668     return ntohs(((const struct sockaddr_in*)sa)->sin_port);
1669 }
1670
1671 static int
1672 ipv4_set_port(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned short port)
1673 {
1674     ((struct sockaddr_in*)sa)->sin_port = htons(port);
1675     return 0;
1676 }
1677
1678 static unsigned int
1679 ipv4_addr_request(struct sar_request *req, const char *node, const char *srv_node, UNUSED_ARG(unsigned int flags))
1680 {
1681     unsigned int len;
1682     if (srv_node)
1683         len = sar_request_build(req, node, REQ_TYPE_A, srv_node, REQ_TYPE_SRV, NULL);
1684     else
1685         len = sar_request_build(req, node, REQ_TYPE_A, NULL);
1686     return len;
1687 }
1688
1689 static void
1690 ipv4_ptr_name(struct sar_getname_state *state, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1691 {
1692     const uint8_t *bytes;
1693
1694     bytes = (uint8_t*)&((struct sockaddr_in*)sa)->sin_addr.s_addr;
1695     memcpy(state->original, bytes, 4);
1696     snprintf(state->name, sizeof(state->name),
1697              "%u.%u.%u.%u.in-addr.arpa",
1698              bytes[3], bytes[2], bytes[1], bytes[0]);
1699 }
1700
1701 static int
1702 ipv4_decode(struct sar_getaddr_state *state, struct dns_rr *rr, unsigned char *raw, UNUSED_ARG(unsigned int raw_size))
1703 {
1704     struct sockaddr_in *sa;
1705     struct addrinfo *ai;
1706
1707     if (rr->rdlength != 4)
1708         return 0;
1709
1710     if (state->flags & SAI_CANONNAME) {
1711         ai = calloc(1, sizeof(*ai) + sizeof(*sa) + strlen(rr->name) + 1);
1712         sa = (struct sockaddr_in*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1713         ai->ai_canonname = strcpy((char*)(sa + 1), rr->name);
1714     } else {
1715         ai = calloc(1, sizeof(*ai) + sizeof(*sa));
1716         sa = (struct sockaddr_in*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1717         ai->ai_canonname = NULL;
1718     }
1719
1720     ai->ai_family = AF_INET;
1721     sa->sin_port = htons(state->port);
1722     memcpy(&sa->sin_addr.s_addr, raw + rr->rd_start, 4);
1723     return sar_getaddr_append(state, ai, 1);
1724 }
1725
1726 static struct sar_family_helper sar_ipv4_helper = {
1727     "127.0.0.1",
1728     "0.0.0.0",
1729     sizeof(struct sockaddr_in),
1730     AF_INET,
1731     ipv4_ntop,
1732     ipv4_pton,
1733     ipv4_get_port,
1734     ipv4_set_port,
1735     ipv4_addr_request,
1736     ipv4_ptr_name,
1737     ipv4_decode,
1738     NULL
1739 };
1740
1741 #if defined(AF_INET6)
1742
1743 static unsigned int
1744 ipv6_ntop(char *output, unsigned int out_size, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1745 {
1746     struct sockaddr_in6 *sin6;
1747     unsigned int pos, part, max_start, max_zeros, curr_zeros, ii;
1748     unsigned short addr16;
1749
1750     sin6 = (struct sockaddr_in6*)sa;
1751     /* Find longest run of zeros. */
1752     for (max_start = max_zeros = curr_zeros = ii = 0; ii < 8; ++ii) {
1753         addr16 = (sin6->sin6_addr.s6_addr[ii * 2] << 8) | sin6->sin6_addr.s6_addr[ii * 2 + 1];
1754         if (!addr16)
1755             curr_zeros++;
1756         else if (curr_zeros > max_zeros) {
1757             max_start = ii - curr_zeros;
1758             max_zeros = curr_zeros;
1759             curr_zeros = 0;
1760         }
1761     }
1762     if (curr_zeros > max_zeros) {
1763         max_start = ii - curr_zeros;
1764         max_zeros = curr_zeros;
1765     }
1766
1767     /* Print out address. */
1768 #define APPEND(CH) do { output[pos++] = (CH); if (pos >= out_size) return 0; } while (0)
1769     for (pos = 0, ii = 0; ii < 8; ++ii) {
1770         if ((max_zeros > 0) && (ii == max_start)) {
1771             if (ii == 0)
1772                 APPEND(':');
1773             APPEND(':');
1774             ii += max_zeros - 1;
1775             continue;
1776         }
1777         part = (sin6->sin6_addr.s6_addr[ii * 2] << 8) | sin6->sin6_addr.s6_addr[ii * 2 + 1];
1778         if (part >= 0x1000)
1779             APPEND(hexdigits[part >> 12]);
1780         if (part >= 0x100)
1781             APPEND(hexdigits[(part >> 8) & 15]);
1782         if (part >= 0x10)
1783             APPEND(hexdigits[(part >> 4) & 15]);
1784         APPEND(hexdigits[part & 15]);
1785         if (ii < 7)
1786             APPEND(':');
1787     }
1788     APPEND('\0');
1789 #undef APPEND
1790
1791     return pos;
1792 }
1793
1794 static const unsigned char xdigit_value[256] = {
1795    0, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1798    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
1799    0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1800    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1801    0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1802 };
1803
1804 static unsigned int
1805 ipv6_pton(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned int *bits, const char *input)
1806 {
1807     const char *part_start = NULL;
1808     struct sockaddr_in6 *sin6;
1809     char *colon;
1810     char *dot;
1811     unsigned int part = 0, pos = 0, ii = 0, cpos = 8;
1812
1813     if (!(colon = strchr(input, ':')))
1814         return 0;
1815     dot = strchr(input, '.');
1816     if (dot && dot < colon)
1817         return 0;
1818     sin6 = (struct sockaddr_in6*)sa;
1819     /* Parse IPv6, possibly like ::127.0.0.1.
1820      * This is pretty straightforward; the only trick is borrowed
1821      * from Paul Vixie (BIND): when it sees a "::" continue as if
1822      * it were a single ":", but note where it happened, and fill
1823      * with zeros afterwards.
1824      */
1825     if (input[pos] == ':') {
1826         if ((input[pos+1] != ':') || (input[pos+2] == ':'))
1827             return 0;
1828         cpos = 0;
1829         pos += 2;
1830         part_start = input + pos;
1831     }
1832     while (ii < 8) {
1833         if (isxdigit(input[pos])) {
1834             part = (part << 4) | xdigit_value[(unsigned char)input[pos]];
1835             if (part > 0xffff)
1836                 return 0;
1837             pos++;
1838         } else if (input[pos] == ':') {
1839             part_start = input + ++pos;
1840             if (input[pos] == '.')
1841                 return 0;
1842             sin6->sin6_addr.s6_addr[ii * 2] = part >> 8;
1843             sin6->sin6_addr.s6_addr[ii * 2 + 1] = part & 255;
1844             ii++;
1845             part = 0;
1846             if (input[pos] == ':') {
1847                 if (cpos < 8)
1848                     return 0;
1849                 cpos = ii;
1850                 pos++;
1851             }
1852         } else if (input[pos] == '.') {
1853             uint32_t ip4;
1854             unsigned int len;
1855             len = sar_pton_ip4(part_start, bits, &ip4);
1856             if (!len || (ii > 6))
1857                 return 0;
1858             memcpy(sin6->sin6_addr.s6_addr + ii * 2, &ip4, sizeof(ip4));
1859             if (bits)
1860                 *bits += ii * 16;
1861             ii += 2;
1862             pos = part_start + len - input;
1863             break;
1864         } else if (bits && input[pos] == '/' && isdigit(input[pos + 1])) {
1865             unsigned int len;
1866             char *term;
1867
1868             len = strtoul(input + pos + 1, &term, 10);
1869             if (term <= input + pos + 1)
1870                 break;
1871             else if (len > 128)
1872                 return 0;
1873             if (bits)
1874                 *bits = len;
1875             pos = term - input;
1876             break;
1877         } else if (cpos <= 8) {
1878             sin6->sin6_addr.s6_addr[ii * 2] = part >> 8;
1879             sin6->sin6_addr.s6_addr[ii * 2 + 1] = part & 255;
1880             ii++;
1881             break;
1882         } else return 0;
1883     }
1884     /* Shift stuff after "::" up and fill middle with zeros. */
1885     if (cpos < 8) {
1886         unsigned int jj;
1887         ii <<= 1;
1888         cpos <<= 1;
1889         for (jj = 0; jj < ii - cpos; jj++)
1890             sin6->sin6_addr.s6_addr[15 - jj] = sin6->sin6_addr.s6_addr[ii - jj - 1];
1891         for (jj = 0; jj < 16 - ii; jj++)
1892             sin6->sin6_addr.s6_addr[cpos + jj] = 0;
1893     }
1894     sa->sa_family = AF_INET6;
1895     return pos;
1896 }
1897
1898 static int
1899 ipv6_get_port(const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1900 {
1901     return ntohs(((const struct sockaddr_in6*)sa)->sin6_port);
1902 }
1903
1904 static int
1905 ipv6_set_port(struct sockaddr *sa, UNUSED_ARG(unsigned int socklen), unsigned short port)
1906 {
1907     ((struct sockaddr_in6*)sa)->sin6_port = htons(port);
1908     return 0;
1909 }
1910
1911 static unsigned int
1912 ipv6_addr_request(struct sar_request *req, const char *node, const char *srv_node, unsigned int flags)
1913 {
1914     unsigned int len;
1915     if (flags & SAI_V4MAPPED) {
1916         if (srv_node)
1917             len = sar_request_build(req, node, REQ_TYPE_AAAA, node, REQ_TYPE_A, srv_node, REQ_TYPE_SRV, NULL);
1918         else
1919             len = sar_request_build(req, node, REQ_TYPE_AAAA, node, REQ_TYPE_A, NULL);
1920     } else {
1921         if (srv_node)
1922             len = sar_request_build(req, node, REQ_TYPE_AAAA, srv_node, REQ_TYPE_SRV, NULL);
1923         else
1924             len = sar_request_build(req, node, REQ_TYPE_AAAA, NULL);
1925     }
1926     return len;
1927 }
1928
1929 static void
1930 ipv6_ptr_name(struct sar_getname_state *state, const struct sockaddr *sa, UNUSED_ARG(unsigned int socklen))
1931 {
1932     const uint8_t *bytes;
1933     unsigned int ii, jj;
1934
1935     bytes = ((struct sockaddr_in6*)sa)->sin6_addr.s6_addr;
1936     memcpy(state->original, bytes, 16);
1937     for (jj = 0, ii = 16; ii > 0; ) {
1938         state->name[jj++] = hexdigits[bytes[--ii] & 15];
1939         state->name[jj++] = hexdigits[bytes[ii] >> 4];
1940         state->name[jj++] = '.';
1941     }
1942     strcpy(state->name + jj, ".ip6.arpa");
1943     state->doing_arpa = 1;
1944 }
1945
1946 static int
1947 ipv6_decode(struct sar_getaddr_state *state, struct dns_rr *rr, unsigned char *raw, UNUSED_ARG(unsigned int raw_size))
1948 {
1949     struct sockaddr_in6 *sa;
1950     struct addrinfo *ai;
1951
1952     if (state->flags & SAI_CANONNAME) {
1953         ai = calloc(1, sizeof(*ai) + sizeof(*sa) + strlen(rr->name) + 1);
1954         sa = (struct sockaddr_in6*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1955         ai->ai_canonname = strcpy((char*)(sa + 1), rr->name);
1956     } else {
1957         ai = calloc(1, sizeof(*ai) + sizeof(*sa));
1958         sa = (struct sockaddr_in6*)(ai->ai_addr = (struct sockaddr*)(ai + 1));
1959         ai->ai_canonname = NULL;
1960     }
1961
1962     if (rr->rdlength == 4) {
1963         sa->sin6_addr.s6_addr[10] = sa->sin6_addr.s6_addr[11] = 0xff;
1964         memcpy(sa->sin6_addr.s6_addr + 12, raw + rr->rd_start, 4);
1965     } else if (rr->rdlength == 16) {
1966         memcpy(sa->sin6_addr.s6_addr, raw + rr->rd_start, 16);
1967     } else {
1968         free(ai);
1969         return 0;
1970     }
1971
1972     ai->ai_family = AF_INET6;
1973     sa->sin6_port = htons(state->port);
1974     return sar_getaddr_append(state, ai, 1);
1975 }
1976
1977 static struct sar_family_helper sar_ipv6_helper = {
1978     "::1",
1979     "::",
1980     sizeof(struct sockaddr_in6),
1981     AF_INET6,
1982     ipv6_ntop,
1983     ipv6_pton,
1984     ipv6_get_port,
1985     ipv6_set_port,
1986     ipv6_addr_request,
1987     ipv6_ptr_name,
1988     ipv6_decode,
1989     NULL
1990 };
1991
1992 #endif /* defined(AF_INET6) */
1993
1994 static void
1995 sar_cleanup(void)
1996 {
1997     ioset_close(sar_fd, 1);
1998     dict_delete(services_byname);
1999     dict_delete(services_byport);
2000     dict_delete(sar_nameservers);
2001     dict_delete(sar_requests);
2002 }
2003
2004 static void
2005 sar_conf_reload(void)
2006 {
2007     dict_t node;
2008     const char *resolv_conf = "/etc/resolv.conf";
2009     const char *services = "/etc/services";
2010     const char *str;
2011
2012     node = conf_get_data("modules/sar", RECDB_OBJECT);
2013     if (node != NULL) {
2014         str = database_get_data(node, "resolv_conf", RECDB_QSTRING);
2015         if (str) resolv_conf = str;
2016         str = database_get_data(node, "services", RECDB_QSTRING);
2017         if (str) services = str;
2018     }
2019     sar_dns_init(resolv_conf);
2020     sar_services_init(services);
2021 }
2022
2023 void
2024 sar_init(void)
2025 {
2026     reg_exit_func(sar_cleanup);
2027     sar_log = log_register_type("sar", NULL);
2028
2029     sar_requests = dict_new();
2030     dict_set_free_data(sar_requests, sar_request_cleanup);
2031
2032     sar_nameservers = dict_new();
2033     dict_set_free_data(sar_nameservers, free);
2034
2035     services_byname = dict_new();
2036     dict_set_free_data(services_byname, free);
2037
2038     services_byport = dict_new();
2039     dict_set_free_data(services_byport, free);
2040
2041     sar_register_helper(&sar_ipv4_helper);
2042 #if defined(AF_INET6)
2043     sar_register_helper(&sar_ipv6_helper);
2044 #endif
2045
2046     conf_register_reload(sar_conf_reload);
2047 }