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 3 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 #if defined(HAVE_NETINET_IN_H)
28 # include <netinet/in.h> /* sockaddr_in6 on some BSDs */
31 static const char hexdigits
[] = "0123456789abcdef";
34 struct sar_getaddr_state
;
35 struct sar_getname_state
;
37 struct sar_family_helper
{
38 const char *localhost_addr
;
39 const char *unspec_addr
;
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
);
51 struct sar_family_helper
*next
;
54 #define MAX_FAMILY AF_INET
55 static struct sar_family_helper sar_ipv4_helper
;
58 # if AF_INET6 > MAX_FAMILY
60 # define MAX_FAMILY AF_INET6
62 static struct sar_family_helper sar_ipv6_helper
;
65 static struct sar_family_helper
*sar_helpers
[MAX_FAMILY
+1];
66 static struct sar_family_helper
*sar_first_helper
;
69 sar_ntop(char *output
, unsigned int out_size
, const struct sockaddr
*sa
, unsigned int socklen
)
72 assert(output
!= NULL
);
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
);
86 sar_pton(struct sockaddr
*sa
, unsigned int socklen
, unsigned int *bits
, const char *input
)
88 struct sar_family_helper
*helper
;
92 assert(input
!= NULL
);
94 memset(sa
, 0, socklen
);
97 for (helper
= sar_first_helper
; helper
; helper
= helper
->next
) {
98 if (socklen
< helper
->socklen
)
100 len
= helper
->pton(sa
, socklen
, bits
, input
);
102 sa
->sa_family
= helper
->family
;
106 return 0; /* parse failed */
110 sar_get_port(const struct sockaddr
*sa
, unsigned int socklen
)
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
);
120 sar_set_port(struct sockaddr
*sa
, unsigned int socklen
, unsigned short port
)
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
);
130 sar_strerror(enum sar_errcode 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.";
151 sar_free(struct addrinfo
*ai
)
153 struct addrinfo
*next
;
154 for (; ai
; ai
= next
) {
160 /** Global variables to support DNS name resolution. */
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 void *sar_bind_address
;
171 static struct log_type
*sar_log
;
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.
178 * Update queries (including RFC 2136) seems a likely candidate for
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
185 * Other DNS extensions (at least through RFC 3755) are believed to be
186 * too rare or insufficiently useful to bother supporting.
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
194 struct sar_nameserver
{
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
;
208 /* EDNS0 uses 12 bit RCODEs, TSIG/TKEY use 16 bit RCODEs.
209 * Declare local RCODE failures here.*/
211 RCODE_TIMED_OUT
= 65536,
212 RCODE_QUERY_TOO_LONG
,
213 RCODE_LABEL_TOO_LONG
,
214 RCODE_SOCKET_FAILURE
,
218 #define DNS_NAME_LENGTH 256
220 #define RES_SIZE_FLAGS 0xc0
221 #define RES_SF_LABEL 0x00
222 #define RES_SF_POINTER 0xc0
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
;
230 sar_rcode_text(unsigned int 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";
250 sar_request_fail(struct sar_request
*req
, unsigned int rcode
)
252 log_module(sar_log
, LOG_DEBUG
, "sar_request_fail({id=%d}, rcode=%d)", req
->id
, rcode
);
255 req
->cb_fail(req
, rcode
);
259 sar_request_abort(req
);
262 static unsigned long next_sar_timeout
;
265 sar_timeout_cb(void *data
)
268 dict_iterator_t next
;
269 time_t next_timeout
= INT_MAX
;
271 for (it
= dict_first(sar_requests
); it
; it
= next
) {
272 struct sar_request
*req
;
275 next
= iter_next(it
);
276 if (req
->expiry
> next_timeout
)
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
);
283 sar_request_send(req
);
285 if (next_timeout
< INT_MAX
) {
286 next_sar_timeout
= next_timeout
;
287 timeq_add(next_timeout
, sar_timeout_cb
, data
);
292 sar_check_timeout(unsigned long when
)
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
;
302 sar_request_cleanup(void *d
)
304 struct sar_request
*req
= d
;
305 log_module(sar_log
, LOG_DEBUG
, "sar_request_cleanup({id=%d})", req
->id
);
308 req
->cb_fail(req
, RCODE_DESTROYED
);
313 sar_dns_init(const char *resolv_conf_path
)
315 struct string_list
*ns_sv
;
316 struct string_list
*ds_sv
;
321 /* Initialize configuration defaults. */
322 conf
.sar_localdomain
[0] = '\0';
323 conf
.sar_timeout
= 3;
324 conf
.sar_retries
= 3;
327 ns_sv
= alloc_string_list(4);
328 ds_sv
= alloc_string_list(4);
330 /* Scan resolver configuration file. */
331 resolv_conf
= fopen(resolv_conf_path
, "r");
335 char linebuf
[LINE_MAX
], ch
;
337 while (fgets(linebuf
, sizeof(linebuf
), resolv_conf
)) {
338 ch
= linebuf
[len
= strcspn(linebuf
, " \t\r\n")];
340 arg
= linebuf
+ len
+ 1;
341 if (!strcmp(linebuf
, "nameserver")) {
343 ch
= arg
[len
= strcspn(arg
, " \t\r\n")];
345 string_list_append(ns_sv
, strdup(arg
));
348 } else if (!strcmp(linebuf
, "domain")) {
350 safestrncpy(conf
.sar_localdomain
, arg
, sizeof(conf
.sar_localdomain
));
352 } else if (!strcmp(linebuf
, "search")) {
354 ch
= arg
[len
= strcspn(arg
, " \t\r\n")];
356 string_list_append(ds_sv
, strdup(arg
));
359 } else if (!strcmp(linebuf
, "options")) {
361 ch
= arg
[len
= strcspn(arg
, " \t\r\n")];
363 opt
= strchr(arg
, ':');
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
);
375 } else if (!strcmp(arg
, "edns0")) {
376 conf
.sar_edns0
= 1440;
384 /* This is apparently what BIND defaults to using. */
385 string_list_append(ns_sv
, "127.0.0.1");
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
));
392 /* Check configuration entries that might override resolv.conf. */
393 node
= conf_get_data("modules/sar", RECDB_OBJECT
);
396 struct string_list
*slist
;
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
);
410 free_string_list(ds_sv
);
411 ds_sv
= string_list_copy(slist
);
413 slist
= database_get_data(node
, "nameservers", RECDB_STRING_LIST
);
415 free_string_list(ns_sv
);
416 ns_sv
= string_list_copy(slist
);
418 sa
= (struct sockaddr
*)conf
.sar_bind_address
;
419 memset(sa
, 0, sizeof(struct sockaddr_storage
));
420 str
= database_get_data(node
, "bind_address", RECDB_QSTRING
);
421 if (str
) sar_pton(sa
, sizeof(struct sockaddr_storage
), NULL
, str
);
422 str
= database_get_data(node
, "bind_port", RECDB_QSTRING
);
424 if (sa
->sa_family
== AF_INET
) {
425 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
426 sin
->sin_port
= ntohs(atoi(str
));
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
));
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
;
445 sar_request_abort(struct sar_request
*req
)
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
);
453 dict_remove(sar_requests
, req
->id_text
);
456 static struct sar_nameserver
*
457 sar_our_server(const struct sockaddr_storage
*ss
, unsigned int ss_len
)
461 for (it
= dict_first(sar_nameservers
); it
; it
= iter_next(it
)) {
462 struct sar_nameserver
*ns
;
465 if (ns
->ss_len
== ss_len
&& !memcmp(ss
, ns
->ss
, ss_len
))
472 sar_extract_name(const unsigned char *buf
, unsigned int size
, unsigned int *ppos
)
474 struct string_buffer cv
;
475 unsigned int pos
, jumped
;
481 cv
.list
= calloc(1, cv
.size
);
489 cv
.list
[cv
.used
- 1] = '\0'; /* chop off terminating '.' */
491 string_buffer_append(&cv
, '\0');
494 switch (buf
[pos
] & RES_SIZE_FLAGS
) {
496 unsigned int len
= buf
[pos
];
497 if (pos
+ len
+ 1 >= size
)
499 string_buffer_append_substring(&cv
, (char*)buf
+ pos
+ 1, len
);
500 string_buffer_append(&cv
, '.');
505 if ((pos
+ 1 >= size
) || (cv
.used
>= size
))
509 pos
= (buf
[pos
] & ~RES_SIZE_FLAGS
) << 8 | buf
[pos
+1];
522 sar_decode_answer(struct sar_request
*req
, struct dns_header
*hdr
, unsigned char *buf
, unsigned int size
)
525 unsigned int ii
, rr_count
, pos
;
528 /* Skip over query section. */
529 for (ii
= 0, pos
= 12; ii
< hdr
->qdcount
; ++ii
) {
530 /* Skip over compressed names. */
536 switch (buf
[pos
] & RES_SIZE_FLAGS
) {
543 pos
= (buf
[pos
] & ~RES_SIZE_FLAGS
) << 8 | buf
[pos
+1];
551 /* Skip over null terminator, type and class part of question. */
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
);
564 if (pos
+ 10 > size
) {
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;
581 req
->cb_ok(req
, hdr
, rr
, buf
, size
);
585 dict_remove(sar_requests
, req
->id_text
);
595 static const unsigned char *
596 sar_extract_rdata(struct dns_rr
*rr
, unsigned int len
, unsigned char *raw
, unsigned int raw_size
)
598 if (len
> rr
->rdlength
)
600 if (rr
->rd_start
+ len
> raw_size
)
602 return raw
+ rr
->rd_start
;
606 sar_fd_readable(struct io_fd
*fd
)
608 struct dns_header hdr
;
609 struct sar_nameserver
*ns
;
610 struct sar_request
*req
;
614 int res
, rcode
, buf_len
;
617 assert(sar_fd
== fd
);
618 buf_len
= conf
.sar_edns0
;
621 buf
= alloca(buf_len
);
622 ss_len
= sizeof(struct sockaddr_storage
);
624 res
= recvfrom(sar_fd_fd
, buf
, buf_len
, 0, (struct sockaddr
*)ss
, &ss_len
);
625 if (res
< 12 || !(ns
= sar_our_server((struct sockaddr_storage
*)ss
, ss_len
)))
627 hdr
.id
= buf
[0] << 8 | buf
[1];
628 hdr
.flags
= buf
[2] << 8 | buf
[3];
629 hdr
.qdcount
= buf
[4] << 8 | buf
[5];
630 hdr
.ancount
= buf
[6] << 8 | buf
[7];
631 hdr
.nscount
= buf
[8] << 8 | buf
[9];
632 hdr
.arcount
= buf
[10] << 8 | buf
[11];
634 sprintf(id_text
, "%d", hdr
.id
);
635 req
= dict_find(sar_requests
, id_text
, NULL
);
636 log_module(sar_log
, LOG_DEBUG
, "sar_fd_readable(%p): hdr {id=%d, flags=0x%x, qdcount=%d, ancount=%d, nscount=%d, arcount=%d} -> req %p", (void*)fd
, hdr
.id
, hdr
.flags
, hdr
.qdcount
, hdr
.ancount
, hdr
.nscount
, hdr
.arcount
, (void*)req
);
637 if (!req
|| !req
->retries
|| !(hdr
.flags
& REQ_FLAG_QR
)) {
641 rcode
= hdr
.flags
& REQ_FLAG_RCODE_MASK
;
642 if (rcode
!= RCODE_NO_ERROR
) {
643 sar_request_fail(req
, rcode
);
644 } else if (sar_decode_answer(req
, &hdr
, (unsigned char*)buf
, res
)) {
645 ns
->resp_scrambled
++;
646 sar_request_fail(req
, RCODE_FORMAT_ERROR
);
651 sar_build_nslist(struct string_list
*nslist
)
653 dict_iterator_t it
, next
;
654 struct sar_nameserver
*ns
;
657 for (it
= dict_first(sar_nameservers
); it
; it
= iter_next(it
)) {
662 for (ii
= 0; ii
< nslist
->used
; ++ii
) {
665 name
= nslist
->list
[ii
];
666 ns
= dict_find(sar_nameservers
, name
, NULL
);
669 ns
= calloc(1, sizeof(*ns
) + strlen(name
) + 1);
670 ns
->name
= (char*)(ns
+ 1);
671 strcpy(ns
->name
, name
);
672 ns
->ss_len
= sizeof(struct sockaddr_storage
);
673 ns
->ss
= calloc(1, ns
->ss_len
);
674 sa
= (struct sockaddr
*)ns
->ss
;
675 if (!sar_pton(sa
, ns
->ss_len
, NULL
, name
)) {
679 sar_set_port(sa
, ns
->ss_len
, 53);
680 ns
->ss_len
= sar_helpers
[sa
->sa_family
]->socklen
;
681 dict_insert(sar_nameservers
, ns
->name
, ns
);
686 for (it
= dict_first(sar_nameservers
); it
; it
= next
) {
687 next
= iter_next(it
);
690 dict_remove(sar_nameservers
, ns
->name
);
695 sar_free_nameserver(void *obj
)
697 struct sar_nameserver
*ns
= obj
;
703 sar_addrlen(const struct sockaddr
*sa
, UNUSED_ARG(unsigned int size
))
705 return sa
->sa_family
<= MAX_FAMILY
&& sar_helpers
[sa
->sa_family
]
706 ? sar_helpers
[sa
->sa_family
]->socklen
: 0;
715 /* Build list of nameservers. */
716 sar_build_nslist(conf
.sar_nslist
);
718 sa
= (struct sockaddr
*)conf
.sar_bind_address
;
719 if (sa
->sa_family
!= 0) {
720 sar_fd_fd
= socket(sa
->sa_family
, SOCK_DGRAM
, 0);
722 log_module(sar_log
, LOG_FATAL
, "Unable to create resolver socket: %s", strerror(errno
));
726 res
= bind(sar_fd_fd
, sa
, sar_addrlen(sa
, sizeof(struct sockaddr_storage
)));
728 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
));
731 struct sar_nameserver
*ns
;
733 it
= dict_first(sar_nameservers
);
735 sar_fd_fd
= socket(((struct sockaddr
*)ns
->ss
)->sa_family
, SOCK_DGRAM
, 0);
737 log_module(sar_log
, LOG_FATAL
, "Unable to create resolver socket: %s", strerror(errno
));
742 sar_fd
= ioset_add(sar_fd_fd
);
744 log_module(sar_log
, LOG_FATAL
, "Unable to register resolver socket with event loop.");
747 sar_fd
->state
= IO_CONNECTED
;
748 sar_fd
->readable_cb
= sar_fd_readable
;
758 set_compare_charp(const void *a_
, const void *b_
)
760 char * const *a
= a_
, * const *b
= b_
;
761 return strcasecmp(*a
, *b
);
765 string_buffer_reserve(struct string_buffer
*cv
, unsigned int min_length
)
767 if (cv
->size
< min_length
) {
769 new_buffer
= realloc(cv
->list
, min_length
);
771 cv
->size
= min_length
;
772 cv
->list
= new_buffer
;
777 /** Append \a name to \a cv in compressed form. */
779 sar_append_name(struct string_buffer
*cv
, const char *name
, struct name_ofs
*ofs
, unsigned int *used
, unsigned int alloc
)
781 struct name_ofs
*pofs
;
785 pofs
= bsearch(&name
, ofs
, *used
, sizeof(ofs
[0]), set_compare_charp
);
787 string_buffer_reserve(cv
, cv
->used
+ 2);
788 cv
->list
[cv
->used
++] = RES_SF_POINTER
| (pofs
->ofs
>> 8);
789 cv
->list
[cv
->used
++] = pofs
->ofs
& 255;
792 len
= strcspn(name
, ".");
796 ofs
[*used
].name
= name
;
797 ofs
[*used
].ofs
= cv
->used
;
798 qsort(ofs
, (*used
)++, sizeof(ofs
[0]), set_compare_charp
);
800 string_buffer_reserve(cv
, cv
->used
+ len
+ 1);
801 cv
->list
[cv
->used
] = RES_SF_LABEL
| len
;
802 memcpy(cv
->list
+ cv
->used
+ 1, name
, len
);
804 if (name
[len
] == '.')
806 else if (name
[len
] == '\0')
809 string_buffer_append(cv
, '\0');
813 /** Build a DNS question packet from a variable-length argument list.
814 * In \a args, there is at least one pari consisting of const char
815 * *name and unsigned int qtype. A null name argument terminates the
819 sar_request_vbuild(struct sar_request
*req
, va_list args
)
821 struct name_ofs suffixes
[32];
822 struct string_buffer cv
;
824 unsigned int suf_used
;
826 unsigned int qdcount
;
830 cv
.list
= calloc(1, cv
.size
);
832 val
= REQ_OPCODE_QUERY
| REQ_FLAG_RD
;
833 cv
.list
[0] = req
->id
>> 8;
834 cv
.list
[1] = req
->id
& 255;
835 cv
.list
[2] = val
>> 8;
836 cv
.list
[3] = val
& 255;
837 cv
.list
[6] = cv
.list
[7] = cv
.list
[8] = cv
.list
[9] = cv
.list
[10] = 0;
839 for (qdcount
= 0; (name
= va_arg(args
, const char*)); ++qdcount
) {
840 if (sar_append_name(&cv
, name
, suffixes
, &suf_used
, ArrayLength(suffixes
))) {
841 string_buffer_clean(&cv
);
844 string_buffer_reserve(&cv
, cv
.used
+ 4);
845 val
= va_arg(args
, unsigned int);
846 cv
.list
[cv
.used
++] = val
>> 8;
847 cv
.list
[cv
.used
++] = val
& 255;
848 cv
.list
[cv
.used
++] = REQ_CLASS_IN
>> 8;
849 cv
.list
[cv
.used
++] = REQ_CLASS_IN
& 255;
851 cv
.list
[4] = qdcount
>> 8;
852 cv
.list
[5] = qdcount
& 255;
853 val
= conf
.sar_edns0
;
855 string_buffer_reserve(&cv
, cv
.used
+ 11);
856 cv
.list
[cv
.used
+ 0] = '\0'; /* empty name */
857 cv
.list
[cv
.used
+ 1] = REQ_TYPE_OPT
>> 8;
858 cv
.list
[cv
.used
+ 2] = REQ_TYPE_OPT
& 255;
859 cv
.list
[cv
.used
+ 3] = val
>> 8;
860 cv
.list
[cv
.used
+ 4] = val
& 255;
861 cv
.list
[cv
.used
+ 5] = 0; /* extended-rcode */
862 cv
.list
[cv
.used
+ 6] = 0; /* version */
863 cv
.list
[cv
.used
+ 7] = 0; /* reserved */
864 cv
.list
[cv
.used
+ 8] = 0; /* reserved */
865 cv
.list
[cv
.used
+ 9] = 0; /* msb rdlen */
866 cv
.list
[cv
.used
+ 10] = 0; /* lsb rdlen */
868 cv
.list
[11] = 1; /* update arcount */
869 } else cv
.list
[11] = 0;
873 req
->body
= (unsigned char*)cv
.list
;
874 req
->body_len
= cv
.used
;
878 /** Build a DNS question packet. After \a req, there is at least one
879 * pair consisting of const char *name and unsigned int qtype. A null
880 * name argument terminates the list.
883 sar_request_build(struct sar_request
*req
, ...)
887 va_start(vargs
, req
);
888 ret
= sar_request_vbuild(req
, vargs
);
894 sar_request_send(struct sar_request
*req
)
898 /* make sure we have our local socket */
899 if (!sar_fd
&& sar_open_fd()) {
900 sar_request_fail(req
, RCODE_SOCKET_FAILURE
);
904 log_module(sar_log
, LOG_DEBUG
, "sar_request_send({id=%d})", req
->id
);
906 /* send query to each configured nameserver */
907 for (it
= dict_first(sar_nameservers
); it
; it
= iter_next(it
)) {
908 struct sar_nameserver
*ns
;
912 res
= sendto(sar_fd_fd
, req
->body
, req
->body_len
, 0, (struct sockaddr
*)ns
->ss
, ns
->ss_len
);
915 log_module(sar_log
, LOG_DEBUG
, "Sent %u bytes to %s.", res
, ns
->name
);
917 log_module(sar_log
, LOG_ERROR
, "Unable to send %u bytes to nameserver %s: %s", req
->body_len
, ns
->name
, strerror(errno
));
919 assert(0 && "resolver sendto() unexpectedly returned zero");
922 /* Check that query timeout is soon enough. */
923 req
->expiry
= now
+ (conf
.sar_timeout
<< ++req
->retries
);
924 sar_check_timeout(req
->expiry
);
928 sar_request_alloc(unsigned int data_len
, sar_request_ok_cb ok_cb
, sar_request_fail_cb fail_cb
)
930 struct sar_request
*req
;
932 req
= calloc(1, sizeof(*req
) + data_len
);
934 req
->cb_fail
= fail_cb
;
936 req
->id
= rand() & 0xffff;
937 sprintf(req
->id_text
, "%d", req
->id
);
938 } while (dict_find(sar_requests
, req
->id_text
, NULL
));
939 dict_insert(sar_requests
, req
->id_text
, req
);
940 log_module(sar_log
, LOG_DEBUG
, "sar_request_alloc(%d) -> {id=%d}", data_len
, req
->id
);
945 sar_request_simple(unsigned int data_len
, sar_request_ok_cb ok_cb
, sar_request_fail_cb fail_cb
, ...)
947 struct sar_request
*req
;
949 req
= sar_request_alloc(data_len
, ok_cb
, fail_cb
);
953 va_start(args
, fail_cb
);
954 sar_request_vbuild(req
, args
);
956 sar_request_send(req
);
967 struct service_byname
{
968 const char *name
; /* service name */
970 /* note: if valid != 0, port == 0, check canonical entry */
971 struct service_byname
*canon
; /* if NULL, this is canonical */
973 unsigned int valid
: 1;
974 unsigned int srv
: 1;
975 } protos
[SERVICE_NUM_PROTOS
];
978 struct service_byport
{
981 struct service_byname
*byname
[SERVICE_NUM_PROTOS
];
984 static dict_t services_byname
; /* contains struct service_byname */
985 static dict_t services_byport
; /* contains struct service_byport */
987 static struct service_byname
*
988 sar_service_byname(const char *name
, int autocreate
)
990 struct service_byname
*byname
;
992 byname
= dict_find(services_byname
, name
, NULL
);
993 if (!byname
&& autocreate
) {
994 byname
= calloc(1, sizeof(*byname
) + strlen(name
) + 1);
995 byname
->name
= strcpy((char*)(byname
+ 1), name
);
996 dict_insert(services_byname
, byname
->name
, byname
);
1001 static struct service_byport
*
1002 sar_service_byport(unsigned int port
, int autocreate
)
1004 struct service_byport
*byport
;
1007 sprintf(port_text
, "%d", port
);
1008 byport
= dict_find(services_byport
, port_text
, NULL
);
1009 if (!byport
&& autocreate
) {
1010 byport
= calloc(1, sizeof(*byport
));
1011 byport
->port
= port
;
1012 sprintf(byport
->port_text
, "%d", port
);
1013 dict_insert(services_byport
, byport
->port_text
, byport
);
1019 sar_services_load_file(const char *etc_services
)
1021 static const char *whitespace
= " \t\r\n";
1022 struct service_byname
*canon
;
1023 struct service_byport
*byport
;
1024 char *name
, *port
, *alias
, *ptr
;
1027 enum service_proto proto
;
1028 char linebuf
[LINE_MAX
];
1030 file
= fopen(etc_services
, "r");
1033 while (fgets(linebuf
, sizeof(linebuf
), file
)) {
1034 ptr
= strchr(linebuf
, '#');
1037 /* Tokenize canonical service name and port number. */
1038 name
= strtok_r(linebuf
, whitespace
, &ptr
);
1041 port
= strtok_r(NULL
, whitespace
, &ptr
);
1044 pnum
= strtoul(port
, &port
, 10);
1045 if (pnum
== 0 || *port
++ != '/')
1047 if (!strcmp(port
, "udp"))
1048 proto
= SERVICE_UDP
;
1049 else if (!strcmp(port
, "tcp"))
1050 proto
= SERVICE_TCP
;
1053 /* Set up canonical name-indexed service entry. */
1054 canon
= sar_service_byname(name
, 1);
1055 if (canon
->protos
[proto
].valid
) {
1056 /* log_module(sar_log, LOG_ERROR, "Service %s/%s listed twice.", name, port); who cares? */
1059 canon
->protos
[proto
].canon
= NULL
;
1060 canon
->protos
[proto
].port
= pnum
;
1061 canon
->protos
[proto
].valid
= 1;
1063 /* Set up port-indexed service entry. */
1064 byport
= sar_service_byport(pnum
, 1);
1065 if (!byport
->byname
[proto
])
1066 byport
->byname
[proto
] = canon
;
1068 /* Add alias entries. */
1069 while ((alias
= strtok_r(NULL
, whitespace
, &ptr
))) {
1070 struct service_byname
*byname
;
1072 byname
= sar_service_byname(alias
, 1);
1073 if (byname
->protos
[proto
].valid
) {
1074 /* We do not log this since there are a lot of
1075 * duplicate aliases, some only differing in case. */
1078 byname
->protos
[proto
].canon
= canon
;
1079 byname
->protos
[proto
].port
= pnum
;
1080 byname
->protos
[proto
].valid
= 1;
1087 sar_services_init(const char *etc_services
)
1089 /* These are a portion of the services listed at
1090 * http://www.dns-sd.org/ServiceTypes.html.
1092 static const char *tcp_srvs
[] = { "cvspserver", "distcc", "ftp", "http",
1093 "imap", "ipp", "irc", "ldap", "login", "nfs", "pop3", "postgresql",
1094 "rsync", "sftp-ssh", "soap", "ssh", "telnet", "webdav", "xmpp-client",
1095 "xmpp-server", "xul-http", NULL
};
1096 static const char *udp_srvs
[] = { "bootps", "dns-update", "domain", "nfs",
1097 "ntp", "tftp", NULL
};
1098 struct service_byname
*byname
;
1101 /* Forget old services dicts and allocate new ones. */
1102 dict_delete(services_byname
);
1103 services_byname
= dict_new();
1104 dict_set_free_data(services_byname
, free
);
1106 dict_delete(services_byport
);
1107 services_byport
= dict_new();
1108 dict_set_free_data(services_byport
, free
);
1110 /* Load the list from the services file. */
1111 sar_services_load_file(etc_services
);
1113 /* Mark well-known services as using DNS-SD SRV records. */
1114 for (ii
= 0; tcp_srvs
[ii
]; ++ii
) {
1115 byname
= sar_service_byname(tcp_srvs
[ii
], 1);
1116 byname
->protos
[SERVICE_TCP
].srv
= 1;
1119 for (ii
= 0; udp_srvs
[ii
]; ++ii
) {
1120 byname
= sar_service_byname(udp_srvs
[ii
], 1);
1121 byname
->protos
[SERVICE_UDP
].srv
= 1;
1126 sar_register_helper(struct sar_family_helper
*helper
)
1128 assert(helper
->family
<= MAX_FAMILY
);
1129 sar_helpers
[helper
->family
] = helper
;
1130 helper
->next
= sar_first_helper
;
1131 sar_first_helper
= helper
;
1134 struct sar_getaddr_state
{
1135 struct sar_family_helper
*helper
;
1136 struct addrinfo
*ai_head
;
1137 struct addrinfo
*ai_tail
;
1140 unsigned int search_pos
;
1141 unsigned int flags
, socktype
, protocol
, port
;
1142 unsigned int srv_ofs
;
1143 char full_name
[DNS_NAME_LENGTH
];
1147 sar_getaddr_append(struct sar_getaddr_state
*state
, struct addrinfo
*ai
, int copy
)
1151 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_append({full_name=%s}, ai=%p, copy=%d)", state
->full_name
, (void*)ai
, copy
);
1153 /* Set the appropriate pointer to the new element(s). */
1155 state
->ai_tail
->ai_next
= ai
;
1157 state
->ai_head
= ai
;
1159 /* Find the end of the list. */
1161 /* Make sure we copy fields for both the first and last entries. */
1164 if (!ai
->ai_addrlen
) {
1165 assert(sar_helpers
[ai
->ai_family
]);
1166 ai
->ai_addrlen
= sar_helpers
[ai
->ai_family
]->socklen
;
1168 #if defined(HAVE_SOCKADDR_SA_LEN)
1169 ai
->ai_addr
->sa_len
= ai
->ai_addrlen
;
1171 ai
->ai_addr
->sa_family
= ai
->ai_family
;
1172 ai
->ai_socktype
= state
->socktype
;
1173 ai
->ai_protocol
= state
->protocol
;
1180 for (count
= 1; ai
->ai_next
; ++count
, ai
= ai
->ai_next
)
1184 /* Set the tail pointer and return count of appended items. */
1185 state
->ai_tail
= ai
;
1189 static struct sar_request
*
1190 sar_getaddr_request(struct sar_request
*req
)
1192 struct sar_getaddr_state
*state
;
1194 char full_name
[DNS_NAME_LENGTH
];
1196 state
= (struct sar_getaddr_state
*)(req
+ 1);
1198 /* If we can and should, append the current search domain. */
1199 if (state
->search_pos
< conf
.sar_search
->used
)
1200 snprintf(full_name
, sizeof(full_name
), "%s.%s", state
->full_name
, conf
.sar_search
->list
[state
->search_pos
]);
1201 else if (state
->search_pos
== conf
.sar_search
->used
)
1202 safestrncpy(full_name
, state
->full_name
, sizeof(full_name
));
1204 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_request({id=%d}): failed", req
->id
);
1205 state
->cb(state
->cb_ctx
, NULL
, SAI_NONAME
);
1209 /* Build the appropriate request for DNS record(s). */
1210 if (state
->flags
& SAI_ALL
)
1211 len
= sar_request_build(req
, full_name
+ state
->srv_ofs
, REQ_QTYPE_ALL
, NULL
);
1212 else if (state
->srv_ofs
)
1213 len
= state
->helper
->build_addr_request(req
, full_name
+ state
->srv_ofs
, full_name
, state
->flags
);
1215 len
= state
->helper
->build_addr_request(req
, full_name
, NULL
, state
->flags
);
1217 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_request({id=%d}): full_name=%s, srv_ofs=%d", req
->id
, full_name
, state
->srv_ofs
);
1219 /* Check that the request could be built. */
1221 state
->cb(state
->cb_ctx
, NULL
, SAI_NODATA
);
1225 /* Send the request. */
1226 sar_request_send(req
);
1231 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
)
1233 struct sar_getaddr_state
*state
;
1235 unsigned int jj
, pos
, hit
;
1237 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
);
1238 state
= (struct sar_getaddr_state
*)(req
+ 1);
1240 switch (rr
[rr_idx
].type
) {
1242 if (state
->flags
& SAI_ALL
)
1243 return sar_ipv4_helper
.decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1244 #if defined(AF_INET6)
1245 else if (state
->flags
& SAI_V4MAPPED
)
1246 return sar_ipv6_helper
.decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1248 return state
->helper
->decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1251 #if defined(AF_INET6)
1252 if (state
->flags
& SAI_ALL
)
1253 return sar_ipv6_helper
.decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1254 return state
->helper
->decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1259 case REQ_TYPE_CNAME
:
1260 /* there should be the canonical name next */
1261 pos
= rr
[rr_idx
].rd_start
;
1262 cname
= sar_extract_name(raw
, raw_size
, &pos
);
1264 return 0; /* XXX: eventually log the unhandled body */
1265 /* and it should correspond to some other answer in the response */
1266 for (jj
= hit
= 0; jj
< hdr
->ancount
; ++jj
) {
1267 if (strcasecmp(cname
, rr
[jj
].name
))
1269 hit
+= sar_getaddr_decode(req
, hdr
, rr
, raw
, raw_size
, jj
);
1271 /* XXX: if (!hit) handle or log the incomplete recursion; */
1275 /* TODO: decode the SRV record */
1283 sar_getaddr_ok(struct sar_request
*req
, struct dns_header
*hdr
, struct dns_rr
*rr
, unsigned char *raw
, unsigned int raw_size
)
1285 struct sar_getaddr_state
*state
;
1288 state
= (struct sar_getaddr_state
*)(req
+ 1);
1290 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_ok({id=%d}, {id=%d}, <rr>, <data>, %u)", req
->id
, hdr
->id
, raw_size
);
1291 for (ii
= 0; ii
< hdr
->ancount
; ++ii
)
1292 sar_getaddr_decode(req
, hdr
, rr
, raw
, raw_size
, ii
);
1294 /* If we found anything, report it, else try again. */
1296 state
->cb(state
->cb_ctx
, state
->ai_head
, SAI_SUCCESS
);
1298 sar_getaddr_request(req
);
1302 sar_getaddr_fail(struct sar_request
*req
, UNUSED_ARG(unsigned int rcode
))
1304 struct sar_getaddr_state
*state
;
1306 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_fail({id=%d}, rcode=%u)", req
->id
, rcode
);
1307 state
= (struct sar_getaddr_state
*)(req
+ 1);
1308 state
->cb(state
->cb_ctx
, NULL
, SAI_FAIL
);
1311 struct sar_request
*
1312 sar_getaddr(const char *node
, const char *service
, const struct addrinfo
*hints_
, sar_addr_cb cb
, void *cb_ctx
)
1314 struct addrinfo hints
;
1315 struct sar_family_helper
*helper
;
1316 struct service_byname
*svc
;
1320 unsigned int portnum
;
1322 enum service_proto proto
;
1324 if (!node
&& !service
) {
1325 cb(cb_ctx
, NULL
, SAI_NONAME
);
1329 /* Initialize local hints structure. */
1331 memcpy(&hints
, hints_
, sizeof(hints
));
1333 memset(&hints
, 0, sizeof(hints
));
1335 /* Translate socket type to internal protocol. */
1336 switch (hints
.ai_socktype
) {
1337 case 0: hints
.ai_socktype
= SOCK_STREAM
; /* and fall through */
1338 case SOCK_STREAM
: proto
= SERVICE_TCP
; break;
1339 case SOCK_DGRAM
: proto
= SERVICE_UDP
; break;
1341 cb(cb_ctx
, NULL
, SAI_SOCKTYPE
);
1345 /* Figure out preferred socket size. */
1346 if (hints
.ai_family
== AF_UNSPEC
)
1347 hints
.ai_family
= AF_INET
;
1348 if (hints
.ai_family
> MAX_FAMILY
1349 || !(helper
= sar_helpers
[hints
.ai_family
])) {
1350 cb(cb_ctx
, NULL
, SAI_FAMILY
);
1353 hints
.ai_addrlen
= helper
->socklen
;
1355 /* If \a node is NULL, figure out the correct default from the
1356 * requested family and SAI_PASSIVE flag.
1359 node
= (hints
.ai_flags
& SAI_PASSIVE
) ? helper
->unspec_addr
: helper
->localhost_addr
;
1361 /* Try to parse (failing that, look up) \a service. */
1363 portnum
= 0, svc
= NULL
;
1364 else if ((portnum
= strtoul(service
, &end
, 10)), *end
== '\0')
1366 else if ((svc
= sar_service_byname(service
, 0)) != NULL
)
1367 portnum
= svc
->protos
[proto
].port
;
1369 cb(cb_ctx
, NULL
, SAI_SERVICE
);
1373 /* Try to parse \a node as a numeric hostname.*/
1374 ss_len
= sizeof(struct sockaddr_storage
);
1375 ss
= alloca(ss_len
);
1376 pos
= sar_pton((struct sockaddr
*)ss
, ss_len
, NULL
, node
);
1377 if (pos
&& node
[pos
] == '\0') {
1378 struct addrinfo
*ai
;
1379 char canonname
[SAR_NTOP_MAX
];
1381 /* we have a valid address; use it */
1382 sar_set_port((struct sockaddr
*)ss
, ss_len
, portnum
);
1383 hints
.ai_addrlen
= sar_addrlen((struct sockaddr
*)ss
, ss_len
);
1384 if (!hints
.ai_addrlen
) {
1385 cb(cb_ctx
, NULL
, SAI_FAMILY
);
1388 pos
= sar_ntop(canonname
, sizeof(canonname
), (struct sockaddr
*)ss
, hints
.ai_addrlen
);
1390 /* allocate and fill in the addrinfo response */
1391 ai
= calloc(1, sizeof(*ai
) + hints
.ai_addrlen
+ pos
+ 1);
1392 ai
->ai_family
= ((struct sockaddr
*)ss
)->sa_family
;
1393 ai
->ai_socktype
= hints
.ai_socktype
;
1394 ai
->ai_protocol
= hints
.ai_protocol
;
1395 ai
->ai_addrlen
= hints
.ai_addrlen
;
1396 ai
->ai_addr
= memcpy(ai
+ 1, ss
, ai
->ai_addrlen
);
1397 ai
->ai_canonname
= strcpy((char*)ai
->ai_addr
+ ai
->ai_addrlen
, canonname
);
1398 cb(cb_ctx
, ai
, SAI_SUCCESS
);
1400 } else if (hints
.ai_flags
& SAI_NUMERICHOST
) {
1401 cb(cb_ctx
, NULL
, SAI_NONAME
);
1404 struct sar_request
*req
;
1405 struct sar_getaddr_state
*state
;
1406 unsigned int len
, ii
;
1408 req
= sar_request_alloc(sizeof(*state
), sar_getaddr_ok
, sar_getaddr_fail
);
1410 state
= (struct sar_getaddr_state
*)(req
+ 1);
1411 state
->helper
= helper
;
1412 state
->ai_head
= state
->ai_tail
= NULL
;
1414 state
->cb_ctx
= cb_ctx
;
1415 state
->flags
= hints
.ai_flags
;
1416 state
->socktype
= hints
.ai_socktype
;
1417 state
->protocol
= hints
.ai_protocol
;
1418 state
->port
= portnum
;
1420 if ((state
->flags
& SAI_NOSRV
) || !svc
)
1422 else if (svc
->protos
[proto
].srv
)
1423 state
->srv_ofs
= snprintf(state
->full_name
, sizeof(state
->full_name
), "_%s._%s.", svc
->name
, (proto
== SERVICE_UDP
? "udp" : "tcp"));
1424 else if (state
->flags
& SAI_FORCESRV
)
1425 state
->srv_ofs
= snprintf(state
->full_name
, sizeof(state
->full_name
), "_%s._%s.", service
, (proto
== SERVICE_UDP
? "udp" : "tcp"));
1429 if (state
->srv_ofs
< sizeof(state
->full_name
))
1430 safestrncpy(state
->full_name
+ state
->srv_ofs
, node
, sizeof(state
->full_name
) - state
->srv_ofs
);
1432 for (ii
= len
= 0; node
[ii
]; ++ii
)
1433 if (node
[ii
] == '.')
1435 if (len
>= conf
.sar_ndots
)
1436 state
->search_pos
= conf
.sar_search
->used
;
1438 state
->search_pos
= 0;
1440 /* XXX: fill in *state with any other fields needed to parse responses. */
1442 if (!sar_getaddr_request(req
)) {
1450 struct sar_getname_state
{
1455 unsigned int family
;
1456 enum service_proto proto
;
1457 unsigned short port
;
1458 unsigned int doing_arpa
: 1; /* checking .ip6.arpa vs .ip6.int */
1459 unsigned char original
[16]; /* original address data */
1460 /* name must be long enough to hold "0.0.<etc>.ip6.arpa" */
1465 sar_getname_fail(struct sar_request
*req
, UNUSED_ARG(unsigned int rcode
))
1467 struct sar_getname_state
*state
;
1470 state
= (struct sar_getname_state
*)(req
+ 1);
1471 if (state
->doing_arpa
) {
1472 len
= strlen(state
->name
);
1474 strcpy(state
->name
+ len
- 4, "int");
1475 len
= sar_request_build(req
, state
->name
, REQ_TYPE_PTR
, NULL
);
1477 sar_request_send(req
);
1481 state
->cb(state
->cb_ctx
, NULL
, NULL
, SAI_FAIL
);
1482 free(state
->hostname
);
1485 static const char *sar_getname_port(unsigned int port
, unsigned int flags
, char *tmpbuf
, unsigned int tmpbuf_len
)
1487 struct service_byport
*service
;
1488 enum service_proto proto
;
1491 sprintf(port_text
, "%d", port
);
1492 proto
= (flags
& SNI_DGRAM
) ? SERVICE_UDP
: SERVICE_TCP
;
1493 if (!(flags
& SNI_NUMERICSERV
)
1494 && (service
= dict_find(services_byport
, port_text
, NULL
))
1495 && service
->byname
[proto
])
1496 return service
->byname
[proto
]->name
;
1497 snprintf(tmpbuf
, tmpbuf_len
, "%d", port
);
1502 sar_getname_confirm(struct sar_request
*req
, struct dns_header
*hdr
, struct dns_rr
*rr
, unsigned char *raw
, unsigned int raw_size
)
1504 struct sar_getname_state
*state
;
1505 const unsigned char *data
;
1506 const char *portname
;
1508 unsigned int ii
, nbr
;
1510 state
= (struct sar_getname_state
*)(req
+ 1);
1511 for (ii
= 0; ii
< hdr
->ancount
; ++ii
) {
1512 /* Is somebody confused or trying to play games? */
1513 if (rr
[ii
].class != REQ_CLASS_IN
1514 || strcasecmp(state
->hostname
, rr
[ii
].name
))
1516 switch (rr
[ii
].type
) {
1517 case REQ_TYPE_A
: nbr
= 4; break;
1518 case REQ_TYPE_AAAA
: nbr
= 16; break;
1521 data
= sar_extract_rdata(rr
, nbr
, raw
, raw_size
);
1522 if (data
&& !memcmp(data
, state
->original
, nbr
)) {
1523 portname
= sar_getname_port(state
->port
, state
->flags
, servbuf
, sizeof(servbuf
));
1524 state
->cb(state
->cb_ctx
, state
->hostname
, portname
, SAI_SUCCESS
);
1525 free(state
->hostname
);
1529 state
->cb(state
->cb_ctx
, NULL
, NULL
, SAI_MISMATCH
);
1530 free(state
->hostname
);
1534 sar_getname_ok(struct sar_request
*req
, struct dns_header
*hdr
, struct dns_rr
*rr
, unsigned char *raw
, unsigned int raw_size
)
1536 struct sar_getname_state
*state
;
1537 const char *portname
;
1538 unsigned int ii
, pos
;
1541 state
= (struct sar_getname_state
*)(req
+ 1);
1542 for (ii
= 0; ii
< hdr
->ancount
; ++ii
) {
1543 if (rr
[ii
].type
!= REQ_TYPE_PTR
1544 || rr
[ii
].class != REQ_CLASS_IN
1545 || strcasecmp(rr
[ii
].name
, state
->name
))
1547 pos
= rr
[ii
].rd_start
;
1548 state
->hostname
= sar_extract_name(raw
, raw_size
, &pos
);
1552 if (!state
->hostname
) {
1553 state
->cb(state
->cb_ctx
, NULL
, NULL
, SAI_NONAME
);
1557 if (state
->flags
& SNI_PARANOID
) {
1558 req
->cb_ok
= sar_getname_confirm
;
1559 pos
= sar_helpers
[state
->family
]->build_addr_request(req
, state
->hostname
, NULL
, 0);
1561 sar_request_send(req
);
1563 free(state
->hostname
);
1564 state
->cb(state
->cb_ctx
, NULL
, NULL
, SAI_FAIL
);
1569 portname
= sar_getname_port(state
->port
, state
->flags
, servbuf
, sizeof(servbuf
));
1570 state
->cb(state
->cb_ctx
, state
->hostname
, portname
, SAI_SUCCESS
);
1571 free(state
->hostname
);
1574 struct sar_request
*
1575 sar_getname(const struct sockaddr
*sa
, unsigned int salen
, int flags
, sar_name_cb cb
, void *cb_ctx
)
1577 struct sar_family_helper
*helper
;
1578 struct sar_request
*req
;
1579 struct sar_getname_state
*state
;
1583 if (sa
->sa_family
> MAX_FAMILY
1584 || !(helper
= sar_helpers
[sa
->sa_family
])) {
1585 cb(cb_ctx
, NULL
, NULL
, SAI_FAMILY
);
1589 port
= helper
->get_port(sa
, salen
);
1591 if (flags
& SNI_NUMERICHOST
) {
1592 const char *servname
;
1593 char host
[SAR_NTOP_MAX
], servbuf
[16];
1595 /* If appropriate, try to look up service name. */
1596 servname
= sar_getname_port(port
, flags
, servbuf
, sizeof(servbuf
));
1597 len
= sar_ntop(host
, sizeof(host
), sa
, salen
);
1599 cb(cb_ctx
, host
, servname
, SAI_SUCCESS
);
1603 req
= sar_request_alloc(sizeof(*state
), sar_getname_ok
, sar_getname_fail
);
1605 state
= (struct sar_getname_state
*)(req
+ 1);
1607 state
->cb_ctx
= cb_ctx
;
1608 state
->flags
= flags
;
1609 state
->family
= sa
->sa_family
;
1612 helper
->build_ptr_name(state
, sa
, salen
);
1613 assert(strlen(state
->name
) < sizeof(state
->name
));
1614 len
= sar_request_build(req
, state
->name
, REQ_TYPE_PTR
, NULL
);
1616 cb(cb_ctx
, NULL
, NULL
, SAI_NODATA
);
1621 sar_request_send(req
);
1626 ipv4_ntop(char *output
, unsigned int out_size
, const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1628 struct sockaddr_in
*sin
;
1629 unsigned int ip4
, pos
;
1631 sin
= (struct sockaddr_in
*)sa
;
1632 ip4
= ntohl(sin
->sin_addr
.s_addr
);
1633 pos
= snprintf(output
, out_size
, "%u.%u.%u.%u", (ip4
>> 24), (ip4
>> 16) & 255, (ip4
>> 8) & 255, ip4
& 255);
1634 return (pos
< out_size
) ? pos
: 0;
1638 sar_pton_ip4(const char *input
, unsigned int *bits
, uint32_t *output
)
1640 unsigned int dots
= 0, pos
= 0, part
= 0, ip
= 0;
1642 /* Intentionally no support for bizarre IPv4 formats (plain
1643 * integers, octal or hex components) -- only vanilla dotted
1644 * decimal quads, optionally with trailing /nn.
1646 if (input
[0] == '.')
1649 if (isdigit(input
[pos
])) {
1650 part
= part
* 10 + input
[pos
++] - '0';
1653 if ((dots
== 3) && !isdigit(input
[pos
])) {
1654 *output
= htonl(ip
| part
);
1657 } else if (input
[pos
] == '.') {
1658 if (input
[++pos
] == '.')
1660 ip
|= part
<< (24 - 8 * dots
++);
1662 } else if (bits
&& input
[pos
] == '/' && isdigit(input
[pos
+ 1])) {
1666 len
= strtoul(input
+ pos
+ 1, &term
, 10);
1667 if (term
<= input
+ pos
+ 1)
1672 return term
- input
;
1678 ipv4_pton(struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
), unsigned int *bits
, const char *input
)
1682 pos
= sar_pton_ip4(input
, bits
, &((struct sockaddr_in
*)sa
)->sin_addr
.s_addr
);
1685 sa
->sa_family
= AF_INET
;
1686 #if defined(HAVE_SOCKADDR_SA_LEN)
1687 sa
->sa_len
= sizeof(struct sockaddr_in
);
1693 ipv4_get_port(const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1695 return ntohs(((const struct sockaddr_in
*)sa
)->sin_port
);
1699 ipv4_set_port(struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
), unsigned short port
)
1701 ((struct sockaddr_in
*)sa
)->sin_port
= htons(port
);
1706 ipv4_addr_request(struct sar_request
*req
, const char *node
, const char *srv_node
, UNUSED_ARG(unsigned int flags
))
1710 len
= sar_request_build(req
, node
, REQ_TYPE_A
, srv_node
, REQ_TYPE_SRV
, NULL
);
1712 len
= sar_request_build(req
, node
, REQ_TYPE_A
, NULL
);
1717 ipv4_ptr_name(struct sar_getname_state
*state
, const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1719 const uint8_t *bytes
;
1721 bytes
= (uint8_t*)&((struct sockaddr_in
*)sa
)->sin_addr
.s_addr
;
1722 memcpy(state
->original
, bytes
, 4);
1723 snprintf(state
->name
, sizeof(state
->name
),
1724 "%u.%u.%u.%u.in-addr.arpa",
1725 bytes
[3], bytes
[2], bytes
[1], bytes
[0]);
1729 ipv4_decode(struct sar_getaddr_state
*state
, struct dns_rr
*rr
, unsigned char *raw
, UNUSED_ARG(unsigned int raw_size
))
1731 struct sockaddr_in
*sa
;
1732 struct addrinfo
*ai
;
1734 if (rr
->rdlength
!= 4)
1737 if (state
->flags
& SAI_CANONNAME
) {
1738 ai
= calloc(1, sizeof(*ai
) + sizeof(*sa
) + strlen(rr
->name
) + 1);
1739 sa
= (struct sockaddr_in
*)(ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1));
1740 ai
->ai_canonname
= strcpy((char*)(sa
+ 1), rr
->name
);
1742 ai
= calloc(1, sizeof(*ai
) + sizeof(*sa
));
1743 sa
= (struct sockaddr_in
*)(ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1));
1744 ai
->ai_canonname
= NULL
;
1747 ai
->ai_family
= AF_INET
;
1748 sa
->sin_port
= htons(state
->port
);
1749 memcpy(&sa
->sin_addr
.s_addr
, raw
+ rr
->rd_start
, 4);
1750 return sar_getaddr_append(state
, ai
, 1);
1753 static struct sar_family_helper sar_ipv4_helper
= {
1756 sizeof(struct sockaddr_in
),
1768 #if defined(AF_INET6)
1771 ipv6_ntop(char *output
, unsigned int out_size
, const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1773 struct sockaddr_in6
*sin6
;
1774 unsigned int pos
, part
, max_start
, max_zeros
, curr_zeros
, ii
;
1775 unsigned short addr16
;
1777 sin6
= (struct sockaddr_in6
*)sa
;
1778 /* Find longest run of zeros. */
1779 for (max_start
= max_zeros
= curr_zeros
= ii
= 0; ii
< 8; ++ii
) {
1780 addr16
= (sin6
->sin6_addr
.s6_addr
[ii
* 2] << 8) | sin6
->sin6_addr
.s6_addr
[ii
* 2 + 1];
1783 else if (curr_zeros
> max_zeros
) {
1784 max_start
= ii
- curr_zeros
;
1785 max_zeros
= curr_zeros
;
1789 if (curr_zeros
> max_zeros
) {
1790 max_start
= ii
- curr_zeros
;
1791 max_zeros
= curr_zeros
;
1794 /* Print out address. */
1795 #define APPEND(CH) do { output[pos++] = (CH); if (pos >= out_size) return 0; } while (0)
1796 for (pos
= 0, ii
= 0; ii
< 8; ++ii
) {
1797 if ((max_zeros
> 0) && (ii
== max_start
)) {
1801 ii
+= max_zeros
- 1;
1804 part
= (sin6
->sin6_addr
.s6_addr
[ii
* 2] << 8) | sin6
->sin6_addr
.s6_addr
[ii
* 2 + 1];
1806 APPEND(hexdigits
[part
>> 12]);
1808 APPEND(hexdigits
[(part
>> 8) & 15]);
1810 APPEND(hexdigits
[(part
>> 4) & 15]);
1811 APPEND(hexdigits
[part
& 15]);
1821 static const unsigned char xdigit_value
[256] = {
1822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1823 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1824 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1825 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
1826 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1827 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1828 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1832 ipv6_pton(struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
), unsigned int *bits
, const char *input
)
1834 const char *part_start
= NULL
;
1835 struct sockaddr_in6
*sin6
;
1838 unsigned int part
= 0, pos
= 0, ii
= 0, cpos
= 8;
1840 if (!(colon
= strchr(input
, ':')))
1842 dot
= strchr(input
, '.');
1843 if (dot
&& dot
< colon
)
1845 sin6
= (struct sockaddr_in6
*)sa
;
1846 /* Parse IPv6, possibly like ::127.0.0.1.
1847 * This is pretty straightforward; the only trick is borrowed
1848 * from Paul Vixie (BIND): when it sees a "::" continue as if
1849 * it were a single ":", but note where it happened, and fill
1850 * with zeros afterwards.
1852 if (input
[pos
] == ':') {
1853 if ((input
[pos
+1] != ':') || (input
[pos
+2] == ':'))
1857 part_start
= input
+ pos
;
1860 if (isxdigit(input
[pos
])) {
1861 part
= (part
<< 4) | xdigit_value
[(unsigned char)input
[pos
]];
1865 } else if (input
[pos
] == ':') {
1866 part_start
= input
+ ++pos
;
1867 if (input
[pos
] == '.')
1869 sin6
->sin6_addr
.s6_addr
[ii
* 2] = part
>> 8;
1870 sin6
->sin6_addr
.s6_addr
[ii
* 2 + 1] = part
& 255;
1873 if (input
[pos
] == ':') {
1879 } else if (input
[pos
] == '.') {
1882 len
= sar_pton_ip4(part_start
, bits
, &ip4
);
1883 if (!len
|| (ii
> 6))
1885 memcpy(sin6
->sin6_addr
.s6_addr
+ ii
* 2, &ip4
, sizeof(ip4
));
1889 pos
= part_start
+ len
- input
;
1891 } else if (bits
&& input
[pos
] == '/' && isdigit(input
[pos
+ 1])) {
1895 len
= strtoul(input
+ pos
+ 1, &term
, 10);
1896 if (term
<= input
+ pos
+ 1)
1904 } else if (cpos
<= 8) {
1905 sin6
->sin6_addr
.s6_addr
[ii
* 2] = part
>> 8;
1906 sin6
->sin6_addr
.s6_addr
[ii
* 2 + 1] = part
& 255;
1911 /* Shift stuff after "::" up and fill middle with zeros. */
1916 for (jj
= 0; jj
< ii
- cpos
; jj
++)
1917 sin6
->sin6_addr
.s6_addr
[15 - jj
] = sin6
->sin6_addr
.s6_addr
[ii
- jj
- 1];
1918 for (jj
= 0; jj
< 16 - ii
; jj
++)
1919 sin6
->sin6_addr
.s6_addr
[cpos
+ jj
] = 0;
1921 sa
->sa_family
= AF_INET6
;
1922 #if defined(HAVE_SOCKADDR_SA_LEN)
1923 sa
->sa_len
= sizeof(struct sockaddr_in6
);
1929 ipv6_get_port(const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1931 return ntohs(((const struct sockaddr_in6
*)sa
)->sin6_port
);
1935 ipv6_set_port(struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
), unsigned short port
)
1937 ((struct sockaddr_in6
*)sa
)->sin6_port
= htons(port
);
1942 ipv6_addr_request(struct sar_request
*req
, const char *node
, const char *srv_node
, unsigned int flags
)
1945 if (flags
& SAI_V4MAPPED
) {
1947 len
= sar_request_build(req
, node
, REQ_TYPE_AAAA
, node
, REQ_TYPE_A
, srv_node
, REQ_TYPE_SRV
, NULL
);
1949 len
= sar_request_build(req
, node
, REQ_TYPE_AAAA
, node
, REQ_TYPE_A
, NULL
);
1952 len
= sar_request_build(req
, node
, REQ_TYPE_AAAA
, srv_node
, REQ_TYPE_SRV
, NULL
);
1954 len
= sar_request_build(req
, node
, REQ_TYPE_AAAA
, NULL
);
1960 ipv6_ptr_name(struct sar_getname_state
*state
, const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1962 const uint8_t *bytes
;
1963 unsigned int ii
, jj
;
1965 bytes
= ((struct sockaddr_in6
*)sa
)->sin6_addr
.s6_addr
;
1966 memcpy(state
->original
, bytes
, 16);
1967 for (jj
= 0, ii
= 16; ii
> 0; ) {
1968 state
->name
[jj
++] = hexdigits
[bytes
[--ii
] & 15];
1969 state
->name
[jj
++] = hexdigits
[bytes
[ii
] >> 4];
1970 state
->name
[jj
++] = '.';
1972 strcpy(state
->name
+ jj
, ".ip6.arpa");
1973 state
->doing_arpa
= 1;
1977 ipv6_decode(struct sar_getaddr_state
*state
, struct dns_rr
*rr
, unsigned char *raw
, UNUSED_ARG(unsigned int raw_size
))
1979 struct sockaddr_in6
*sa
;
1980 struct addrinfo
*ai
;
1982 if (state
->flags
& SAI_CANONNAME
) {
1983 ai
= calloc(1, sizeof(*ai
) + sizeof(*sa
) + strlen(rr
->name
) + 1);
1984 sa
= (struct sockaddr_in6
*)(ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1));
1985 ai
->ai_canonname
= strcpy((char*)(sa
+ 1), rr
->name
);
1987 ai
= calloc(1, sizeof(*ai
) + sizeof(*sa
));
1988 sa
= (struct sockaddr_in6
*)(ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1));
1989 ai
->ai_canonname
= NULL
;
1992 if (rr
->rdlength
== 4) {
1993 sa
->sin6_addr
.s6_addr
[10] = sa
->sin6_addr
.s6_addr
[11] = 0xff;
1994 memcpy(sa
->sin6_addr
.s6_addr
+ 12, raw
+ rr
->rd_start
, 4);
1995 } else if (rr
->rdlength
== 16) {
1996 memcpy(sa
->sin6_addr
.s6_addr
, raw
+ rr
->rd_start
, 16);
2002 ai
->ai_family
= AF_INET6
;
2003 sa
->sin6_port
= htons(state
->port
);
2004 return sar_getaddr_append(state
, ai
, 1);
2007 static struct sar_family_helper sar_ipv6_helper
= {
2010 sizeof(struct sockaddr_in6
),
2022 #endif /* defined(AF_INET6) */
2025 sar_cleanup(UNUSED_ARG(void *extra
))
2027 ioset_close(sar_fd
, 1);
2028 dict_delete(services_byname
);
2029 dict_delete(services_byport
);
2030 dict_delete(sar_nameservers
);
2031 dict_delete(sar_requests
);
2032 free_string_list(conf
.sar_search
);
2033 free_string_list(conf
.sar_nslist
);
2037 sar_conf_reload(void)
2040 const char *resolv_conf
= "/etc/resolv.conf";
2041 const char *services
= "/etc/services";
2044 node
= conf_get_data("modules/sar", RECDB_OBJECT
);
2046 str
= database_get_data(node
, "resolv_conf", RECDB_QSTRING
);
2047 if (str
) resolv_conf
= str
;
2048 str
= database_get_data(node
, "services", RECDB_QSTRING
);
2049 if (str
) services
= str
;
2051 sar_dns_init(resolv_conf
);
2052 sar_services_init(services
);
2058 conf
.sar_bind_address
= calloc(1, sizeof(struct sockaddr_storage
));
2059 reg_exit_func(sar_cleanup
, NULL
);
2060 sar_log
= log_register_type("sar", NULL
);
2062 sar_requests
= dict_new();
2063 dict_set_free_data(sar_requests
, sar_request_cleanup
);
2065 sar_nameservers
= dict_new();
2066 dict_set_free_data(sar_nameservers
, sar_free_nameserver
);
2068 sar_register_helper(&sar_ipv4_helper
);
2069 #if defined(AF_INET6)
2070 sar_register_helper(&sar_ipv6_helper
);
2073 conf_register_reload(sar_conf_reload
);