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 struct sockaddr_storage 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
;
205 struct sockaddr_storage ss
;
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(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
);
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 sockaddr_storage ss
;
609 struct dns_header hdr
;
610 struct sar_nameserver
*ns
;
611 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
);
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
)))
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];
633 sprintf(id_text
, "%d", hdr
.id
);
634 req
= dict_find(sar_requests
, id_text
, NULL
);
635 log_module(sar_log
, LOG_DEBUG
, "sar_fd_readable(%p): hdr {id=%d, flags=0x%x, qdcount=%d, ancount=%d, nscount=%d, arcount=%d} -> req %p", (void*)fd
, hdr
.id
, hdr
.flags
, hdr
.qdcount
, hdr
.ancount
, hdr
.nscount
, hdr
.arcount
, (void*)req
);
636 if (!req
|| !req
->retries
|| !(hdr
.flags
& REQ_FLAG_QR
)) {
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
);
650 sar_build_nslist(struct string_list
*nslist
)
652 dict_iterator_t it
, next
;
653 struct sar_nameserver
*ns
;
656 for (it
= dict_first(sar_nameservers
); it
; it
= iter_next(it
)) {
661 for (ii
= 0; ii
< nslist
->used
; ++ii
) {
664 name
= nslist
->list
[ii
];
665 ns
= dict_find(sar_nameservers
, name
, NULL
);
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
)) {
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
);
682 for (it
= dict_first(sar_nameservers
); it
; it
= next
) {
683 next
= iter_next(it
);
686 dict_remove(sar_nameservers
, ns
->name
);
695 /* Build list of nameservers. */
696 sar_build_nslist(conf
.sar_nslist
);
698 if (conf
.sar_bind_address
.ss_family
!= 0) {
701 ai
= (struct addrinfo
*)&conf
.sar_bind_address
;
702 sar_fd_fd
= socket(ai
->ai_family
, SOCK_DGRAM
, 0);
704 log_module(sar_log
, LOG_FATAL
, "Unable to create resolver socket: %s", strerror(errno
));
708 res
= bind(sar_fd_fd
, ai
->ai_addr
, ai
->ai_addrlen
);
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
));
713 struct sar_nameserver
*ns
;
715 it
= dict_first(sar_nameservers
);
717 sar_fd_fd
= socket(ns
->ss
.ss_family
, SOCK_DGRAM
, 0);
719 log_module(sar_log
, LOG_FATAL
, "Unable to create resolver socket: %s", strerror(errno
));
724 sar_fd
= ioset_add(sar_fd_fd
);
726 log_module(sar_log
, LOG_FATAL
, "Unable to register resolver socket with event loop.");
729 sar_fd
->state
= IO_CONNECTED
;
730 sar_fd
->readable_cb
= sar_fd_readable
;
740 set_compare_charp(const void *a_
, const void *b_
)
742 char * const *a
= a_
, * const *b
= b_
;
743 return strcasecmp(*a
, *b
);
747 string_buffer_reserve(struct string_buffer
*cv
, unsigned int min_length
)
749 if (cv
->size
< min_length
) {
751 new_buffer
= realloc(cv
->list
, min_length
);
753 cv
->size
= min_length
;
754 cv
->list
= new_buffer
;
759 /** Append \a name to \a cv in compressed form. */
761 sar_append_name(struct string_buffer
*cv
, const char *name
, struct name_ofs
*ofs
, unsigned int *used
, unsigned int alloc
)
763 struct name_ofs
*pofs
;
767 pofs
= bsearch(&name
, ofs
, *used
, sizeof(ofs
[0]), set_compare_charp
);
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;
774 len
= strcspn(name
, ".");
778 ofs
[*used
].name
= name
;
779 ofs
[*used
].ofs
= cv
->used
;
780 qsort(ofs
, (*used
)++, sizeof(ofs
[0]), set_compare_charp
);
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
);
786 if (name
[len
] == '.')
788 else if (name
[len
] == '\0')
791 string_buffer_append(cv
, '\0');
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
801 sar_request_vbuild(struct sar_request
*req
, va_list args
)
803 struct name_ofs suffixes
[32];
804 struct string_buffer cv
;
806 unsigned int suf_used
;
808 unsigned int qdcount
;
812 cv
.list
= calloc(1, cv
.size
);
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;
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
);
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;
833 cv
.list
[4] = qdcount
>> 8;
834 cv
.list
[5] = qdcount
& 255;
835 val
= conf
.sar_edns0
;
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 */
850 cv
.list
[11] = 1; /* update arcount */
851 } else cv
.list
[11] = 0;
855 req
->body
= (unsigned char*)cv
.list
;
856 req
->body_len
= cv
.used
;
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.
865 sar_request_build(struct sar_request
*req
, ...)
869 va_start(vargs
, req
);
870 ret
= sar_request_vbuild(req
, vargs
);
876 sar_request_send(struct sar_request
*req
)
880 /* make sure we have our local socket */
881 if (!sar_fd
&& sar_open_fd()) {
882 sar_request_fail(req
, RCODE_SOCKET_FAILURE
);
886 log_module(sar_log
, LOG_DEBUG
, "sar_request_send({id=%d})", req
->id
);
888 /* send query to each configured nameserver */
889 for (it
= dict_first(sar_nameservers
); it
; it
= iter_next(it
)) {
890 struct sar_nameserver
*ns
;
894 res
= sendto(sar_fd_fd
, req
->body
, req
->body_len
, 0, (struct sockaddr
*)&ns
->ss
, ns
->ss_len
);
897 log_module(sar_log
, LOG_DEBUG
, "Sent %u bytes to %s.", res
, ns
->name
);
899 log_module(sar_log
, LOG_ERROR
, "Unable to send %u bytes to nameserver %s: %s", req
->body_len
, ns
->name
, strerror(errno
));
901 assert(0 && "resolver sendto() unexpectedly returned zero");
904 /* Check that query timeout is soon enough. */
905 req
->expiry
= now
+ (conf
.sar_timeout
<< ++req
->retries
);
906 sar_check_timeout(req
->expiry
);
910 sar_request_alloc(unsigned int data_len
, sar_request_ok_cb ok_cb
, sar_request_fail_cb fail_cb
)
912 struct sar_request
*req
;
914 req
= calloc(1, sizeof(*req
) + data_len
);
916 req
->cb_fail
= fail_cb
;
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
);
927 sar_request_simple(unsigned int data_len
, sar_request_ok_cb ok_cb
, sar_request_fail_cb fail_cb
, ...)
929 struct sar_request
*req
;
931 req
= sar_request_alloc(data_len
, ok_cb
, fail_cb
);
935 va_start(args
, fail_cb
);
936 sar_request_vbuild(req
, args
);
938 sar_request_send(req
);
949 struct service_byname
{
950 const char *name
; /* service name */
952 /* note: if valid != 0, port == 0, check canonical entry */
953 struct service_byname
*canon
; /* if NULL, this is canonical */
955 unsigned int valid
: 1;
956 unsigned int srv
: 1;
957 } protos
[SERVICE_NUM_PROTOS
];
960 struct service_byport
{
963 struct service_byname
*byname
[SERVICE_NUM_PROTOS
];
966 static dict_t services_byname
; /* contains struct service_byname */
967 static dict_t services_byport
; /* contains struct service_byport */
969 static struct service_byname
*
970 sar_service_byname(const char *name
, int autocreate
)
972 struct service_byname
*byname
;
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
);
983 static struct service_byport
*
984 sar_service_byport(unsigned int port
, int autocreate
)
986 struct service_byport
*byport
;
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
));
994 sprintf(byport
->port_text
, "%d", port
);
995 dict_insert(services_byport
, byport
->port_text
, byport
);
1001 sar_services_load_file(const char *etc_services
)
1003 static const char *whitespace
= " \t\r\n";
1004 struct service_byname
*canon
;
1005 struct service_byport
*byport
;
1006 char *name
, *port
, *alias
, *ptr
;
1009 enum service_proto proto
;
1010 char linebuf
[LINE_MAX
];
1012 file
= fopen(etc_services
, "r");
1015 while (fgets(linebuf
, sizeof(linebuf
), file
)) {
1016 ptr
= strchr(linebuf
, '#');
1019 /* Tokenize canonical service name and port number. */
1020 name
= strtok_r(linebuf
, whitespace
, &ptr
);
1023 port
= strtok_r(NULL
, whitespace
, &ptr
);
1026 pnum
= strtoul(port
, &port
, 10);
1027 if (pnum
== 0 || *port
++ != '/')
1029 if (!strcmp(port
, "udp"))
1030 proto
= SERVICE_UDP
;
1031 else if (!strcmp(port
, "tcp"))
1032 proto
= SERVICE_TCP
;
1035 /* Set up canonical name-indexed service entry. */
1036 canon
= sar_service_byname(name
, 1);
1037 if (canon
->protos
[proto
].valid
) {
1038 /* log_module(sar_log, LOG_ERROR, "Service %s/%s listed twice.", name, port); who cares? */
1041 canon
->protos
[proto
].canon
= NULL
;
1042 canon
->protos
[proto
].port
= pnum
;
1043 canon
->protos
[proto
].valid
= 1;
1045 /* Set up port-indexed service entry. */
1046 byport
= sar_service_byport(pnum
, 1);
1047 if (!byport
->byname
[proto
])
1048 byport
->byname
[proto
] = canon
;
1050 /* Add alias entries. */
1051 while ((alias
= strtok_r(NULL
, whitespace
, &ptr
))) {
1052 struct service_byname
*byname
;
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. */
1060 byname
->protos
[proto
].canon
= canon
;
1061 byname
->protos
[proto
].port
= pnum
;
1062 byname
->protos
[proto
].valid
= 1;
1069 sar_services_init(const char *etc_services
)
1071 /* These are a portion of the services listed at
1072 * http://www.dns-sd.org/ServiceTypes.html.
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
;
1083 /* Forget old services dicts and allocate new ones. */
1084 dict_delete(services_byname
);
1085 services_byname
= dict_new();
1086 dict_set_free_data(services_byname
, free
);
1088 dict_delete(services_byport
);
1089 services_byport
= dict_new();
1090 dict_set_free_data(services_byport
, free
);
1092 /* Load the list from the services file. */
1093 sar_services_load_file(etc_services
);
1095 /* Mark well-known services as using DNS-SD SRV records. */
1096 for (ii
= 0; tcp_srvs
[ii
]; ++ii
) {
1097 byname
= sar_service_byname(tcp_srvs
[ii
], 1);
1098 byname
->protos
[SERVICE_TCP
].srv
= 1;
1101 for (ii
= 0; udp_srvs
[ii
]; ++ii
) {
1102 byname
= sar_service_byname(udp_srvs
[ii
], 1);
1103 byname
->protos
[SERVICE_UDP
].srv
= 1;
1108 sar_register_helper(struct sar_family_helper
*helper
)
1110 assert(helper
->family
<= MAX_FAMILY
);
1111 sar_helpers
[helper
->family
] = helper
;
1112 helper
->next
= sar_first_helper
;
1113 sar_first_helper
= helper
;
1117 sar_addrlen(const struct sockaddr
*sa
, UNUSED_ARG(unsigned int size
))
1119 return sa
->sa_family
<= MAX_FAMILY
&& sar_helpers
[sa
->sa_family
]
1120 ? sar_helpers
[sa
->sa_family
]->socklen
: 0;
1123 struct sar_getaddr_state
{
1124 struct sar_family_helper
*helper
;
1125 struct addrinfo
*ai_head
;
1126 struct addrinfo
*ai_tail
;
1129 unsigned int search_pos
;
1130 unsigned int flags
, socktype
, protocol
, port
;
1131 unsigned int srv_ofs
;
1132 char full_name
[DNS_NAME_LENGTH
];
1136 sar_getaddr_append(struct sar_getaddr_state
*state
, struct addrinfo
*ai
, int copy
)
1140 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_append({full_name=%s}, ai=%p, copy=%d)", state
->full_name
, (void*)ai
, copy
);
1142 /* Set the appropriate pointer to the new element(s). */
1144 state
->ai_tail
->ai_next
= ai
;
1146 state
->ai_head
= ai
;
1148 /* Find the end of the list. */
1150 /* Make sure we copy fields for both the first and last entries. */
1153 if (!ai
->ai_addrlen
) {
1154 assert(sar_helpers
[ai
->ai_family
]);
1155 ai
->ai_addrlen
= sar_helpers
[ai
->ai_family
]->socklen
;
1157 #if defined(HAVE_SOCKADDR_SA_LEN)
1158 ai
->ai_addr
->sa_len
= ai
->ai_addrlen
;
1160 ai
->ai_addr
->sa_family
= ai
->ai_family
;
1161 ai
->ai_socktype
= state
->socktype
;
1162 ai
->ai_protocol
= state
->protocol
;
1169 for (count
= 1; ai
->ai_next
; ++count
, ai
= ai
->ai_next
)
1173 /* Set the tail pointer and return count of appended items. */
1174 state
->ai_tail
= ai
;
1178 static struct sar_request
*
1179 sar_getaddr_request(struct sar_request
*req
)
1181 struct sar_getaddr_state
*state
;
1183 char full_name
[DNS_NAME_LENGTH
];
1185 state
= (struct sar_getaddr_state
*)(req
+ 1);
1187 /* If we can and should, append the current search domain. */
1188 if (state
->search_pos
< conf
.sar_search
->used
)
1189 snprintf(full_name
, sizeof(full_name
), "%s.%s", state
->full_name
, conf
.sar_search
->list
[state
->search_pos
]);
1190 else if (state
->search_pos
== conf
.sar_search
->used
)
1191 safestrncpy(full_name
, state
->full_name
, sizeof(full_name
));
1193 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_request({id=%d}): failed", req
->id
);
1194 state
->cb(state
->cb_ctx
, NULL
, SAI_NONAME
);
1198 /* Build the appropriate request for DNS record(s). */
1199 if (state
->flags
& SAI_ALL
)
1200 len
= sar_request_build(req
, full_name
+ state
->srv_ofs
, REQ_QTYPE_ALL
, NULL
);
1201 else if (state
->srv_ofs
)
1202 len
= state
->helper
->build_addr_request(req
, full_name
+ state
->srv_ofs
, full_name
, state
->flags
);
1204 len
= state
->helper
->build_addr_request(req
, full_name
, NULL
, state
->flags
);
1206 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_request({id=%d}): full_name=%s, srv_ofs=%d", req
->id
, full_name
, state
->srv_ofs
);
1208 /* Check that the request could be built. */
1210 state
->cb(state
->cb_ctx
, NULL
, SAI_NODATA
);
1214 /* Send the request. */
1215 sar_request_send(req
);
1220 sar_getaddr_decode(struct sar_request
*req
, struct dns_header
*hdr
, struct dns_rr
*rr
, unsigned char *raw
, unsigned int raw_size
, unsigned int rr_idx
)
1222 struct sar_getaddr_state
*state
;
1224 unsigned int jj
, pos
, hit
;
1226 log_module(sar_log
, LOG_DEBUG
, " sar_getaddr_decode(id=%d, <hdr>, {type=%d, rdlength=%d, name=%s}, <data>, %u, <idx>)", hdr
->id
, rr
[rr_idx
].type
, rr
[rr_idx
].rdlength
, rr
[rr_idx
].name
, raw_size
);
1227 state
= (struct sar_getaddr_state
*)(req
+ 1);
1229 switch (rr
[rr_idx
].type
) {
1231 if (state
->flags
& SAI_ALL
)
1232 return sar_ipv4_helper
.decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1233 #if defined(AF_INET6)
1234 else if (state
->flags
& SAI_V4MAPPED
)
1235 return sar_ipv6_helper
.decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1237 return state
->helper
->decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1240 #if defined(AF_INET6)
1241 if (state
->flags
& SAI_ALL
)
1242 return sar_ipv6_helper
.decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1243 return state
->helper
->decode_addr(state
, rr
+ rr_idx
, raw
, raw_size
);
1248 case REQ_TYPE_CNAME
:
1249 /* there should be the canonical name next */
1250 pos
= rr
[rr_idx
].rd_start
;
1251 cname
= sar_extract_name(raw
, raw_size
, &pos
);
1253 return 0; /* XXX: eventually log the unhandled body */
1254 /* and it should correspond to some other answer in the response */
1255 for (jj
= hit
= 0; jj
< hdr
->ancount
; ++jj
) {
1256 if (strcasecmp(cname
, rr
[jj
].name
))
1258 hit
+= sar_getaddr_decode(req
, hdr
, rr
, raw
, raw_size
, jj
);
1260 /* XXX: if (!hit) handle or log the incomplete recursion; */
1264 /* TODO: decode the SRV record */
1272 sar_getaddr_ok(struct sar_request
*req
, struct dns_header
*hdr
, struct dns_rr
*rr
, unsigned char *raw
, unsigned int raw_size
)
1274 struct sar_getaddr_state
*state
;
1277 state
= (struct sar_getaddr_state
*)(req
+ 1);
1279 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_ok({id=%d}, {id=%d}, <rr>, <data>, %u)", req
->id
, hdr
->id
, raw_size
);
1280 for (ii
= 0; ii
< hdr
->ancount
; ++ii
)
1281 sar_getaddr_decode(req
, hdr
, rr
, raw
, raw_size
, ii
);
1283 /* If we found anything, report it, else try again. */
1285 state
->cb(state
->cb_ctx
, state
->ai_head
, SAI_SUCCESS
);
1287 sar_getaddr_request(req
);
1291 sar_getaddr_fail(struct sar_request
*req
, UNUSED_ARG(unsigned int rcode
))
1293 struct sar_getaddr_state
*state
;
1295 log_module(sar_log
, LOG_DEBUG
, "sar_getaddr_fail({id=%d}, rcode=%u)", req
->id
, rcode
);
1296 state
= (struct sar_getaddr_state
*)(req
+ 1);
1297 state
->cb(state
->cb_ctx
, NULL
, SAI_FAIL
);
1300 struct sar_request
*
1301 sar_getaddr(const char *node
, const char *service
, const struct addrinfo
*hints_
, sar_addr_cb cb
, void *cb_ctx
)
1303 struct sockaddr_storage ss
;
1304 struct addrinfo hints
;
1305 struct sar_family_helper
*helper
;
1306 struct service_byname
*svc
;
1308 unsigned int portnum
;
1310 enum service_proto proto
;
1312 if (!node
&& !service
) {
1313 cb(cb_ctx
, NULL
, SAI_NONAME
);
1317 /* Initialize local hints structure. */
1319 memcpy(&hints
, hints_
, sizeof(hints
));
1321 memset(&hints
, 0, sizeof(hints
));
1323 /* Translate socket type to internal protocol. */
1324 switch (hints
.ai_socktype
) {
1325 case 0: hints
.ai_socktype
= SOCK_STREAM
; /* and fall through */
1326 case SOCK_STREAM
: proto
= SERVICE_TCP
; break;
1327 case SOCK_DGRAM
: proto
= SERVICE_UDP
; break;
1329 cb(cb_ctx
, NULL
, SAI_SOCKTYPE
);
1333 /* Figure out preferred socket size. */
1334 if (hints
.ai_family
== AF_UNSPEC
)
1335 hints
.ai_family
= AF_INET
;
1336 if (hints
.ai_family
> MAX_FAMILY
1337 || !(helper
= sar_helpers
[hints
.ai_family
])) {
1338 cb(cb_ctx
, NULL
, SAI_FAMILY
);
1341 hints
.ai_addrlen
= helper
->socklen
;
1343 /* If \a node is NULL, figure out the correct default from the
1344 * requested family and SAI_PASSIVE flag.
1347 node
= (hints
.ai_flags
& SAI_PASSIVE
) ? helper
->unspec_addr
: helper
->localhost_addr
;
1349 /* Try to parse (failing that, look up) \a service. */
1351 portnum
= 0, svc
= NULL
;
1352 else if ((portnum
= strtoul(service
, &end
, 10)), *end
== '\0')
1354 else if ((svc
= sar_service_byname(service
, 0)) != NULL
)
1355 portnum
= svc
->protos
[proto
].port
;
1357 cb(cb_ctx
, NULL
, SAI_SERVICE
);
1361 /* Try to parse \a node as a numeric hostname.*/
1362 pos
= sar_pton((struct sockaddr
*)&ss
, sizeof(ss
), NULL
, node
);
1363 if (pos
&& node
[pos
] == '\0') {
1364 struct addrinfo
*ai
;
1365 char canonname
[SAR_NTOP_MAX
];
1367 /* we have a valid address; use it */
1368 sar_set_port((struct sockaddr
*)&ss
, sizeof(ss
), portnum
);
1369 hints
.ai_addrlen
= sar_addrlen((struct sockaddr
*)&ss
, sizeof(ss
));
1370 if (!hints
.ai_addrlen
) {
1371 cb(cb_ctx
, NULL
, SAI_FAMILY
);
1374 pos
= sar_ntop(canonname
, sizeof(canonname
), (struct sockaddr
*)&ss
, hints
.ai_addrlen
);
1376 /* allocate and fill in the addrinfo response */
1377 ai
= calloc(1, sizeof(*ai
) + hints
.ai_addrlen
+ pos
+ 1);
1378 ai
->ai_family
= ss
.ss_family
;
1379 ai
->ai_socktype
= hints
.ai_socktype
;
1380 ai
->ai_protocol
= hints
.ai_protocol
;
1381 ai
->ai_addrlen
= hints
.ai_addrlen
;
1382 ai
->ai_addr
= memcpy(ai
+ 1, &ss
, ai
->ai_addrlen
);
1383 ai
->ai_canonname
= strcpy((char*)ai
->ai_addr
+ ai
->ai_addrlen
, canonname
);
1384 cb(cb_ctx
, ai
, SAI_SUCCESS
);
1386 } else if (hints
.ai_flags
& SAI_NUMERICHOST
) {
1387 cb(cb_ctx
, NULL
, SAI_NONAME
);
1390 struct sar_request
*req
;
1391 struct sar_getaddr_state
*state
;
1392 unsigned int len
, ii
;
1394 req
= sar_request_alloc(sizeof(*state
), sar_getaddr_ok
, sar_getaddr_fail
);
1396 state
= (struct sar_getaddr_state
*)(req
+ 1);
1397 state
->helper
= helper
;
1398 state
->ai_head
= state
->ai_tail
= NULL
;
1400 state
->cb_ctx
= cb_ctx
;
1401 state
->flags
= hints
.ai_flags
;
1402 state
->socktype
= hints
.ai_socktype
;
1403 state
->protocol
= hints
.ai_protocol
;
1404 state
->port
= portnum
;
1406 if ((state
->flags
& SAI_NOSRV
) || !svc
)
1408 else if (svc
->protos
[proto
].srv
)
1409 state
->srv_ofs
= snprintf(state
->full_name
, sizeof(state
->full_name
), "_%s._%s.", svc
->name
, (proto
== SERVICE_UDP
? "udp" : "tcp"));
1410 else if (state
->flags
& SAI_FORCESRV
)
1411 state
->srv_ofs
= snprintf(state
->full_name
, sizeof(state
->full_name
), "_%s._%s.", service
, (proto
== SERVICE_UDP
? "udp" : "tcp"));
1415 if (state
->srv_ofs
< sizeof(state
->full_name
))
1416 safestrncpy(state
->full_name
+ state
->srv_ofs
, node
, sizeof(state
->full_name
) - state
->srv_ofs
);
1418 for (ii
= len
= 0; node
[ii
]; ++ii
)
1419 if (node
[ii
] == '.')
1421 if (len
>= conf
.sar_ndots
)
1422 state
->search_pos
= conf
.sar_search
->used
;
1424 state
->search_pos
= 0;
1426 /* XXX: fill in *state with any other fields needed to parse responses. */
1428 if (!sar_getaddr_request(req
)) {
1436 struct sar_getname_state
{
1441 unsigned int family
;
1442 enum service_proto proto
;
1443 unsigned short port
;
1444 unsigned int doing_arpa
: 1; /* checking .ip6.arpa vs .ip6.int */
1445 unsigned char original
[16]; /* original address data */
1446 /* name must be long enough to hold "0.0.<etc>.ip6.arpa" */
1451 sar_getname_fail(struct sar_request
*req
, UNUSED_ARG(unsigned int rcode
))
1453 struct sar_getname_state
*state
;
1456 state
= (struct sar_getname_state
*)(req
+ 1);
1457 if (state
->doing_arpa
) {
1458 len
= strlen(state
->name
);
1460 strcpy(state
->name
+ len
- 4, "int");
1461 len
= sar_request_build(req
, state
->name
, REQ_TYPE_PTR
, NULL
);
1463 sar_request_send(req
);
1467 state
->cb(state
->cb_ctx
, NULL
, NULL
, SAI_FAIL
);
1468 free(state
->hostname
);
1471 static const char *sar_getname_port(unsigned int port
, unsigned int flags
, char *tmpbuf
, unsigned int tmpbuf_len
)
1473 struct service_byport
*service
;
1474 enum service_proto proto
;
1477 sprintf(port_text
, "%d", port
);
1478 proto
= (flags
& SNI_DGRAM
) ? SERVICE_UDP
: SERVICE_TCP
;
1479 if (!(flags
& SNI_NUMERICSERV
)
1480 && (service
= dict_find(services_byport
, port_text
, NULL
))
1481 && service
->byname
[proto
])
1482 return service
->byname
[proto
]->name
;
1483 snprintf(tmpbuf
, tmpbuf_len
, "%d", port
);
1488 sar_getname_confirm(struct sar_request
*req
, struct dns_header
*hdr
, struct dns_rr
*rr
, unsigned char *raw
, unsigned int raw_size
)
1490 struct sar_getname_state
*state
;
1491 const unsigned char *data
;
1492 const char *portname
;
1494 unsigned int ii
, nbr
;
1496 state
= (struct sar_getname_state
*)(req
+ 1);
1497 for (ii
= 0; ii
< hdr
->ancount
; ++ii
) {
1498 /* Is somebody confused or trying to play games? */
1499 if (rr
[ii
].class != REQ_CLASS_IN
1500 || strcasecmp(state
->hostname
, rr
[ii
].name
))
1502 switch (rr
[ii
].type
) {
1503 case REQ_TYPE_A
: nbr
= 4; break;
1504 case REQ_TYPE_AAAA
: nbr
= 16; break;
1507 data
= sar_extract_rdata(rr
, nbr
, raw
, raw_size
);
1508 if (data
&& !memcmp(data
, state
->original
, nbr
)) {
1509 portname
= sar_getname_port(state
->port
, state
->flags
, servbuf
, sizeof(servbuf
));
1510 state
->cb(state
->cb_ctx
, state
->hostname
, portname
, SAI_SUCCESS
);
1511 free(state
->hostname
);
1515 state
->cb(state
->cb_ctx
, NULL
, NULL
, SAI_MISMATCH
);
1516 free(state
->hostname
);
1520 sar_getname_ok(struct sar_request
*req
, struct dns_header
*hdr
, struct dns_rr
*rr
, unsigned char *raw
, unsigned int raw_size
)
1522 struct sar_getname_state
*state
;
1523 const char *portname
;
1524 unsigned int ii
, pos
;
1527 state
= (struct sar_getname_state
*)(req
+ 1);
1528 for (ii
= 0; ii
< hdr
->ancount
; ++ii
) {
1529 if (rr
[ii
].type
!= REQ_TYPE_PTR
1530 || rr
[ii
].class != REQ_CLASS_IN
1531 || strcasecmp(rr
[ii
].name
, state
->name
))
1533 pos
= rr
[ii
].rd_start
;
1534 state
->hostname
= sar_extract_name(raw
, raw_size
, &pos
);
1538 if (!state
->hostname
) {
1539 state
->cb(state
->cb_ctx
, NULL
, NULL
, SAI_NONAME
);
1543 if (state
->flags
& SNI_PARANOID
) {
1544 req
->cb_ok
= sar_getname_confirm
;
1545 pos
= sar_helpers
[state
->family
]->build_addr_request(req
, state
->hostname
, NULL
, 0);
1547 sar_request_send(req
);
1549 free(state
->hostname
);
1550 state
->cb(state
->cb_ctx
, NULL
, NULL
, SAI_FAIL
);
1555 portname
= sar_getname_port(state
->port
, state
->flags
, servbuf
, sizeof(servbuf
));
1556 state
->cb(state
->cb_ctx
, state
->hostname
, portname
, SAI_SUCCESS
);
1557 free(state
->hostname
);
1560 struct sar_request
*
1561 sar_getname(const struct sockaddr
*sa
, unsigned int salen
, int flags
, sar_name_cb cb
, void *cb_ctx
)
1563 struct sar_family_helper
*helper
;
1564 struct sar_request
*req
;
1565 struct sar_getname_state
*state
;
1569 if (sa
->sa_family
> MAX_FAMILY
1570 || !(helper
= sar_helpers
[sa
->sa_family
])) {
1571 cb(cb_ctx
, NULL
, NULL
, SAI_FAMILY
);
1575 port
= helper
->get_port(sa
, salen
);
1577 if (flags
& SNI_NUMERICHOST
) {
1578 const char *servname
;
1579 char host
[SAR_NTOP_MAX
], servbuf
[16];
1581 /* If appropriate, try to look up service name. */
1582 servname
= sar_getname_port(port
, flags
, servbuf
, sizeof(servbuf
));
1583 len
= sar_ntop(host
, sizeof(host
), sa
, salen
);
1585 cb(cb_ctx
, host
, servname
, SAI_SUCCESS
);
1589 req
= sar_request_alloc(sizeof(*state
), sar_getname_ok
, sar_getname_fail
);
1591 state
= (struct sar_getname_state
*)(req
+ 1);
1593 state
->cb_ctx
= cb_ctx
;
1594 state
->flags
= flags
;
1595 state
->family
= sa
->sa_family
;
1598 helper
->build_ptr_name(state
, sa
, salen
);
1599 assert(strlen(state
->name
) < sizeof(state
->name
));
1600 len
= sar_request_build(req
, state
->name
, REQ_TYPE_PTR
, NULL
);
1602 cb(cb_ctx
, NULL
, NULL
, SAI_NODATA
);
1607 sar_request_send(req
);
1612 ipv4_ntop(char *output
, unsigned int out_size
, const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1614 struct sockaddr_in
*sin
;
1615 unsigned int ip4
, pos
;
1617 sin
= (struct sockaddr_in
*)sa
;
1618 ip4
= ntohl(sin
->sin_addr
.s_addr
);
1619 pos
= snprintf(output
, out_size
, "%u.%u.%u.%u", (ip4
>> 24), (ip4
>> 16) & 255, (ip4
>> 8) & 255, ip4
& 255);
1620 return (pos
< out_size
) ? pos
: 0;
1624 sar_pton_ip4(const char *input
, unsigned int *bits
, uint32_t *output
)
1626 unsigned int dots
= 0, pos
= 0, part
= 0, ip
= 0;
1628 /* Intentionally no support for bizarre IPv4 formats (plain
1629 * integers, octal or hex components) -- only vanilla dotted
1630 * decimal quads, optionally with trailing /nn.
1632 if (input
[0] == '.')
1635 if (isdigit(input
[pos
])) {
1636 part
= part
* 10 + input
[pos
++] - '0';
1639 if ((dots
== 3) && !isdigit(input
[pos
])) {
1640 *output
= htonl(ip
| part
);
1643 } else if (input
[pos
] == '.') {
1644 if (input
[++pos
] == '.')
1646 ip
|= part
<< (24 - 8 * dots
++);
1648 } else if (bits
&& input
[pos
] == '/' && isdigit(input
[pos
+ 1])) {
1652 len
= strtoul(input
+ pos
+ 1, &term
, 10);
1653 if (term
<= input
+ pos
+ 1)
1658 return term
- input
;
1664 ipv4_pton(struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
), unsigned int *bits
, const char *input
)
1668 pos
= sar_pton_ip4(input
, bits
, &((struct sockaddr_in
*)sa
)->sin_addr
.s_addr
);
1671 sa
->sa_family
= AF_INET
;
1672 #if defined(HAVE_SOCKADDR_SA_LEN)
1673 sa
->sa_len
= sizeof(struct sockaddr_in
);
1679 ipv4_get_port(const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1681 return ntohs(((const struct sockaddr_in
*)sa
)->sin_port
);
1685 ipv4_set_port(struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
), unsigned short port
)
1687 ((struct sockaddr_in
*)sa
)->sin_port
= htons(port
);
1692 ipv4_addr_request(struct sar_request
*req
, const char *node
, const char *srv_node
, UNUSED_ARG(unsigned int flags
))
1696 len
= sar_request_build(req
, node
, REQ_TYPE_A
, srv_node
, REQ_TYPE_SRV
, NULL
);
1698 len
= sar_request_build(req
, node
, REQ_TYPE_A
, NULL
);
1703 ipv4_ptr_name(struct sar_getname_state
*state
, const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1705 const uint8_t *bytes
;
1707 bytes
= (uint8_t*)&((struct sockaddr_in
*)sa
)->sin_addr
.s_addr
;
1708 memcpy(state
->original
, bytes
, 4);
1709 snprintf(state
->name
, sizeof(state
->name
),
1710 "%u.%u.%u.%u.in-addr.arpa",
1711 bytes
[3], bytes
[2], bytes
[1], bytes
[0]);
1715 ipv4_decode(struct sar_getaddr_state
*state
, struct dns_rr
*rr
, unsigned char *raw
, UNUSED_ARG(unsigned int raw_size
))
1717 struct sockaddr_in
*sa
;
1718 struct addrinfo
*ai
;
1720 if (rr
->rdlength
!= 4)
1723 if (state
->flags
& SAI_CANONNAME
) {
1724 ai
= calloc(1, sizeof(*ai
) + sizeof(*sa
) + strlen(rr
->name
) + 1);
1725 sa
= (struct sockaddr_in
*)(ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1));
1726 ai
->ai_canonname
= strcpy((char*)(sa
+ 1), rr
->name
);
1728 ai
= calloc(1, sizeof(*ai
) + sizeof(*sa
));
1729 sa
= (struct sockaddr_in
*)(ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1));
1730 ai
->ai_canonname
= NULL
;
1733 ai
->ai_family
= AF_INET
;
1734 sa
->sin_port
= htons(state
->port
);
1735 memcpy(&sa
->sin_addr
.s_addr
, raw
+ rr
->rd_start
, 4);
1736 return sar_getaddr_append(state
, ai
, 1);
1739 static struct sar_family_helper sar_ipv4_helper
= {
1742 sizeof(struct sockaddr_in
),
1754 #if defined(AF_INET6)
1757 ipv6_ntop(char *output
, unsigned int out_size
, const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1759 struct sockaddr_in6
*sin6
;
1760 unsigned int pos
, part
, max_start
, max_zeros
, curr_zeros
, ii
;
1761 unsigned short addr16
;
1763 sin6
= (struct sockaddr_in6
*)sa
;
1764 /* Find longest run of zeros. */
1765 for (max_start
= max_zeros
= curr_zeros
= ii
= 0; ii
< 8; ++ii
) {
1766 addr16
= (sin6
->sin6_addr
.s6_addr
[ii
* 2] << 8) | sin6
->sin6_addr
.s6_addr
[ii
* 2 + 1];
1769 else if (curr_zeros
> max_zeros
) {
1770 max_start
= ii
- curr_zeros
;
1771 max_zeros
= curr_zeros
;
1775 if (curr_zeros
> max_zeros
) {
1776 max_start
= ii
- curr_zeros
;
1777 max_zeros
= curr_zeros
;
1780 /* Print out address. */
1781 #define APPEND(CH) do { output[pos++] = (CH); if (pos >= out_size) return 0; } while (0)
1782 for (pos
= 0, ii
= 0; ii
< 8; ++ii
) {
1783 if ((max_zeros
> 0) && (ii
== max_start
)) {
1787 ii
+= max_zeros
- 1;
1790 part
= (sin6
->sin6_addr
.s6_addr
[ii
* 2] << 8) | sin6
->sin6_addr
.s6_addr
[ii
* 2 + 1];
1792 APPEND(hexdigits
[part
>> 12]);
1794 APPEND(hexdigits
[(part
>> 8) & 15]);
1796 APPEND(hexdigits
[(part
>> 4) & 15]);
1797 APPEND(hexdigits
[part
& 15]);
1807 static const unsigned char xdigit_value
[256] = {
1808 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1809 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1810 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1811 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
1812 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1813 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1814 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1818 ipv6_pton(struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
), unsigned int *bits
, const char *input
)
1820 const char *part_start
= NULL
;
1821 struct sockaddr_in6
*sin6
;
1824 unsigned int part
= 0, pos
= 0, ii
= 0, cpos
= 8;
1826 if (!(colon
= strchr(input
, ':')))
1828 dot
= strchr(input
, '.');
1829 if (dot
&& dot
< colon
)
1831 sin6
= (struct sockaddr_in6
*)sa
;
1832 /* Parse IPv6, possibly like ::127.0.0.1.
1833 * This is pretty straightforward; the only trick is borrowed
1834 * from Paul Vixie (BIND): when it sees a "::" continue as if
1835 * it were a single ":", but note where it happened, and fill
1836 * with zeros afterwards.
1838 if (input
[pos
] == ':') {
1839 if ((input
[pos
+1] != ':') || (input
[pos
+2] == ':'))
1843 part_start
= input
+ pos
;
1846 if (isxdigit(input
[pos
])) {
1847 part
= (part
<< 4) | xdigit_value
[(unsigned char)input
[pos
]];
1851 } else if (input
[pos
] == ':') {
1852 part_start
= input
+ ++pos
;
1853 if (input
[pos
] == '.')
1855 sin6
->sin6_addr
.s6_addr
[ii
* 2] = part
>> 8;
1856 sin6
->sin6_addr
.s6_addr
[ii
* 2 + 1] = part
& 255;
1859 if (input
[pos
] == ':') {
1865 } else if (input
[pos
] == '.') {
1868 len
= sar_pton_ip4(part_start
, bits
, &ip4
);
1869 if (!len
|| (ii
> 6))
1871 memcpy(sin6
->sin6_addr
.s6_addr
+ ii
* 2, &ip4
, sizeof(ip4
));
1875 pos
= part_start
+ len
- input
;
1877 } else if (bits
&& input
[pos
] == '/' && isdigit(input
[pos
+ 1])) {
1881 len
= strtoul(input
+ pos
+ 1, &term
, 10);
1882 if (term
<= input
+ pos
+ 1)
1890 } else if (cpos
<= 8) {
1891 sin6
->sin6_addr
.s6_addr
[ii
* 2] = part
>> 8;
1892 sin6
->sin6_addr
.s6_addr
[ii
* 2 + 1] = part
& 255;
1897 /* Shift stuff after "::" up and fill middle with zeros. */
1902 for (jj
= 0; jj
< ii
- cpos
; jj
++)
1903 sin6
->sin6_addr
.s6_addr
[15 - jj
] = sin6
->sin6_addr
.s6_addr
[ii
- jj
- 1];
1904 for (jj
= 0; jj
< 16 - ii
; jj
++)
1905 sin6
->sin6_addr
.s6_addr
[cpos
+ jj
] = 0;
1907 sa
->sa_family
= AF_INET6
;
1908 #if defined(HAVE_SOCKADDR_SA_LEN)
1909 sa
->sa_len
= sizeof(struct sockaddr_in6
);
1915 ipv6_get_port(const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1917 return ntohs(((const struct sockaddr_in6
*)sa
)->sin6_port
);
1921 ipv6_set_port(struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
), unsigned short port
)
1923 ((struct sockaddr_in6
*)sa
)->sin6_port
= htons(port
);
1928 ipv6_addr_request(struct sar_request
*req
, const char *node
, const char *srv_node
, unsigned int flags
)
1931 if (flags
& SAI_V4MAPPED
) {
1933 len
= sar_request_build(req
, node
, REQ_TYPE_AAAA
, node
, REQ_TYPE_A
, srv_node
, REQ_TYPE_SRV
, NULL
);
1935 len
= sar_request_build(req
, node
, REQ_TYPE_AAAA
, node
, REQ_TYPE_A
, NULL
);
1938 len
= sar_request_build(req
, node
, REQ_TYPE_AAAA
, srv_node
, REQ_TYPE_SRV
, NULL
);
1940 len
= sar_request_build(req
, node
, REQ_TYPE_AAAA
, NULL
);
1946 ipv6_ptr_name(struct sar_getname_state
*state
, const struct sockaddr
*sa
, UNUSED_ARG(unsigned int socklen
))
1948 const uint8_t *bytes
;
1949 unsigned int ii
, jj
;
1951 bytes
= ((struct sockaddr_in6
*)sa
)->sin6_addr
.s6_addr
;
1952 memcpy(state
->original
, bytes
, 16);
1953 for (jj
= 0, ii
= 16; ii
> 0; ) {
1954 state
->name
[jj
++] = hexdigits
[bytes
[--ii
] & 15];
1955 state
->name
[jj
++] = hexdigits
[bytes
[ii
] >> 4];
1956 state
->name
[jj
++] = '.';
1958 strcpy(state
->name
+ jj
, ".ip6.arpa");
1959 state
->doing_arpa
= 1;
1963 ipv6_decode(struct sar_getaddr_state
*state
, struct dns_rr
*rr
, unsigned char *raw
, UNUSED_ARG(unsigned int raw_size
))
1965 struct sockaddr_in6
*sa
;
1966 struct addrinfo
*ai
;
1968 if (state
->flags
& SAI_CANONNAME
) {
1969 ai
= calloc(1, sizeof(*ai
) + sizeof(*sa
) + strlen(rr
->name
) + 1);
1970 sa
= (struct sockaddr_in6
*)(ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1));
1971 ai
->ai_canonname
= strcpy((char*)(sa
+ 1), rr
->name
);
1973 ai
= calloc(1, sizeof(*ai
) + sizeof(*sa
));
1974 sa
= (struct sockaddr_in6
*)(ai
->ai_addr
= (struct sockaddr
*)(ai
+ 1));
1975 ai
->ai_canonname
= NULL
;
1978 if (rr
->rdlength
== 4) {
1979 sa
->sin6_addr
.s6_addr
[10] = sa
->sin6_addr
.s6_addr
[11] = 0xff;
1980 memcpy(sa
->sin6_addr
.s6_addr
+ 12, raw
+ rr
->rd_start
, 4);
1981 } else if (rr
->rdlength
== 16) {
1982 memcpy(sa
->sin6_addr
.s6_addr
, raw
+ rr
->rd_start
, 16);
1988 ai
->ai_family
= AF_INET6
;
1989 sa
->sin6_port
= htons(state
->port
);
1990 return sar_getaddr_append(state
, ai
, 1);
1993 static struct sar_family_helper sar_ipv6_helper
= {
1996 sizeof(struct sockaddr_in6
),
2008 #endif /* defined(AF_INET6) */
2013 ioset_close(sar_fd
, 1);
2014 dict_delete(services_byname
);
2015 dict_delete(services_byport
);
2016 dict_delete(sar_nameservers
);
2017 dict_delete(sar_requests
);
2018 free_string_list(conf
.sar_search
);
2019 free_string_list(conf
.sar_nslist
);
2023 sar_conf_reload(void)
2026 const char *resolv_conf
= "/etc/resolv.conf";
2027 const char *services
= "/etc/services";
2030 node
= conf_get_data("modules/sar", RECDB_OBJECT
);
2032 str
= database_get_data(node
, "resolv_conf", RECDB_QSTRING
);
2033 if (str
) resolv_conf
= str
;
2034 str
= database_get_data(node
, "services", RECDB_QSTRING
);
2035 if (str
) services
= str
;
2037 sar_dns_init(resolv_conf
);
2038 sar_services_init(services
);
2044 reg_exit_func(sar_cleanup
);
2045 sar_log
= log_register_type("sar", NULL
);
2047 sar_requests
= dict_new();
2048 dict_set_free_data(sar_requests
, sar_request_cleanup
);
2050 sar_nameservers
= dict_new();
2051 dict_set_free_data(sar_nameservers
, free
);
2053 sar_register_helper(&sar_ipv4_helper
);
2054 #if defined(AF_INET6)
2055 sar_register_helper(&sar_ipv6_helper
);
2058 conf_register_reload(sar_conf_reload
);