r12001@catbus: nickm | 2007-02-28 15:24:12 -0500
[tor.git] / src / or / eventdns.c
blob517db588530518db262e11a5c7ad103aef5b3ca4
1 /* $Id$ */
3 /* The original version of this module was written by Adam Langley; for
4 * a history of modifications, check out the subversion logs.
6 * When editing this module, try to keep it re-mergeable by Adam. Don't
7 * reformat the whitespace, add Tor dependencies, or so on.
9 * TODO:
10 * - Replace all externally visible magic numbers with #defined constants.
11 * - Write documentation for APIs of all external functions.
14 /* Async DNS Library
15 * Adam Langley <agl@imperialviolet.org>
16 * Public Domain code
18 * This software is Public Domain. To view a copy of the public domain dedication,
19 * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
20 * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
22 * I ask and expect, but do not require, that all derivative works contain an
23 * attribution similar to:
24 * Parts developed by Adam Langley <agl@imperialviolet.org>
26 * You may wish to replace the word "Parts" with something else depending on
27 * the amount of original code.
29 * (Derivative works does not include programs which link against, run or include
30 * the source verbatim in their source distributions)
32 * Version: 0.1b
35 #include <sys/types.h>
36 #include "eventdns_tor.h"
37 //#define NDEBUG
38 #include "../common/torint.h"
40 #ifndef DNS_USE_CPU_CLOCK_FOR_ID
41 #ifndef DNS_USE_GETTIMEOFDAY_FOR_ID
42 #ifndef DNS_USE_OPENSSL_FOR_ID
43 #error Must configure at least one id generation method.
44 #error Please see the documentation.
45 #endif
46 #endif
47 #endif
49 // #define _POSIX_C_SOURCE 200507
50 #define _GNU_SOURCE
52 #ifdef DNS_USE_CPU_CLOCK_FOR_ID
53 #ifdef DNS_USE_OPENSSL_FOR_ID
54 #error Multiple id options selected
55 #endif
56 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
57 #error Multiple id options selected
58 #endif
59 #include <time.h>
60 #endif
62 #ifdef DNS_USE_OPENSSL_FOR_ID
63 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
64 #error Multiple id options selected
65 #endif
66 #include <openssl/rand.h>
67 #endif
69 #define _FORTIFY_SOURCE 3
71 #include <string.h>
72 #include <fcntl.h>
73 #include <sys/time.h>
74 #ifdef HAVE_STDINT_H
75 #include <stdint.h>
76 #endif
77 #include <stdlib.h>
78 #include <string.h>
79 #include <errno.h>
80 #include <assert.h>
81 #include <unistd.h>
82 #include <limits.h>
83 #include <sys/stat.h>
84 #include <ctype.h>
85 #include <stdio.h>
86 #include <stdarg.h>
88 #include "eventdns.h"
89 #ifdef WIN32
90 #include <windows.h>
91 #include <winsock2.h>
92 #include <iphlpapi.h>
93 #else
94 #include <sys/socket.h>
95 #include <netinet/in.h>
96 #include <arpa/inet.h>
97 #endif
99 #ifdef HAVE_NETINET_IN6_H
100 #include <netinet/in6.h>
101 #endif
103 #ifdef WIN32
104 typedef int socklen_t;
105 #endif
107 #define EVDNS_LOG_DEBUG 0
108 #define EVDNS_LOG_WARN 1
110 #ifndef HOST_NAME_MAX
111 #define HOST_NAME_MAX 255
112 #endif
114 #ifndef NDEBUG
115 #include <stdio.h>
116 #endif
118 #undef MIN
119 #define MIN(a,b) ((a)<(b)?(a):(b))
121 #if 0
122 #ifdef __USE_ISOC99B
123 // libevent doesn't work without this
124 typedef uint8_t u_char;
125 typedef unsigned int uint;
126 #endif
127 #endif
128 #include <event.h>
130 #define u64 uint64_t
131 #define u32 uint32_t
132 #define u16 uint16_t
133 #define u8 uint8_t
135 #define MAX_ADDRS 4 // maximum number of addresses from a single packet
136 // which we bother recording
138 #define TYPE_A EVDNS_TYPE_A
139 #define TYPE_PTR EVDNS_TYPE_PTR
140 #define TYPE_AAAA EVDNS_TYPE_AAAA
142 #define CLASS_INET EVDNS_CLASS_INET
144 #define CLEAR(x) do { memset((x), 0, sizeof(*(x))); } while(0)
146 struct request {
147 u8 *request; // the dns packet data
148 unsigned int request_len;
149 int reissue_count;
150 int tx_count; // the number of times that this packet has been sent
151 unsigned int request_type; // TYPE_PTR or TYPE_A
152 void *user_pointer; // the pointer given to us for this request
153 evdns_callback_type user_callback;
154 struct nameserver *ns; // the server which we last sent it
156 // elements used by the searching code
157 int search_index;
158 struct search_state *search_state;
159 char *search_origname; // needs to be free()ed
160 int search_flags;
162 // these objects are kept in a circular list
163 struct request *next, *prev;
165 struct event timeout_event;
167 u16 trans_id; // the transaction id
168 char request_appended; // true if the request pointer is data which follows this struct
169 char transmit_me; // needs to be transmitted
172 #ifndef HAVE_STRUCT_IN6_ADDR
173 struct in6_addr {
174 u8 s6_addr[16];
176 #endif
178 struct reply {
179 unsigned int type;
180 unsigned int have_answer;
181 union {
182 struct {
183 u32 addrcount;
184 u32 addresses[MAX_ADDRS];
185 } a;
186 struct {
187 u32 addrcount;
188 struct in6_addr addresses[MAX_ADDRS];
189 } aaaa;
190 struct {
191 char name[HOST_NAME_MAX];
192 } ptr;
193 } data;
196 struct nameserver {
197 int socket; // a connected UDP socket
198 u32 address;
199 int failed_times; // number of times which we have given this server a chance
200 int timedout; // number of times in a row a request has timed out
201 struct event event;
202 // these objects are kept in a circular list
203 struct nameserver *next, *prev;
204 struct event timeout_event; // used to keep the timeout for
205 // when we next probe this server.
206 // Valid if state == 0
207 char state; // zero if we think that this server is down
208 char choked; // true if we have an EAGAIN from this server's socket
209 char write_waiting; // true if we are waiting for EV_WRITE events
212 static struct request *req_head = NULL, *req_waiting_head = NULL;
213 static struct nameserver *server_head = NULL;
215 // Represents a local port where we're listening for DNS requests. Right now,
216 // only UDP is supported.
217 struct evdns_server_port {
218 int socket; // socket we use to read queries and write replies.
219 int refcnt; // reference count.
220 char choked; // Are we currently blocked from writing?
221 char closing; // Are we trying to close this port, pending writes?
222 evdns_request_callback_fn_type user_callback; // Fn to handle requests
223 void *user_data; // Opaque pointer passed to user_callback
224 struct event event; // Read/write event
225 // circular list of replies that we want to write.
226 struct server_request *pending_replies;
229 // Represents part of a reply being built. (That is, a single RR.)
230 struct server_reply_item {
231 struct server_reply_item *next; // next item in sequence.
232 char *name; // name part of the RR
233 u16 type : 16; // The RR type
234 u16 class : 16; // The RR class (usually CLASS_INET)
235 u32 ttl; // The RR TTL
236 char is_name; // True iff data is a label
237 u16 datalen; // Length of data; -1 if data is a label
238 void *data; // The contents of the RR
241 // Represents a request that we've received as a DNS server, and holds
242 // the components of the reply as we're constructing it.
243 struct server_request {
244 // Pointers to the next and previous entries on the list of replies
245 // that we're waiting to write. Only set if we have tried to respond
246 // and gotten EAGAIN.
247 struct server_request *next_pending;
248 struct server_request *prev_pending;
250 u16 trans_id; // Transaction id.
251 struct evdns_server_port *port; // Which port received this request on?
252 struct sockaddr_storage addr; // Where to send the response
253 socklen_t addrlen; // length of addr
255 int n_answer; // how many answer RRs have been set?
256 int n_authority; // how many authority RRs have been set?
257 int n_additional; // how many additional RRs have been set?
259 struct server_reply_item *answer; // linked list of answer RRs
260 struct server_reply_item *authority; // linked list of authority RRs
261 struct server_reply_item *additional; // linked list of additional RRs
263 // Constructed response. Only set once we're ready to send a reply.
264 // Once this is set, the RR fields are cleared, and no more should be set.
265 char *response;
266 size_t response_len;
268 // Caller-visible fields: flags, questions.
269 struct evdns_server_request base;
272 // helper macro
273 #define OFFSET_OF(st, member) ((off_t) (((char*)&((st*)0)->member)-(char*)0))
275 // Given a pointer to an evdns_server_request, get the corresponding
276 // server_request.
277 #define TO_SERVER_REQUEST(base_ptr) \
278 ((struct server_request*) \
279 (((char*)(base_ptr) - OFFSET_OF(struct server_request, base))))
281 // The number of good nameservers that we have
282 static int global_good_nameservers = 0;
284 // inflight requests are contained in the req_head list
285 // and are actually going out across the network
286 static int global_requests_inflight = 0;
287 // requests which aren't inflight are in the waiting list
288 // and are counted here
289 static int global_requests_waiting = 0;
291 static int global_max_requests_inflight = 64;
293 static struct timeval global_timeout = {5, 0}; // 5 seconds
294 static int global_max_reissues = 1; // a reissue occurs when we get some errors from the server
295 static int global_max_retransmits = 3; // number of times we'll retransmit a request which timed out
296 // number of timeouts in a row before we consider this server to be down
297 static int global_max_nameserver_timeout = 3;
299 // These are the timeout values for nameservers. If we find a nameserver is down
300 // we try to probe it at intervals as given below. Values are in seconds.
301 static const struct timeval global_nameserver_timeouts[] = {{10, 0}, {60, 0}, {300, 0}, {900, 0}, {3600, 0}};
302 static const int global_nameserver_timeouts_length = sizeof(global_nameserver_timeouts)/sizeof(struct timeval);
304 static const char *const evdns_error_strings[] = {"no error", "The name server was unable to interpret the query", "The name server suffered an internal error", "The requested domain name does not exist", "The name server refused to reply to the request"};
306 static struct nameserver *nameserver_pick(void);
307 static void evdns_request_insert(struct request *req, struct request **head);
308 static void nameserver_ready_callback(int fd, short events, void *arg);
309 static int evdns_transmit(void);
310 static int evdns_request_transmit(struct request *req);
311 static void nameserver_send_probe(struct nameserver *const ns);
312 static void search_request_finished(struct request *const);
313 static int search_try_next(struct request *const req);
314 static int search_request_new(int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg);
315 static void evdns_requests_pump_waiting_queue(void);
316 static u16 transaction_id_pick(void);
317 static struct request *request_new(int type, const char *name, int flags, evdns_callback_type callback, void *ptr);
318 static void request_submit(struct request *req);
320 static int server_request_free(struct server_request *req);
321 static void server_request_free_answers(struct server_request *req);
322 static void server_port_free(struct evdns_server_port *port);
323 static void server_port_ready_callback(int fd, short events, void *arg);
325 static int strtoint(const char *const str);
327 #ifdef WIN32
328 static int
329 last_error(int sock)
331 int optval, optvallen=sizeof(optval);
332 int err = WSAGetLastError();
333 if (err == WSAEWOULDBLOCK && sock >= 0) {
334 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
335 &optvallen))
336 return err;
337 if (optval)
338 return optval;
340 return err;
343 static int
344 error_is_eagain(int err)
346 return err == EAGAIN || err == WSAEWOULDBLOCK;
348 static int
349 inet_aton(const char *c, struct in_addr *addr)
351 uint32_t r;
352 if (strcmp(c, "255.255.255.255") == 0) {
353 addr->s_addr = 0xffffffffu;
354 } else {
355 r = inet_addr(c);
356 if (r == INADDR_NONE)
357 return 0;
358 addr->s_addr = r;
360 return 1;
362 #define CLOSE_SOCKET(x) closesocket(x)
363 #else
364 #define last_error(sock) (errno)
365 #define error_is_eagain(err) ((err) == EAGAIN)
366 #define CLOSE_SOCKET(x) close(x)
367 #endif
369 #define ISSPACE(c) isspace((int)(unsigned char)(c))
370 #define ISDIGIT(c) isdigit((int)(unsigned char)(c))
372 #ifndef NDEBUG
373 static const char *
374 debug_ntoa(u32 address)
376 static char buf[32];
377 u32 a = ntohl(address);
378 snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
379 (int)(u8)((a>>24)&0xff),
380 (int)(u8)((a>>16)&0xff),
381 (int)(u8)((a>>8 )&0xff),
382 (int)(u8)((a )&0xff));
383 return buf;
385 #endif
387 static evdns_debug_log_fn_type evdns_log_fn = NULL;
389 void
390 evdns_set_log_fn(evdns_debug_log_fn_type fn)
392 evdns_log_fn = fn;
395 #ifdef __GNUC__
396 #define EVDNS_LOG_CHECK __attribute__ ((format(printf, 2, 3)))
397 #else
398 #define EVDNS_LOG_CHECK
399 #endif
401 static void _evdns_log(int warn, const char *fmt, ...) EVDNS_LOG_CHECK;
402 static void
403 _evdns_log(int warn, const char *fmt, ...)
405 va_list args;
406 static char buf[512];
407 if (!evdns_log_fn)
408 return;
409 va_start(args,fmt);
410 #ifdef WIN32
411 _vsnprintf(buf, sizeof(buf), fmt, args);
412 #else
413 vsnprintf(buf, sizeof(buf), fmt, args);
414 #endif
415 buf[sizeof(buf)-1] = '\0';
416 evdns_log_fn(warn, buf);
417 va_end(args);
420 #define log _evdns_log
422 // This walks the list of inflight requests to find the
423 // one with a matching transaction id. Returns NULL on
424 // failure
425 static struct request *
426 request_find_from_trans_id(u16 trans_id) {
427 struct request *req = req_head, *const started_at = req_head;
429 if (req) {
430 do {
431 if (req->trans_id == trans_id) return req;
432 req = req->next;
433 } while (req != started_at);
436 return NULL;
439 // a libevent callback function which is called when a nameserver
440 // has gone down and we want to test if it has came back to life yet
441 static void
442 nameserver_prod_callback(int fd, short events, void *arg) {
443 struct nameserver *const ns = (struct nameserver *) arg;
444 (void)fd;
445 (void)events;
447 nameserver_send_probe(ns);
450 // a libevent callback which is called when a nameserver probe (to see if
451 // it has come back to life) times out. We increment the count of failed_times
452 // and wait longer to send the next probe packet.
453 static void
454 nameserver_probe_failed(struct nameserver *const ns) {
455 const struct timeval * timeout;
456 (void) evtimer_del(&ns->timeout_event);
457 CLEAR(&ns->timeout_event);
458 if (ns->state == 1) {
459 // This can happen if the nameserver acts in a way which makes us mark
460 // it as bad and then starts sending good replies.
461 return;
464 timeout =
465 &global_nameserver_timeouts[MIN(ns->failed_times,
466 global_nameserver_timeouts_length - 1)];
467 ns->failed_times++;
469 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
470 if (evtimer_add(&ns->timeout_event, (struct timeval *) timeout) < 0) {
471 log(EVDNS_LOG_WARN,
472 "Error from libevent when adding timer event for %s",
473 debug_ntoa(ns->address));
474 // ???? Do more?
478 // called when a nameserver has been deemed to have failed. For example, too
479 // many packets have timed out etc
480 static void
481 nameserver_failed(struct nameserver *const ns, const char *msg) {
482 struct request *req, *started_at;
483 // if this nameserver has already been marked as failed
484 // then don't do anything
485 if (!ns->state) return;
487 log(EVDNS_LOG_WARN, "Nameserver %s has failed: %s",
488 debug_ntoa(ns->address), msg);
489 global_good_nameservers--;
490 assert(global_good_nameservers >= 0);
491 if (global_good_nameservers == 0) {
492 log(EVDNS_LOG_WARN, "All nameservers have failed");
495 ns->state = 0;
496 ns->failed_times = 1;
498 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
499 if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
500 log(EVDNS_LOG_WARN,
501 "Error from libevent when adding timer event for %s",
502 debug_ntoa(ns->address));
503 // ???? Do more?
506 // walk the list of inflight requests to see if any can be reassigned to
507 // a different server. Requests in the waiting queue don't have a
508 // nameserver assigned yet
510 // if we don't have *any* good nameservers then there's no point
511 // trying to reassign requests to one
512 if (!global_good_nameservers) return;
514 req = req_head;
515 started_at = req_head;
516 if (req) {
517 do {
518 if (req->tx_count == 0 && req->ns == ns) {
519 // still waiting to go out, can be moved
520 // to another server
521 req->ns = nameserver_pick();
523 req = req->next;
524 } while (req != started_at);
528 static void
529 nameserver_up(struct nameserver *const ns) {
530 if (ns->state) return;
531 log(EVDNS_LOG_WARN, "Nameserver %s is back up",
532 debug_ntoa(ns->address));
533 evtimer_del(&ns->timeout_event);
534 CLEAR(&ns->timeout_event);
535 ns->state = 1;
536 ns->failed_times = 0;
537 ns->timedout = 0;
538 global_good_nameservers++;
541 static void
542 request_trans_id_set(struct request *const req, const u16 trans_id) {
543 req->trans_id = trans_id;
544 *((u16 *) req->request) = htons(trans_id);
547 // Called to remove a request from a list and dealloc it.
548 // head is a pointer to the head of the list it should be
549 // removed from or NULL if the request isn't in a list.
550 static void
551 request_finished(struct request *const req, struct request **head) {
552 if (head) {
553 if (req->next == req) {
554 // only item in the list
555 *head = NULL;
556 } else {
557 req->next->prev = req->prev;
558 req->prev->next = req->next;
559 if (*head == req) *head = req->next;
563 log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
564 (unsigned long) req);
565 evtimer_del(&req->timeout_event);
566 CLEAR(&req->timeout_event);
568 search_request_finished(req);
569 global_requests_inflight--;
571 if (!req->request_appended) {
572 // need to free the request data on it's own
573 free(req->request);
574 } else {
575 // the request data is appended onto the header
576 // so everything gets free()ed when we:
579 CLEAR(req);
580 free(req);
582 evdns_requests_pump_waiting_queue();
585 // This is called when a server returns a funny error code.
586 // We try the request again with another server.
588 // return:
589 // 0 ok
590 // 1 failed/reissue is pointless
591 static int
592 request_reissue(struct request *req) {
593 const struct nameserver *const last_ns = req->ns;
594 // the last nameserver should have been marked as failing
595 // by the caller of this function, therefore pick will try
596 // not to return it
597 req->ns = nameserver_pick();
598 if (req->ns == last_ns) {
599 // ... but pick did return it
600 // not a lot of point in trying again with the
601 // same server
602 return 1;
605 req->reissue_count++;
606 req->tx_count = 0;
607 req->transmit_me = 1;
609 return 0;
612 // this function looks for space on the inflight queue and promotes
613 // requests from the waiting queue if it can.
614 static void
615 evdns_requests_pump_waiting_queue(void) {
616 while (global_requests_inflight < global_max_requests_inflight &&
617 global_requests_waiting) {
618 struct request *req;
619 // move a request from the waiting queue to the inflight queue
620 assert(req_waiting_head);
621 if (req_waiting_head->next == req_waiting_head) {
622 // only one item in the queue
623 req = req_waiting_head;
624 req_waiting_head = NULL;
625 } else {
626 req = req_waiting_head;
627 req->next->prev = req->prev;
628 req->prev->next = req->next;
629 req_waiting_head = req->next;
632 global_requests_waiting--;
633 global_requests_inflight++;
635 req->ns = nameserver_pick();
636 request_trans_id_set(req, transaction_id_pick());
638 evdns_request_insert(req, &req_head);
639 evdns_request_transmit(req);
640 evdns_transmit();
644 static void
645 reply_callback(struct request *const req, u32 ttl, u32 err, struct reply *reply) {
646 switch (req->request_type) {
647 case TYPE_A:
648 if (reply)
649 req->user_callback(DNS_ERR_NONE, DNS_IPv4_A,
650 reply->data.a.addrcount, ttl,
651 reply->data.a.addresses,
652 req->user_pointer);
653 else
654 req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
655 return;
656 case TYPE_PTR:
657 if (reply) {
658 char *name = reply->data.ptr.name;
659 req->user_callback(DNS_ERR_NONE, DNS_PTR, 1, ttl,
660 &name, req->user_pointer);
661 } else {
662 req->user_callback(err, 0, 0, 0, NULL,
663 req->user_pointer);
665 return;
666 case TYPE_AAAA:
667 if (reply)
668 req->user_callback(DNS_ERR_NONE, DNS_IPv6_AAAA,
669 reply->data.aaaa.addrcount, ttl,
670 reply->data.aaaa.addresses,
671 req->user_pointer);
672 else
673 req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
674 return;
676 assert(0);
679 // this processes a parsed reply packet
680 static void
681 reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply) {
682 int error;
683 static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED};
685 if (flags & 0x020f || !reply || !reply->have_answer) {
686 // there was an error
687 if (flags & 0x0200) {
688 error = DNS_ERR_TRUNCATED;
689 } else {
690 u16 error_code = (flags & 0x000f) - 1;
691 if (error_code > 4) {
692 error = DNS_ERR_UNKNOWN;
693 } else {
694 error = error_codes[error_code];
698 switch(error) {
699 case DNS_ERR_NOTIMPL:
700 case DNS_ERR_REFUSED:
701 // we regard these errors as marking a bad nameserver
702 if (req->reissue_count < global_max_reissues) {
703 char msg[64];
704 snprintf(msg, sizeof(msg), "Bad response %d (%s)",
705 error, evdns_err_to_string(error));
706 nameserver_failed(req->ns, msg);
707 if (!request_reissue(req)) return;
709 break;
710 case DNS_ERR_SERVERFAILED:
711 // rcode 2 (servfailed) sometimes means "we are broken" and
712 // sometimes (with some binds) means "that request was very
713 // confusing." Treat this as a timeout, not a failure.
714 /*XXXX refactor the parts of */
715 log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
716 "will allow the request to time out.",
717 debug_ntoa(req->ns->address));
718 break;
719 default:
720 // we got a good reply from the nameserver
721 nameserver_up(req->ns);
724 if (req->search_state && req->request_type != TYPE_PTR) {
725 // if we have a list of domains to search in, try the next one
726 if (!search_try_next(req)) {
727 // a new request was issued so this request is finished and
728 // the user callback will be made when that request (or a
729 // child of it) finishes.
730 request_finished(req, &req_head);
731 return;
735 // all else failed. Pass the failure up
736 reply_callback(req, 0, error, NULL);
737 request_finished(req, &req_head);
738 } else {
739 // all ok, tell the user
740 reply_callback(req, ttl, 0, reply);
741 nameserver_up(req->ns);
742 request_finished(req, &req_head);
746 static inline int
747 name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
748 int name_end = -1;
749 int j = *idx;
750 int ptr_count = 0;
751 #define GET32(x) do { if (j + 4 > length) goto err; memcpy(&_t32, packet + j, 4); j += 4; x = ntohl(_t32); } while(0);
752 #define GET16(x) do { if (j + 2 > length) goto err; memcpy(&_t, packet + j, 2); j += 2; x = ntohs(_t); } while(0);
753 #define GET8(x) do { if (j >= length) goto err; x = packet[j++]; } while(0);
755 char *cp = name_out;
756 const char *const end = name_out + name_out_len;
758 // Normally, names are a series of length prefixed strings terminated
759 // with a length of 0 (the lengths are u8's < 63).
760 // However, the length can start with a pair of 1 bits and that
761 // means that the next 14 bits are a pointer within the current
762 // packet.
764 for(;;) {
765 u8 label_len;
766 if (j >= length) return -1;
767 GET8(label_len);
768 if (!label_len) break;
769 if (label_len & 0xc0) {
770 u8 ptr_low;
771 GET8(ptr_low);
772 if (name_end < 0) name_end = j;
773 j = (((int)label_len & 0x3f) << 8) + ptr_low;
774 /* Make sure that the target offset is in-bounds. */
775 if (j < 0 || j >= length) return -1;
776 /* If we've jumped more times than there are characters in the
777 * message, we must have a loop. */
778 if (++ptr_count > length) return -1;
779 continue;
781 if (label_len > 63) return -1;
782 if (cp != name_out) {
783 if (cp + 1 >= end) return -1;
784 *cp++ = '.';
786 if (cp + label_len >= end) return -1;
787 memcpy(cp, packet + j, label_len);
788 cp += label_len;
789 j += label_len;
791 if (cp >= end) return -1;
792 *cp = '\0';
793 if (name_end < 0)
794 *idx = j;
795 else
796 *idx = name_end;
797 return 0;
798 err:
799 return -1;
802 // parses a raw reply from a nameserver.
803 static int
804 reply_parse(u8 *packet, int length) {
805 int j = 0; // index into packet
806 u16 _t; // used by the macros
807 u32 _t32; // used by the macros
808 char tmp_name[256]; // used by the macros
810 u16 trans_id, questions, answers, authority, additional, datalength;
811 u16 flags = 0;
812 u32 ttl, ttl_r = 0xffffffff;
813 struct reply reply;
814 struct request *req = NULL;
815 unsigned int i;
817 GET16(trans_id);
818 GET16(flags);
819 GET16(questions);
820 GET16(answers);
821 GET16(authority);
822 GET16(additional);
823 (void) authority; /* suppress "unused variable" warnings. */
824 (void) additional; /* suppress "unused variable" warnings. */
826 req = request_find_from_trans_id(trans_id);
827 /* if no request, can't do anything. */
828 if (!req) return -1;
830 memset(&reply, 0, sizeof(reply));
832 /* if not an answer, it doesn't go with any of our requests. */
833 if (!(flags & 0x8000)) return -1; // must be an answer
834 if (flags & 0x020f) {
835 // there was an error
836 goto err;
838 // if (!answers) return; // must have an answer of some form
840 // This macro skips a name in the DNS reply.
841 #define SKIP_NAME \
842 do { tmp_name[0] = '\0'; \
843 if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0) \
844 goto err; \
845 } while(0);
847 reply.type = req->request_type;
849 // skip over each question in the reply
850 for (i = 0; i < questions; ++i) {
851 // the question looks like
852 // <label:name><u16:type><u16:class>
853 SKIP_NAME;
854 j += 4;
855 if (j >= length) goto err;
858 // now we have the answer section which looks like
859 // <label:name><u16:type><u16:class><u32:ttl><u16:len><data...>
861 for (i = 0; i < answers; ++i) {
862 u16 type, class;
864 // XXX I'd be more comfortable if we actually checked the name
865 // here. -NM
866 SKIP_NAME;
867 GET16(type);
868 GET16(class);
869 GET32(ttl);
870 GET16(datalength);
872 if (type == TYPE_A && class == CLASS_INET) {
873 int addrcount, addrtocopy;
874 if (req->request_type != TYPE_A) {
875 j += datalength; continue;
877 if ((datalength & 3) != 0) /* not an even number of As. */
878 goto err;
879 addrcount = datalength >> 2;
880 addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
882 ttl_r = MIN(ttl_r, ttl);
883 // we only bother with the first four addresses.
884 if (j + 4*addrtocopy > length) goto err;
885 memcpy(&reply.data.a.addresses[reply.data.a.addrcount],
886 packet + j, 4*addrtocopy);
887 j += 4*addrtocopy;
888 reply.data.a.addrcount += addrtocopy;
889 reply.have_answer = 1;
890 if (reply.data.a.addrcount == MAX_ADDRS) break;
891 } else if (type == TYPE_PTR && class == CLASS_INET) {
892 if (req->request_type != TYPE_PTR) {
893 j += datalength; continue;
895 if (name_parse(packet, length, &j, reply.data.ptr.name,
896 sizeof(reply.data.ptr.name))<0)
897 goto err;
898 ttl_r = MIN(ttl_r, ttl);
899 reply.have_answer = 1;
900 break;
901 } else if (type == TYPE_AAAA && class == CLASS_INET) {
902 int addrcount, addrtocopy;
903 if (req->request_type != TYPE_AAAA) {
904 j += datalength; continue;
906 if ((datalength & 15) != 0) /* not an even number of AAAAs. */
907 goto err;
908 addrcount = datalength >> 4; // each address is 16 bytes long
909 addrtocopy = MIN(MAX_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount);
910 ttl_r = MIN(ttl_r, ttl);
912 // we only bother with the first four addresses.
913 if (j + 16*addrtocopy > length) goto err;
914 memcpy(&reply.data.aaaa.addresses[reply.data.aaaa.addrcount],
915 packet + j, 16*addrtocopy);
916 reply.data.aaaa.addrcount += addrtocopy;
917 j += 16*addrtocopy;
918 reply.have_answer = 1;
919 if (reply.data.aaaa.addrcount == MAX_ADDRS) break;
920 } else {
921 // skip over any other type of resource
922 j += datalength;
926 reply_handle(req, flags, ttl_r, &reply);
927 return 0;
928 err:
929 if (req)
930 reply_handle(req, flags, 0, NULL);
931 return -1;
934 // Parse a raw request (packet,length) sent to a nameserver port (port) from
935 // a DNS client (addr,addrlen), and if it's well-formed, call the corresponding
936 // callback.
937 static int
938 request_parse(u8 *packet, int length, struct evdns_server_port *port, struct sockaddr *addr, socklen_t addrlen)
940 int j = 0; // index into packet
941 u16 _t; // used by the macros
942 char tmp_name[256]; // used by the macros
944 int i;
945 u16 trans_id, flags, questions, answers, authority, additional;
946 struct server_request *server_req = NULL;
948 // Get the header fields
949 GET16(trans_id);
950 GET16(flags);
951 GET16(questions);
952 GET16(answers);
953 GET16(authority);
954 GET16(additional);
956 if (flags & 0x8000) return -1; // Must not be an answer.
957 if (flags & 0x7800) return -1; // only standard queries are supported
958 flags &= 0x0300; // Only TC and RD get preserved.
960 server_req = malloc(sizeof(struct server_request));
961 if (server_req == NULL) return -1;
962 memset(server_req, 0, sizeof(struct server_request));
964 server_req->trans_id = trans_id;
965 memcpy(&server_req->addr, addr, addrlen);
966 server_req->addrlen = addrlen;
968 server_req->base.flags = flags;
969 server_req->base.nquestions = 0;
970 server_req->base.questions = malloc(sizeof(struct evdns_server_question *) * questions);
971 if (server_req->base.questions == NULL)
972 goto err;
974 for (i = 0; i < questions; ++i) {
975 u16 type, class;
976 struct evdns_server_question *q;
977 int namelen;
978 if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)
979 goto err;
980 GET16(type);
981 GET16(class);
982 namelen = strlen(tmp_name);
983 q = malloc(sizeof(struct evdns_server_question) + namelen);
984 if (!q)
985 goto err;
986 q->type = type;
987 q->class = class;
988 memcpy(q->name, tmp_name, namelen+1);
989 server_req->base.questions[server_req->base.nquestions++] = q;
992 // Ignore answers, authority, and additional.
994 server_req->port = port;
995 port->refcnt++;
996 port->user_callback(&(server_req->base), port->user_data);
998 return 0;
999 err:
1000 if (server_req) {
1001 if (server_req->base.questions) {
1002 for (i = 0; i < server_req->base.nquestions; ++i)
1003 free(server_req->base.questions[i]);
1004 free(server_req->base.questions);
1006 CLEAR(server_req);
1007 free(server_req);
1009 return -1;
1011 #undef SKIP_NAME
1012 #undef GET32
1013 #undef GET16
1014 #undef GET8
1017 // Try to choose a strong transaction id which isn't already in flight
1018 static u16
1019 transaction_id_pick(void) {
1020 for (;;) {
1021 const struct request *req = req_head, *started_at;
1022 #ifdef DNS_USE_CPU_CLOCK_FOR_ID
1023 struct timespec ts;
1024 u16 trans_id;
1025 #ifdef CLOCK_MONOTONIC
1026 if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
1027 #else
1028 if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
1029 #endif
1030 event_err(1, "clock_gettime");
1031 trans_id = ts.tv_nsec & 0xffff;
1032 #endif
1034 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
1035 struct timeval tv;
1036 u16 trans_id;
1037 gettimeofday(&tv, NULL);
1038 trans_id = tv.tv_usec & 0xffff;
1039 #endif
1041 #ifdef DNS_USE_OPENSSL_FOR_ID
1042 u16 trans_id;
1043 if (RAND_pseudo_bytes((u8 *) &trans_id, 2) == -1) {
1044 /* // in the case that the RAND call fails we back
1045 // down to using gettimeofday.
1046 struct timeval tv;
1047 gettimeofday(&tv, NULL);
1048 trans_id = tv.tv_usec & 0xffff; */
1049 abort();
1051 #endif
1053 if (trans_id == 0xffff) continue;
1054 // now check to see if that id is already inflight
1055 req = started_at = req_head;
1056 if (req) {
1057 do {
1058 if (req->trans_id == trans_id) break;
1059 req = req->next;
1060 } while (req != started_at);
1062 // we didn't find it, so this is a good id
1063 if (req == started_at) return trans_id;
1067 // choose a namesever to use. This function will try to ignore
1068 // nameservers which we think are down and load balance across the rest
1069 // by updating the server_head global each time.
1070 static struct nameserver *
1071 nameserver_pick(void) {
1072 struct nameserver *started_at = server_head, *picked;
1073 if (!server_head) return NULL;
1075 // if we don't have any good nameservers then there's no
1076 // point in trying to find one.
1077 if (!global_good_nameservers) {
1078 server_head = server_head->next;
1079 return server_head;
1082 // remember that nameservers are in a circular list
1083 for (;;) {
1084 if (server_head->state) {
1085 // we think this server is currently good
1086 picked = server_head;
1087 server_head = server_head->next;
1088 return picked;
1091 server_head = server_head->next;
1092 if (server_head == started_at) {
1093 // all the nameservers seem to be down
1094 // so we just return this one and hope for the
1095 // best
1096 assert(global_good_nameservers == 0);
1097 picked = server_head;
1098 server_head = server_head->next;
1099 return picked;
1104 // this is called when a namesever socket is ready for reading
1105 static void
1106 nameserver_read(struct nameserver *ns) {
1107 u8 packet[1500];
1109 for (;;) {
1110 const int r = recv(ns->socket, packet, sizeof(packet), 0);
1111 if (r < 0) {
1112 int err = last_error(ns->socket);
1113 if (error_is_eagain(err)) return;
1114 nameserver_failed(ns, strerror(err));
1115 return;
1117 ns->timedout = 0;
1118 reply_parse(packet, r);
1122 // Read a packet from a DNS client on a server port s, parse it, and
1123 // act accordingly.
1124 static void
1125 server_port_read(struct evdns_server_port *s) {
1126 u8 packet[1500];
1127 struct sockaddr_storage addr;
1128 socklen_t addrlen;
1129 int r;
1131 for (;;) {
1132 addrlen = sizeof(struct sockaddr_storage);
1133 r = recvfrom(s->socket, packet, sizeof(packet), 0,
1134 (struct sockaddr*) &addr, &addrlen);
1135 if (r < 0) {
1136 int err = last_error(s->socket);
1137 if (error_is_eagain(err)) return;
1138 log(EVDNS_LOG_WARN, "Error %s (%d) while reading request.",
1139 strerror(err), err);
1140 return;
1142 request_parse(packet, r, s, (struct sockaddr*) &addr, addrlen);
1146 // Try to write all pending replies on a given DNS server port.
1147 static void
1148 server_port_flush(struct evdns_server_port *port)
1150 while (port->pending_replies) {
1151 struct server_request *req = port->pending_replies;
1152 int r = sendto(port->socket, req->response, req->response_len, 0,
1153 (struct sockaddr*) &req->addr, req->addrlen);
1154 if (r < 0) {
1155 int err = last_error(port->socket);
1156 if (error_is_eagain(err))
1157 return;
1158 log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", strerror(err), err);
1160 if (server_request_free(req)) {
1161 // we released the last reference to req->port.
1162 return;
1166 // We have no more pending requests; stop listening for 'writeable' events.
1167 (void) event_del(&port->event);
1168 CLEAR(&port->event);
1169 event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
1170 server_port_ready_callback, port);
1171 if (event_add(&port->event, NULL) < 0) {
1172 log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server.");
1173 // ???? Do more?
1177 // set if we are waiting for the ability to write to this server.
1178 // if waiting is true then we ask libevent for EV_WRITE events, otherwise
1179 // we stop these events.
1180 static void
1181 nameserver_write_waiting(struct nameserver *ns, char waiting) {
1182 if (ns->write_waiting == waiting) return;
1184 ns->write_waiting = waiting;
1185 (void) event_del(&ns->event);
1186 CLEAR(&ns->event);
1187 event_set(&ns->event, ns->socket, EV_READ | (waiting ? EV_WRITE : 0) | EV_PERSIST,
1188 nameserver_ready_callback, ns);
1189 if (event_add(&ns->event, NULL) < 0) {
1190 log(EVDNS_LOG_WARN, "Error from libevent when adding event for %s",
1191 debug_ntoa(ns->address));
1192 // ???? Do more?
1196 // a callback function. Called by libevent when the kernel says that
1197 // a nameserver socket is ready for writing or reading
1198 static void
1199 nameserver_ready_callback(int fd, short events, void *arg) {
1200 struct nameserver *ns = (struct nameserver *) arg;
1201 (void)fd;
1203 if (events & EV_WRITE) {
1204 ns->choked = 0;
1205 if (!evdns_transmit()) {
1206 nameserver_write_waiting(ns, 0);
1209 if (events & EV_READ) {
1210 nameserver_read(ns);
1214 // a callback function. Called by libevent when the kernel says that
1215 // a server socket is ready for writing or reading.
1216 static void
1217 server_port_ready_callback(int fd, short events, void *arg) {
1218 struct evdns_server_port *port = (struct evdns_server_port *) arg;
1219 (void) fd;
1221 if (events & EV_WRITE) {
1222 port->choked = 0;
1223 server_port_flush(port);
1225 if (events & EV_READ) {
1226 server_port_read(port);
1230 /* This is an inefficient representation; only use it via the dnslabel_table_*
1231 * functions, so that is can be safely replaced with something smarter later. */
1232 #define MAX_LABELS 128
1233 // Structures used to implement name compression
1234 struct dnslabel_entry { char *v; int pos; };
1235 struct dnslabel_table {
1236 int n_labels; // number of current entries
1237 // map from name to position in message
1238 struct dnslabel_entry labels[MAX_LABELS];
1241 // Initialize dnslabel_table.
1242 static void
1243 dnslabel_table_init(struct dnslabel_table *table)
1245 table->n_labels = 0;
1248 // Free all storage held by table, but not the table itself.
1249 static void
1250 dnslabel_clear(struct dnslabel_table *table)
1252 int i;
1253 for (i = 0; i < table->n_labels; ++i)
1254 free(table->labels[i].v);
1255 table->n_labels = 0;
1258 // return the position of the label in the current message, or -1 if the label
1259 // hasn't been used yet.
1260 static int
1261 dnslabel_table_get_pos(const struct dnslabel_table *table, const char *label)
1263 int i;
1264 for (i = 0; i < table->n_labels; ++i) {
1265 if (!strcmp(label, table->labels[i].v))
1266 return table->labels[i].pos;
1268 return -1;
1271 // remember that we've used the label at position pos
1272 static int
1273 dnslabel_table_add(struct dnslabel_table *table, const char *label, int pos)
1275 char *v;
1276 int p;
1277 if (table->n_labels == MAX_LABELS)
1278 return (-1);
1279 v = strdup(label);
1280 if (v == NULL)
1281 return (-1);
1282 p = table->n_labels++;
1283 table->labels[p].v = v;
1284 table->labels[p].pos = pos;
1286 return (0);
1289 // Converts a string to a length-prefixed set of DNS labels, starting
1290 // at buf[j]. name and buf must not overlap. name_len should be the length
1291 // of name. table is optional, and is used for compression.
1293 // Input: abc.def
1294 // Output: <3>abc<3>def<0>
1296 // Returns the first index after the encoded name, or negative on error.
1297 // -1 label was > 63 bytes
1298 // -2 name too long to fit in buffer.
1300 static off_t
1301 dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j,
1302 const char *name, const int name_len,
1303 struct dnslabel_table *table) {
1304 const char *end = name + name_len;
1305 int ref = 0;
1306 u16 _t;
1308 #define APPEND16(x) do { \
1309 if (j + 2 > (off_t)buf_len) \
1310 goto overflow; \
1311 _t = htons(x); \
1312 memcpy(buf + j, &_t, 2); \
1313 j += 2; \
1314 } while (0)
1315 #define APPEND32(x) do { \
1316 if (j + 4 > (off_t)buf_len) \
1317 goto overflow; \
1318 _t32 = htonl(x); \
1319 memcpy(buf + j, &_t32, 4); \
1320 j += 4; \
1321 } while (0)
1323 if (name_len > 255) return -2;
1325 for (;;) {
1326 const char *const start = name;
1327 if (table && (ref = dnslabel_table_get_pos(table, name)) >= 0) {
1328 APPEND16(ref | 0xc000);
1329 return j;
1331 name = strchr(name, '.');
1332 if (!name) {
1333 const unsigned int label_len = end - start;
1334 if (label_len > 63) return -1;
1335 if ((size_t)(j+label_len+1) > buf_len) return -2;
1336 if (table) dnslabel_table_add(table, start, j);
1337 buf[j++] = label_len;
1339 memcpy(buf + j, start, end - start);
1340 j += end - start;
1341 break;
1342 } else {
1343 // append length of the label.
1344 const unsigned int label_len = name - start;
1345 if (label_len > 63) return -1;
1346 if ((size_t)(j+label_len+1) > buf_len) return -2;
1347 if (table) dnslabel_table_add(table, start, j);
1348 buf[j++] = label_len;
1350 memcpy(buf + j, start, name - start);
1351 j += name - start;
1352 // hop over the '.'
1353 name++;
1357 // the labels must be terminated by a 0.
1358 // It's possible that the name ended in a .
1359 // in which case the zero is already there
1360 if (!j || buf[j-1]) buf[j++] = 0;
1361 return j;
1362 overflow:
1363 return (-2);
1366 // Finds the length of a dns request for a DNS name of the given
1367 // length. The actual request may be smaller than the value returned
1368 // here
1369 static int
1370 evdns_request_len(const int name_len) {
1371 return 96 + // length of the DNS standard header
1372 name_len + 2 +
1373 4; // space for the resource type
1376 // build a dns request packet into buf. buf should be at least as long
1377 // as evdns_request_len told you it should be.
1379 // Returns the amount of space used. Negative on error.
1380 static int
1381 evdns_request_data_build(const char *const name, const int name_len,
1382 const u16 trans_id, const u16 type, const u16 class,
1383 u8 *const buf, size_t buf_len) {
1384 off_t j = 0; // current offset into buf
1385 u16 _t; // used by the macros
1387 APPEND16(trans_id);
1388 APPEND16(0x0100); // standard query, recusion needed
1389 APPEND16(1); // one question
1390 APPEND16(0); // no answers
1391 APPEND16(0); // no authority
1392 APPEND16(0); // no additional
1394 j = dnsname_to_labels(buf, buf_len, j, name, name_len, NULL);
1395 if (j < 0) {
1396 return (int)j;
1399 APPEND16(type);
1400 APPEND16(class);
1402 return (int)j;
1403 overflow:
1404 return (-1);
1407 // exported function
1408 struct evdns_server_port *
1409 evdns_add_server_port(int socket, int is_tcp, evdns_request_callback_fn_type cb, void *user_data)
1411 struct evdns_server_port *port;
1412 if (!(port = malloc(sizeof(struct evdns_server_port))))
1413 return NULL;
1414 memset(port, 0, sizeof(struct evdns_server_port));
1416 assert(!is_tcp); // TCP sockets not yet implemented
1417 port->socket = socket;
1418 port->refcnt = 1;
1419 port->choked = 0;
1420 port->closing = 0;
1421 port->user_callback = cb;
1422 port->user_data = user_data;
1423 port->pending_replies = NULL;
1425 event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
1426 server_port_ready_callback, port);
1427 event_add(&port->event, NULL); // check return.
1428 return port;
1431 // exported function
1432 void
1433 evdns_close_server_port(struct evdns_server_port *port)
1435 if (--port->refcnt == 0)
1436 server_port_free(port);
1437 port->closing = 1;
1440 // exported function
1442 evdns_server_request_add_reply(struct evdns_server_request *_req, int section, const char *name, int type, int class, int ttl, int datalen, int is_name, const char *data)
1444 struct server_request *req = TO_SERVER_REQUEST(_req);
1445 struct server_reply_item **itemp, *item;
1446 int *countp;
1448 if (req->response) /* have we already answered? */
1449 return (-1);
1451 switch (section) {
1452 case EVDNS_ANSWER_SECTION:
1453 itemp = &req->answer;
1454 countp = &req->n_answer;
1455 break;
1456 case EVDNS_AUTHORITY_SECTION:
1457 itemp = &req->authority;
1458 countp = &req->n_authority;
1459 break;
1460 case EVDNS_ADDITIONAL_SECTION:
1461 itemp = &req->additional;
1462 countp = &req->n_additional;
1463 break;
1464 default:
1465 return (-1);
1467 while (*itemp) {
1468 itemp = &((*itemp)->next);
1470 item = malloc(sizeof(struct server_reply_item));
1471 if (!item)
1472 return -1;
1473 CLEAR(item);
1474 item->next = NULL;
1475 if (!(item->name = strdup(name))) {
1476 CLEAR(item);
1477 free(item);
1478 return -1;
1480 item->type = type;
1481 item->class = class;
1482 item->ttl = ttl;
1483 item->is_name = is_name != 0;
1484 item->datalen = 0;
1485 item->data = NULL;
1486 if (data) {
1487 if (item->is_name) {
1488 if (!(item->data = strdup(data))) {
1489 free(item->name);
1490 CLEAR(item);
1491 free(item);
1492 return -1;
1494 item->datalen = -1;
1495 } else {
1496 if (!(item->data = malloc(datalen))) {
1497 free(item->name);
1498 CLEAR(item);
1499 free(item);
1500 return -1;
1502 item->datalen = datalen;
1503 memcpy(item->data, data, datalen);
1507 *itemp = item;
1508 ++(*countp);
1509 return 0;
1512 // exported function
1514 evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
1516 return evdns_server_request_add_reply(
1517 req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
1518 ttl, n*4, 0, addrs);
1521 // exported function
1523 evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
1525 return evdns_server_request_add_reply(
1526 req, EVDNS_ANSWER_SECTION, name, TYPE_AAAA, CLASS_INET,
1527 ttl, n*16, 0, addrs);
1530 // exported function
1532 evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl)
1534 u32 a;
1535 char buf[32];
1536 assert(in || inaddr_name);
1537 assert(!(in && inaddr_name));
1538 if (in) {
1539 a = ntohl(in->s_addr);
1540 snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
1541 (int)(u8)((a )&0xff),
1542 (int)(u8)((a>>8 )&0xff),
1543 (int)(u8)((a>>16)&0xff),
1544 (int)(u8)((a>>24)&0xff));
1545 inaddr_name = buf;
1547 return evdns_server_request_add_reply(
1548 req, EVDNS_ANSWER_SECTION, inaddr_name, TYPE_PTR, CLASS_INET,
1549 ttl, -1, 1, hostname);
1552 // exported function
1554 evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl)
1556 return evdns_server_request_add_reply(
1557 req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
1558 ttl, -1, 1, cname);
1562 static int
1563 evdns_server_request_format_response(struct server_request *req, int err)
1565 unsigned char buf[1500];
1566 size_t buf_len = sizeof(buf);
1567 off_t j = 0, r;
1568 u16 _t;
1569 u32 _t32;
1570 int i;
1571 u16 flags;
1572 struct dnslabel_table table;
1574 if (err < 0 || err > 15) return -1;
1576 /* Set response bit and error code; copy OPCODE and RD fields from
1577 * question; copy RA and AA if set by caller. */
1578 flags = req->base.flags;
1579 flags |= (0x8000 | err);
1581 dnslabel_table_init(&table);
1582 APPEND16(req->trans_id);
1583 APPEND16(flags);
1584 APPEND16(req->base.nquestions);
1585 APPEND16(req->n_answer);
1586 APPEND16(req->n_authority);
1587 APPEND16(req->n_additional);
1589 /* Add questions. */
1590 for (i=0; i < req->base.nquestions; ++i) {
1591 const char *s = req->base.questions[i]->name;
1592 j = dnsname_to_labels(buf, buf_len, j, s, strlen(s), &table);
1593 if (j < 0) {
1594 dnslabel_clear(&table);
1595 return (int) j;
1597 APPEND16(req->base.questions[i]->type);
1598 APPEND16(req->base.questions[i]->class);
1601 /* Add answer, authority, and additional sections. */
1602 for (i=0; i<3; ++i) {
1603 struct server_reply_item *item;
1604 if (i==0)
1605 item = req->answer;
1606 else if (i==1)
1607 item = req->authority;
1608 else
1609 item = req->additional;
1610 while (item) {
1611 r = dnsname_to_labels(buf, buf_len, j, item->name, strlen(item->name), &table);
1612 if (r < 0)
1613 goto overflow;
1614 j = r;
1616 APPEND16(item->type);
1617 APPEND16(item->class);
1618 APPEND32(item->ttl);
1619 if (item->is_name) {
1620 off_t len_idx = j, name_start;
1621 j += 2;
1622 name_start = j;
1623 r = dnsname_to_labels(buf, buf_len, j, item->data, strlen(item->data), &table);
1624 if (r < 0)
1625 goto overflow;
1626 j = r;
1627 _t = htons( (j-name_start) );
1628 memcpy(buf+len_idx, &_t, 2);
1629 } else {
1630 APPEND16(item->datalen);
1631 if (j+item->datalen > (off_t)buf_len)
1632 goto overflow;
1633 memcpy(buf+j, item->data, item->datalen);
1634 j += item->datalen;
1636 item = item->next;
1640 if (j > 512) {
1641 overflow:
1642 j = 512;
1643 buf[3] |= 0x02; /* set the truncated bit. */
1646 req->response_len = j;
1648 if (!(req->response = malloc(req->response_len))) {
1649 server_request_free_answers(req);
1650 dnslabel_clear(&table);
1651 return (-1);
1653 memcpy(req->response, buf, req->response_len);
1654 server_request_free_answers(req);
1655 dnslabel_clear(&table);
1656 return (0);
1659 // exported function
1661 evdns_server_request_respond(struct evdns_server_request *_req, int err)
1663 struct server_request *req = TO_SERVER_REQUEST(_req);
1664 struct evdns_server_port *port = req->port;
1665 int r;
1666 if (!req->response) {
1667 if ((r = evdns_server_request_format_response(req, err))<0)
1668 return r;
1671 r = sendto(port->socket, req->response, req->response_len, 0,
1672 (struct sockaddr*) &req->addr, req->addrlen);
1673 if (r<0) {
1674 int err = last_error(port->socket);
1675 if (! error_is_eagain(err))
1676 return -1;
1678 if (port->pending_replies) {
1679 req->prev_pending = port->pending_replies->prev_pending;
1680 req->next_pending = port->pending_replies;
1681 req->prev_pending->next_pending =
1682 req->next_pending->prev_pending = req;
1683 } else {
1684 req->prev_pending = req->next_pending = req;
1685 port->pending_replies = req;
1686 port->choked = 1;
1688 (void) event_del(&port->event);
1689 CLEAR(&port->event);
1690 event_set(&port->event, port->socket, (port->closing?0:EV_READ) | EV_WRITE | EV_PERSIST, server_port_ready_callback, port);
1692 if (event_add(&port->event, NULL) < 0) {
1693 log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server");
1698 return 1;
1700 if (server_request_free(req))
1701 return 0;
1703 if (req->port->pending_replies)
1704 server_port_flush(port);
1706 return 0;
1709 // Free all storage held by RRs in req.
1710 static void
1711 server_request_free_answers(struct server_request *req)
1713 struct server_reply_item *victim, *next, **list;
1714 int i;
1715 for (i = 0; i < 3; ++i) {
1716 if (i==0)
1717 list = &req->answer;
1718 else if (i==1)
1719 list = &req->authority;
1720 else
1721 list = &req->additional;
1723 victim = *list;
1724 while (victim) {
1725 next = victim->next;
1726 free(victim->name);
1727 if (victim->data)
1728 free(victim->data);
1729 /* XXXX free(victim?) -NM */
1730 victim = next;
1732 *list = NULL;
1736 // Free all storage held by req, and remove links to it.
1737 // return true iff we just wound up freeing the server_port.
1738 static int
1739 server_request_free(struct server_request *req)
1741 int i, rc=1;
1742 if (req->base.questions) {
1743 for (i = 0; i < req->base.nquestions; ++i)
1744 free(req->base.questions[i]);
1747 if (req->port) {
1748 if (req->port->pending_replies == req) {
1749 if (req->next_pending)
1750 req->port->pending_replies = req->next_pending;
1751 else
1752 req->port->pending_replies = NULL;
1754 rc = --req->port->refcnt;
1757 if (req->response) {
1758 free(req->response);
1761 server_request_free_answers(req);
1763 if (req->next_pending && req->next_pending != req) {
1764 req->next_pending->prev_pending = req->prev_pending;
1765 req->prev_pending->next_pending = req->next_pending;
1768 if (rc == 0) {
1769 server_port_free(req->port);
1770 CLEAR(req);
1771 free(req);
1772 return (1);
1774 CLEAR(req);
1775 free(req);
1776 return (0);
1779 // Free all storage held by an evdns_server_port. Only called when
1780 static void
1781 server_port_free(struct evdns_server_port *port)
1783 assert(port);
1784 assert(!port->refcnt);
1785 assert(!port->pending_replies);
1786 if (port->socket > 0) {
1787 CLOSE_SOCKET(port->socket);
1788 port->socket = -1;
1790 (void) event_del(&port->event);
1791 CLEAR(&port->event);
1792 // XXXX actually free the port? -NM
1795 // exported function
1797 evdns_server_request_drop(struct evdns_server_request *_req)
1799 struct server_request *req = TO_SERVER_REQUEST(_req);
1800 server_request_free(req);
1801 return 0;
1804 #undef APPEND16
1805 #undef APPEND32
1807 // this is a libevent callback function which is called when a request
1808 // has timed out.
1809 static void
1810 evdns_request_timeout_callback(int fd, short events, void *arg) {
1811 struct request *const req = (struct request *) arg;
1812 (void) fd;
1813 (void) events;
1815 log(EVDNS_LOG_DEBUG, "Request %lx timed out", (unsigned long) arg);
1817 req->ns->timedout++;
1818 if (req->ns->timedout > global_max_nameserver_timeout) {
1819 req->ns->timedout = 0;
1820 nameserver_failed(req->ns, "request timed out.");
1823 (void) evtimer_del(&req->timeout_event);
1824 CLEAR(&req->timeout_event);
1825 if (req->tx_count >= global_max_retransmits) {
1826 // this request has failed
1827 reply_callback(req, 0, DNS_ERR_TIMEOUT, NULL);
1828 request_finished(req, &req_head);
1829 } else {
1830 // retransmit it
1831 evdns_request_transmit(req);
1835 // try to send a request to a given server.
1837 // return:
1838 // 0 ok
1839 // 1 temporary failure
1840 // 2 other failure
1841 static int
1842 evdns_request_transmit_to(struct request *req, struct nameserver *server) {
1843 const int r = send(server->socket, req->request, req->request_len, 0);
1844 if (r < 0) {
1845 int err = last_error(server->socket);
1846 if (error_is_eagain(err)) return 1;
1847 nameserver_failed(req->ns, strerror(err));
1848 return 2;
1849 } else if (r != (int)req->request_len) {
1850 return 1; // short write
1851 } else {
1852 return 0;
1856 // try to send a request, updating the fields of the request
1857 // as needed
1859 // return:
1860 // 0 ok
1861 // 1 failed
1862 static int
1863 evdns_request_transmit(struct request *req) {
1864 int retcode = 0, r;
1866 // if we fail to send this packet then this flag marks it
1867 // for evdns_transmit
1868 req->transmit_me = 1;
1869 if (req->trans_id == 0xffff) abort();
1871 if (req->ns->choked) {
1872 // don't bother trying to write to a socket
1873 // which we have had EAGAIN from
1874 return 1;
1877 r = evdns_request_transmit_to(req, req->ns);
1878 switch (r) {
1879 case 1:
1880 // temp failure
1881 req->ns->choked = 1;
1882 nameserver_write_waiting(req->ns, 1);
1883 return 1;
1884 case 2:
1885 // failed in some other way
1886 retcode = 1;
1887 break;
1888 default:
1889 // transmitted; we need to check for timeout.
1890 log(EVDNS_LOG_DEBUG,
1891 "Setting timeout for request %lx", (unsigned long) req);
1892 evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
1893 if (evtimer_add(&req->timeout_event, &global_timeout) < 0) {
1894 log(EVDNS_LOG_WARN,
1895 "Error from libevent when adding timer for request %lx",
1896 (unsigned long) req);
1897 // ???? Do more?
1901 req->tx_count++;
1902 req->transmit_me = 0;
1903 return retcode;
1906 static void
1907 nameserver_probe_callback(int result, char type, int count, int ttl, void *addresses, void *arg) {
1908 struct nameserver *const ns = (struct nameserver *) arg;
1909 (void) type;
1910 (void) count;
1911 (void) ttl;
1912 (void) addresses;
1914 if (result == DNS_ERR_NONE || result == DNS_ERR_NOTEXIST) {
1915 // this is a good reply
1916 nameserver_up(ns);
1917 } else nameserver_probe_failed(ns);
1920 static void
1921 nameserver_send_probe(struct nameserver *const ns) {
1922 struct request *req;
1923 // here we need to send a probe to a given nameserver
1924 // in the hope that it is up now.
1926 log(EVDNS_LOG_DEBUG, "Sending probe to %s", debug_ntoa(ns->address));
1928 req = request_new(TYPE_A, "www.google.com", DNS_QUERY_NO_SEARCH, nameserver_probe_callback, ns);
1929 if (!req) return;
1930 // we force this into the inflight queue no matter what
1931 request_trans_id_set(req, transaction_id_pick());
1932 req->ns = ns;
1933 request_submit(req);
1936 // returns:
1937 // 0 didn't try to transmit anything
1938 // 1 tried to transmit something
1939 static int
1940 evdns_transmit(void) {
1941 char did_try_to_transmit = 0;
1943 if (req_head) {
1944 struct request *const started_at = req_head, *req = req_head;
1945 // first transmit all the requests which are currently waiting
1946 do {
1947 if (req->transmit_me) {
1948 did_try_to_transmit = 1;
1949 evdns_request_transmit(req);
1952 req = req->next;
1953 } while (req != started_at);
1956 return did_try_to_transmit;
1959 // exported function
1961 evdns_count_nameservers(void)
1963 const struct nameserver *server = server_head;
1964 int n = 0;
1965 if (!server)
1966 return 0;
1967 do {
1968 ++n;
1969 server = server->next;
1970 } while (server != server_head);
1971 return n;
1974 // exported function
1976 evdns_clear_nameservers_and_suspend(void)
1978 struct nameserver *server = server_head, *started_at = server_head;
1979 struct request *req = req_head, *req_started_at = req_head;
1981 if (!server)
1982 return 0;
1983 while (1) {
1984 struct nameserver *next = server->next;
1985 (void) event_del(&server->event);
1986 CLEAR(&server->event);
1987 (void) evtimer_del(&server->timeout_event);
1988 CLEAR(&server->timeout_event);
1989 if (server->socket >= 0)
1990 CLOSE_SOCKET(server->socket);
1991 CLEAR(server);
1992 free(server);
1993 if (next == started_at)
1994 break;
1995 server = next;
1997 server_head = NULL;
1998 global_good_nameservers = 0;
2000 while (req) {
2001 struct request *next = req->next;
2002 req->tx_count = req->reissue_count = 0;
2003 req->ns = NULL;
2004 // ???? What to do about searches?
2005 (void) evtimer_del(&req->timeout_event);
2006 CLEAR(&req->timeout_event);
2007 req->trans_id = 0;
2008 req->transmit_me = 0;
2010 global_requests_waiting++;
2011 evdns_request_insert(req, &req_waiting_head);
2012 /* We want to insert these suspended elements at the front of
2013 * the waiting queue, since they were pending before any of
2014 * the waiting entries were added. This is a circular list,
2015 * so we can just shift the start back by one.*/
2016 req_waiting_head = req_waiting_head->prev;
2018 if (next == req_started_at)
2019 break;
2020 req = next;
2022 req_head = NULL;
2023 global_requests_inflight = 0;
2025 return 0;
2029 // exported function
2031 evdns_resume(void)
2033 evdns_requests_pump_waiting_queue();
2034 return 0;
2037 static int
2038 _evdns_nameserver_add_impl(unsigned long int address, int port) {
2039 // first check to see if we already have this nameserver
2041 const struct nameserver *server = server_head, *const started_at = server_head;
2042 struct nameserver *ns;
2043 struct sockaddr_in sin;
2044 int err = 0;
2045 if (server) {
2046 do {
2047 if (server->address == address) return 3;
2048 server = server->next;
2049 } while (server != started_at);
2052 ns = (struct nameserver *) malloc(sizeof(struct nameserver));
2053 if (!ns) return -1;
2055 memset(ns, 0, sizeof(struct nameserver));
2057 ns->socket = socket(PF_INET, SOCK_DGRAM, 0);
2058 if (ns->socket < 0) { err = 1; goto out1; }
2059 #ifdef WIN32
2061 u_long nonblocking = 1;
2062 ioctlsocket(ns->socket, FIONBIO, &nonblocking);
2064 #else
2065 fcntl(ns->socket, F_SETFL, O_NONBLOCK);
2066 #endif
2067 sin.sin_addr.s_addr = address;
2068 sin.sin_port = htons(port);
2069 sin.sin_family = AF_INET;
2070 if (connect(ns->socket, (struct sockaddr *) &sin, sizeof(sin)) != 0) {
2071 err = 2;
2072 goto out2;
2075 ns->address = address;
2076 ns->state = 1;
2077 event_set(&ns->event, ns->socket, EV_READ | EV_PERSIST, nameserver_ready_callback, ns);
2078 if (event_add(&ns->event, NULL) < 0) {
2079 err = 2;
2080 goto out2;
2083 log(EVDNS_LOG_DEBUG, "Added nameserver %s", debug_ntoa(address));
2085 // insert this nameserver into the list of them
2086 if (!server_head) {
2087 ns->next = ns->prev = ns;
2088 server_head = ns;
2089 } else {
2090 ns->next = server_head->next;
2091 ns->prev = server_head;
2092 server_head->next = ns;
2093 if (server_head->prev == server_head) {
2094 server_head->prev = ns;
2098 global_good_nameservers++;
2100 return 0;
2102 out2:
2103 CLOSE_SOCKET(ns->socket);
2104 out1:
2105 CLEAR(ns);
2106 free(ns);
2107 log(EVDNS_LOG_WARN, "Unable to add nameserver %s: error %d", debug_ntoa(address), err);
2108 return err;
2111 // exported function
2113 evdns_nameserver_add(unsigned long int address) {
2114 return _evdns_nameserver_add_impl(address, 53);
2117 // exported function
2119 evdns_nameserver_ip_add(const char *ip_as_string) {
2120 struct in_addr ina;
2121 int port;
2122 char buf[20];
2123 const char *cp;
2124 cp = strchr(ip_as_string, ':');
2125 if (! cp) {
2126 cp = ip_as_string;
2127 port = 53;
2128 } else {
2129 port = strtoint(cp+1);
2130 if (port < 0 || port > 65535) {
2131 return 4;
2133 if ((cp-ip_as_string) >= (int)sizeof(buf)) {
2134 return 4;
2136 memcpy(buf, ip_as_string, cp-ip_as_string);
2137 buf[cp-ip_as_string] = '\0';
2138 cp = buf;
2140 if (!inet_aton(cp, &ina)) {
2141 return 4;
2143 return _evdns_nameserver_add_impl(ina.s_addr, port);
2146 // insert into the tail of the queue
2147 static void
2148 evdns_request_insert(struct request *req, struct request **head) {
2149 if (!*head) {
2150 *head = req;
2151 req->next = req->prev = req;
2152 return;
2155 req->prev = (*head)->prev;
2156 req->prev->next = req;
2157 req->next = *head;
2158 (*head)->prev = req;
2161 static int
2162 string_num_dots(const char *s) {
2163 int count = 0;
2164 while ((s = strchr(s, '.'))) {
2165 s++;
2166 count++;
2168 return count;
2171 static struct request *
2172 request_new(int type, const char *name, int flags,
2173 evdns_callback_type callback, void *user_ptr) {
2174 const char issuing_now =
2175 (global_requests_inflight < global_max_requests_inflight) ? 1 : 0;
2177 const int name_len = strlen(name);
2178 const int request_max_len = evdns_request_len(name_len);
2179 const u16 trans_id = issuing_now ? transaction_id_pick() : 0xffff;
2180 // the request data is alloced in a single block with the header
2181 struct request *const req =
2182 (struct request *) malloc(sizeof(struct request) + request_max_len);
2183 int rlen;
2184 (void) flags;
2186 if (!req) return NULL;
2187 memset(req, 0, sizeof(struct request));
2189 // request data lives just after the header
2190 req->request = ((u8 *) req) + sizeof(struct request);
2191 // denotes that the request data shouldn't be free()ed
2192 req->request_appended = 1;
2193 rlen = evdns_request_data_build(name, name_len, trans_id,
2194 type, CLASS_INET, req->request, request_max_len);
2195 if (rlen < 0)
2196 goto err1;
2197 req->request_len = rlen;
2198 req->trans_id = trans_id;
2199 req->tx_count = 0;
2200 req->request_type = type;
2201 req->user_pointer = user_ptr;
2202 req->user_callback = callback;
2203 req->ns = issuing_now ? nameserver_pick() : NULL;
2204 req->next = req->prev = NULL;
2206 return req;
2207 err1:
2208 CLEAR(req);
2209 free(req);
2210 return NULL;
2213 static void
2214 request_submit(struct request *const req) {
2215 if (req->ns) {
2216 // if it has a nameserver assigned then this is going
2217 // straight into the inflight queue
2218 evdns_request_insert(req, &req_head);
2219 global_requests_inflight++;
2220 evdns_request_transmit(req);
2221 } else {
2222 evdns_request_insert(req, &req_waiting_head);
2223 global_requests_waiting++;
2227 // exported function
2228 int evdns_resolve_ipv4(const char *name, int flags,
2229 evdns_callback_type callback, void *ptr) {
2230 log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
2231 if (flags & DNS_QUERY_NO_SEARCH) {
2232 struct request *const req =
2233 request_new(TYPE_A, name, flags, callback, ptr);
2234 if (req == NULL)
2235 return (1);
2236 request_submit(req);
2237 return (0);
2238 } else {
2239 return (search_request_new(TYPE_A, name, flags, callback, ptr));
2243 // exported function
2244 int evdns_resolve_ipv6(const char *name, int flags,
2245 evdns_callback_type callback, void *ptr) {
2246 log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
2247 if (flags & DNS_QUERY_NO_SEARCH) {
2248 struct request *const req =
2249 request_new(TYPE_AAAA, name, flags, callback, ptr);
2250 if (req == NULL)
2251 return (1);
2252 request_submit(req);
2253 return (0);
2254 } else {
2255 return (search_request_new(TYPE_AAAA, name, flags, callback, ptr));
2259 int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
2260 char buf[32];
2261 struct request *req;
2262 u32 a;
2263 assert(in);
2264 a = ntohl(in->s_addr);
2265 snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
2266 (int)(u8)((a )&0xff),
2267 (int)(u8)((a>>8 )&0xff),
2268 (int)(u8)((a>>16)&0xff),
2269 (int)(u8)((a>>24)&0xff));
2270 log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
2271 req = request_new(TYPE_PTR, buf, flags, callback, ptr);
2272 if (!req) return 1;
2273 request_submit(req);
2274 return 0;
2277 int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
2278 char buf[64];
2279 char *cp;
2280 struct request *req;
2281 int i;
2282 assert(in);
2283 cp = buf;
2284 for (i=15; i >= 0; --i) {
2285 u8 byte = in->s6_addr[i];
2286 *cp++ = "0123456789abcdef"[byte & 0x0f];
2287 *cp++ = '.';
2288 *cp++ = "0123456789abcdef"[byte >> 4];
2289 *cp++ = '.';
2291 assert(cp + strlen(".ip6.arpa") < buf+sizeof(buf));
2292 memcpy(cp, ".ip6.arpa", strlen(".ip6.arpa")+1);
2293 log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
2294 req = request_new(TYPE_PTR, buf, flags, callback, ptr);
2295 if (!req) return 1;
2296 request_submit(req);
2297 return 0;
2301 /////////////////////////////////////////////////////////////////////
2302 // Search support
2304 // the libc resolver has support for searching a number of domains
2305 // to find a name. If nothing else then it takes the single domain
2306 // from the gethostname() call.
2308 // It can also be configured via the domain and search options in a
2309 // resolv.conf.
2311 // The ndots option controls how many dots it takes for the resolver
2312 // to decide that a name is non-local and so try a raw lookup first.
2314 struct search_domain {
2315 int len;
2316 struct search_domain *next;
2317 // the text string is appended to this structure
2320 struct search_state {
2321 int refcount;
2322 int ndots;
2323 int num_domains;
2324 struct search_domain *head;
2327 static struct search_state *global_search_state = NULL;
2329 static void
2330 search_state_decref(struct search_state *const state) {
2331 if (!state) return;
2332 state->refcount--;
2333 if (!state->refcount) {
2334 struct search_domain *next, *dom;
2335 for (dom = state->head; dom; dom = next) {
2336 next = dom->next;
2337 CLEAR(dom);
2338 free(dom);
2340 CLEAR(state);
2341 free(state);
2345 static struct search_state *
2346 search_state_new(void) {
2347 struct search_state *state = (struct search_state *) malloc(sizeof(struct search_state));
2348 if (!state) return NULL;
2349 memset(state, 0, sizeof(struct search_state));
2350 state->refcount = 1;
2351 state->ndots = 1;
2353 return state;
2356 static void
2357 search_postfix_clear(void) {
2358 search_state_decref(global_search_state);
2360 global_search_state = search_state_new();
2363 // exported function
2364 void
2365 evdns_search_clear(void) {
2366 search_postfix_clear();
2369 static void
2370 search_postfix_add(const char *domain) {
2371 int domain_len;
2372 struct search_domain *sdomain;
2373 while (domain[0] == '.') domain++;
2374 domain_len = strlen(domain);
2376 if (!global_search_state) global_search_state = search_state_new();
2377 if (!global_search_state) return;
2378 global_search_state->num_domains++;
2380 sdomain = (struct search_domain *) malloc(sizeof(struct search_domain) + domain_len);
2381 if (!sdomain) return;
2382 memcpy( ((u8 *) sdomain) + sizeof(struct search_domain), domain, domain_len);
2383 sdomain->next = global_search_state->head;
2384 sdomain->len = domain_len;
2386 global_search_state->head = sdomain;
2389 // reverse the order of members in the postfix list. This is needed because,
2390 // when parsing resolv.conf we push elements in the wrong order
2391 static void
2392 search_reverse(void) {
2393 struct search_domain *cur, *prev = NULL, *next;
2394 cur = global_search_state->head;
2395 while (cur) {
2396 next = cur->next;
2397 cur->next = prev;
2398 prev = cur;
2399 cur = next;
2402 global_search_state->head = prev;
2405 // exported function
2406 void
2407 evdns_search_add(const char *domain) {
2408 search_postfix_add(domain);
2411 // exported function
2412 void
2413 evdns_search_ndots_set(const int ndots) {
2414 if (!global_search_state) global_search_state = search_state_new();
2415 if (!global_search_state) return;
2416 global_search_state->ndots = ndots;
2419 static void
2420 search_set_from_hostname(void) {
2421 char hostname[HOST_NAME_MAX + 1], *domainname;
2423 search_postfix_clear();
2424 if (gethostname(hostname, sizeof(hostname))) return;
2425 domainname = strchr(hostname, '.');
2426 if (!domainname) return;
2427 search_postfix_add(domainname);
2430 // warning: returns malloced string
2431 static char *
2432 search_make_new(const struct search_state *const state, int n, const char *const base_name) {
2433 const int base_len = strlen(base_name);
2434 const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
2435 struct search_domain *dom;
2437 for (dom = state->head; dom; dom = dom->next) {
2438 if (!n--) {
2439 // this is the postfix we want
2440 // the actual postfix string is kept at the end of the structure
2441 const u8 *const postfix = ((u8 *) dom) + sizeof(struct search_domain);
2442 const int postfix_len = dom->len;
2443 char *const newname = (char *) malloc(base_len + need_to_append_dot + postfix_len + 1);
2444 if (!newname) return NULL;
2445 memcpy(newname, base_name, base_len);
2446 if (need_to_append_dot) newname[base_len] = '.';
2447 memcpy(newname + base_len + need_to_append_dot, postfix, postfix_len);
2448 newname[base_len + need_to_append_dot + postfix_len] = 0;
2449 return newname;
2453 // we ran off the end of the list and still didn't find the requested string
2454 abort();
2455 return NULL; /* unreachable; stops warnings in some compilers. */
2458 static int
2459 search_request_new(int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg) {
2460 assert(type == TYPE_A || type == TYPE_AAAA);
2461 if ( ((flags & DNS_QUERY_NO_SEARCH) == 0) &&
2462 global_search_state &&
2463 global_search_state->num_domains) {
2464 // we have some domains to search
2465 struct request *req;
2466 if (string_num_dots(name) >= global_search_state->ndots) {
2467 req = request_new(type, name, flags, user_callback, user_arg);
2468 if (!req) return 1;
2469 req->search_index = -1;
2470 } else {
2471 char *const new_name = search_make_new(global_search_state, 0, name);
2472 if (!new_name) return 1;
2473 req = request_new(type, new_name, flags, user_callback, user_arg);
2474 free(new_name);
2475 if (!req) return 1;
2476 req->search_index = 0;
2478 req->search_origname = strdup(name);
2479 req->search_state = global_search_state;
2480 req->search_flags = flags;
2481 global_search_state->refcount++;
2482 request_submit(req);
2483 return 0;
2484 } else {
2485 struct request *const req = request_new(type, name, flags, user_callback, user_arg);
2486 if (!req) return 1;
2487 request_submit(req);
2488 return 0;
2492 // this is called when a request has failed to find a name. We need to check
2493 // if it is part of a search and, if so, try the next name in the list
2494 // returns:
2495 // 0 another request has been submitted
2496 // 1 no more requests needed
2497 static int
2498 search_try_next(struct request *const req) {
2499 if (req->search_state) {
2500 // it is part of a search
2501 char *new_name;
2502 struct request *newreq;
2503 req->search_index++;
2504 if (req->search_index >= req->search_state->num_domains) {
2505 // no more postfixes to try, however we may need to try
2506 // this name without a postfix
2507 if (string_num_dots(req->search_origname) < req->search_state->ndots) {
2508 // yep, we need to try it raw
2509 struct request *const newreq = request_new(req->request_type, req->search_origname, req->search_flags, req->user_callback, req->user_pointer);
2510 log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", req->search_origname);
2511 if (newreq) {
2512 request_submit(newreq);
2513 return 0;
2516 return 1;
2519 new_name = search_make_new(req->search_state, req->search_index, req->search_origname);
2520 if (!new_name) return 1;
2521 log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, req->search_index);
2522 newreq = request_new(req->request_type, new_name, req->search_flags, req->user_callback, req->user_pointer);
2523 free(new_name);
2524 if (!newreq) return 1;
2525 newreq->search_origname = req->search_origname;
2526 req->search_origname = NULL;
2527 newreq->search_state = req->search_state;
2528 newreq->search_flags = req->search_flags;
2529 newreq->search_index = req->search_index;
2530 newreq->search_state->refcount++;
2531 request_submit(newreq);
2532 return 0;
2534 return 1;
2537 static void
2538 search_request_finished(struct request *const req) {
2539 if (req->search_state) {
2540 search_state_decref(req->search_state);
2541 req->search_state = NULL;
2543 if (req->search_origname) {
2544 free(req->search_origname);
2545 req->search_origname = NULL;
2549 /////////////////////////////////////////////////////////////////////
2550 // Parsing resolv.conf files
2552 static void
2553 evdns_resolv_set_defaults(int flags) {
2554 // if the file isn't found then we assume a local resolver
2555 if (flags & DNS_OPTION_SEARCH) search_set_from_hostname();
2556 if (flags & DNS_OPTION_NAMESERVERS) evdns_nameserver_ip_add("127.0.0.1");
2559 #ifndef HAVE_STRTOK_R
2560 static char *
2561 strtok_r(char *s, const char *delim, char **state) {
2562 (void)state;
2563 return strtok(s, delim);
2565 #endif
2567 // helper version of atoi which returns -1 on error
2568 static int
2569 strtoint(const char *const str) {
2570 char *endptr;
2571 const int r = strtol(str, &endptr, 10);
2572 if (*endptr) return -1;
2573 return r;
2576 // helper version of atoi that returns -1 on error and clips to bounds.
2577 static int
2578 strtoint_clipped(const char *const str, int min, int max)
2580 int r = strtoint(str);
2581 if (r == -1)
2582 return r;
2583 else if (r<min)
2584 return min;
2585 else if (r>max)
2586 return max;
2587 else
2588 return r;
2591 // exported function
2593 evdns_set_option(const char *option, const char *val, int flags)
2595 if (!strncmp(option, "ndots:", 6)) {
2596 const int ndots = strtoint(val);
2597 if (ndots == -1) return -1;
2598 if (!(flags & DNS_OPTION_SEARCH)) return 0;
2599 log(EVDNS_LOG_DEBUG, "Setting ndots to %d", ndots);
2600 if (!global_search_state) global_search_state = search_state_new();
2601 if (!global_search_state) return -1;
2602 global_search_state->ndots = ndots;
2603 } else if (!strncmp(option, "timeout:", 8)) {
2604 const int timeout = strtoint(val);
2605 if (timeout == -1) return -1;
2606 if (!(flags & DNS_OPTION_MISC)) return 0;
2607 log(EVDNS_LOG_DEBUG, "Setting timeout to %d", timeout);
2608 global_timeout.tv_sec = timeout;
2609 } else if (!strncmp(option, "max-timeouts:", 12)) {
2610 const int maxtimeout = strtoint_clipped(val, 1, 255);
2611 if (maxtimeout == -1) return -1;
2612 if (!(flags & DNS_OPTION_MISC)) return 0;
2613 log(EVDNS_LOG_DEBUG, "Setting maximum allowed timeouts to %d",
2614 maxtimeout);
2615 global_max_nameserver_timeout = maxtimeout;
2616 } else if (!strncmp(option, "max-inflight:", 13)) {
2617 const int maxinflight = strtoint_clipped(val, 1, 65000);
2618 if (maxinflight == -1) return -1;
2619 if (!(flags & DNS_OPTION_MISC)) return 0;
2620 log(EVDNS_LOG_DEBUG, "Setting maximum inflight requests to %d",
2621 maxinflight);
2622 global_max_requests_inflight = maxinflight;
2623 } else if (!strncmp(option, "attempts:", 9)) {
2624 int retries = strtoint(val);
2625 if (retries == -1) return -1;
2626 if (retries > 255) retries = 255;
2627 if (!(flags & DNS_OPTION_MISC)) return 0;
2628 log(EVDNS_LOG_DEBUG, "Setting retries to %d", retries);
2629 global_max_retransmits = retries;
2631 return 0;
2634 static void
2635 resolv_conf_parse_line(char *const start, int flags) {
2636 char *strtok_state;
2637 static const char *const delims = " \t";
2638 #define NEXT_TOKEN strtok_r(NULL, delims, &strtok_state)
2640 char *const first_token = strtok_r(start, delims, &strtok_state);
2641 if (!first_token) return;
2643 if (!strcmp(first_token, "nameserver") && (flags & DNS_OPTION_NAMESERVERS)) {
2644 const char *const nameserver = NEXT_TOKEN;
2645 struct in_addr ina;
2647 if (inet_aton(nameserver, &ina)) {
2648 // address is valid
2649 evdns_nameserver_add(ina.s_addr);
2651 } else if (!strcmp(first_token, "domain") && (flags & DNS_OPTION_SEARCH)) {
2652 const char *const domain = NEXT_TOKEN;
2653 if (domain) {
2654 search_postfix_clear();
2655 search_postfix_add(domain);
2657 } else if (!strcmp(first_token, "search") && (flags & DNS_OPTION_SEARCH)) {
2658 const char *domain;
2659 search_postfix_clear();
2661 while ((domain = NEXT_TOKEN)) {
2662 search_postfix_add(domain);
2664 search_reverse();
2665 } else if (!strcmp(first_token, "options")) {
2666 const char *option;
2667 while ((option = NEXT_TOKEN)) {
2668 const char *val = strchr(option, ':');
2669 evdns_set_option(option, val ? val+1 : "", flags);
2672 #undef NEXT_TOKEN
2675 // exported function
2676 // returns:
2677 // 0 no errors
2678 // 1 failed to open file
2679 // 2 failed to stat file
2680 // 3 file too large
2681 // 4 out of memory
2682 // 5 short read from file
2684 evdns_resolv_conf_parse(int flags, const char *const filename) {
2685 struct stat st;
2686 int fd;
2687 u8 *resolv;
2688 char *start;
2689 int err = 0;
2691 log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
2693 fd = open(filename, O_RDONLY);
2694 if (fd < 0) {
2695 evdns_resolv_set_defaults(flags);
2696 return 1;
2699 if (fstat(fd, &st)) { err = 2; goto out1; }
2700 if (!st.st_size) {
2701 evdns_resolv_set_defaults(flags);
2702 err = (flags & DNS_OPTION_NAMESERVERS) ? 6 : 0;
2703 goto out1;
2705 if (st.st_size > 65535) { err = 3; goto out1; } // no resolv.conf should be any bigger
2707 resolv = (u8 *) malloc((size_t)st.st_size + 1);
2708 if (!resolv) { err = 4; goto out1; }
2710 if (read(fd, resolv, (size_t)st.st_size) != st.st_size) {
2711 err = 5; goto out2;
2713 resolv[st.st_size] = 0; // we malloced an extra byte
2715 start = (char *) resolv;
2716 for (;;) {
2717 char *const newline = strchr(start, '\n');
2718 if (!newline) {
2719 resolv_conf_parse_line(start, flags);
2720 break;
2721 } else {
2722 *newline = 0;
2723 resolv_conf_parse_line(start, flags);
2724 start = newline + 1;
2728 if (!server_head && (flags & DNS_OPTION_NAMESERVERS)) {
2729 // no nameservers were configured.
2730 evdns_nameserver_ip_add("127.0.0.1");
2731 err = 6;
2733 if (flags & DNS_OPTION_SEARCH && (!global_search_state || global_search_state->num_domains == 0)) {
2734 search_set_from_hostname();
2737 out2:
2738 free(resolv);
2739 out1:
2740 close(fd);
2741 return err;
2744 #ifdef WIN32
2745 // Add multiple nameservers from a space-or-comma-separated list.
2746 static int
2747 evdns_nameserver_ip_add_line(const char *ips) {
2748 const char *addr;
2749 char *buf;
2750 int r;
2751 while (*ips) {
2752 while (ISSPACE(*ips) || *ips == ',' || *ips == '\t')
2753 ++ips;
2754 addr = ips;
2755 while (ISDIGIT(*ips) || *ips == '.' || *ips == ':')
2756 ++ips;
2757 buf = malloc(ips-addr+1);
2758 if (!buf) return 4;
2759 memcpy(buf, addr, ips-addr);
2760 buf[ips-addr] = '\0';
2761 r = evdns_nameserver_ip_add(buf);
2762 free(buf);
2763 if (r) return r;
2765 return 0;
2768 typedef DWORD(WINAPI *GetNetworkParams_fn_t)(FIXED_INFO *, DWORD*);
2770 // Use the windows GetNetworkParams interface in iphlpapi.dll to
2771 // figure out what our nameservers are.
2772 static int
2773 load_nameservers_with_getnetworkparams(void)
2775 // Based on MSDN examples and inspection of c-ares code.
2776 FIXED_INFO *fixed;
2777 HMODULE handle = 0;
2778 ULONG size = sizeof(FIXED_INFO);
2779 void *buf = NULL;
2780 int status = 0, r, added_any;
2781 IP_ADDR_STRING *ns;
2782 GetNetworkParams_fn_t fn;
2784 /* XXXX Possibly, we should hardcode the location of this DLL. */
2785 if (!(handle = LoadLibrary("iphlpapi.dll"))) {
2786 log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
2787 //right now status = 0, doesn't that mean "good" - mikec
2788 status = -1;
2789 goto done;
2791 if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, "GetNetworkParams"))) {
2792 log(EVDNS_LOG_WARN, "Could not get address of function.");
2793 //same as above
2794 status = -1;
2795 goto done;
2798 buf = malloc(size);
2799 if (!buf) { status = 4; goto done; }
2800 fixed = buf;
2801 r = fn(fixed, &size);
2802 if (r != ERROR_SUCCESS && r != ERROR_BUFFER_OVERFLOW) {
2803 status = -1;
2804 goto done;
2806 if (r != ERROR_SUCCESS) {
2807 free(buf);
2808 buf = malloc(size);
2809 if (!buf) { status = 4; goto done; }
2810 fixed = buf;
2811 r = fn(fixed, &size);
2812 if (r != ERROR_SUCCESS) {
2813 log(EVDNS_LOG_DEBUG, "fn() failed.");
2814 status = -1;
2815 goto done;
2819 assert(fixed);
2820 added_any = 0;
2821 ns = &(fixed->DnsServerList);
2822 while (ns) {
2823 r = evdns_nameserver_ip_add_line(ns->IpAddress.String);
2824 if (r) {
2825 log(EVDNS_LOG_DEBUG,"Could not add nameserver %s to list,error: %d",
2826 (ns->IpAddress.String),(int)GetLastError());
2827 status = r;
2828 goto done;
2829 } else {
2830 log(EVDNS_LOG_DEBUG,"Succesfully added %s as nameserver",ns->IpAddress.String);
2833 added_any++;
2834 ns = ns->Next;
2837 if (!added_any) {
2838 log(EVDNS_LOG_DEBUG, "No nameservers added.");
2839 status = -1;
2842 done:
2843 if (buf)
2844 free(buf);
2845 if (handle)
2846 FreeLibrary(handle);
2847 return status;
2850 static int
2851 config_nameserver_from_reg_key(HKEY key, const char *subkey)
2853 char *buf;
2854 DWORD bufsz = 0, type = 0;
2855 int status = 0;
2857 if (RegQueryValueEx(key, subkey, 0, &type, NULL, &bufsz)
2858 != ERROR_MORE_DATA)
2859 return -1;
2860 if (!(buf = malloc(bufsz)))
2861 return -1;
2863 if (RegQueryValueEx(key, subkey, 0, &type, (LPBYTE)buf, &bufsz)
2864 == ERROR_SUCCESS && bufsz > 1) {
2865 status = evdns_nameserver_ip_add_line(buf);
2868 free(buf);
2869 return status;
2872 #define SERVICES_KEY "System\\CurrentControlSet\\Services\\"
2873 #define WIN_NS_9X_KEY SERVICES_KEY "VxD\\MSTCP"
2874 #define WIN_NS_NT_KEY SERVICES_KEY "Tcpip\\Parameters"
2876 static int
2877 load_nameservers_from_registry(void)
2879 int found = 0;
2880 int r;
2881 #define TRY(k, name) \
2882 if (!found && config_nameserver_from_reg_key(k,name) == 0) { \
2883 log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name); \
2884 found = 1; \
2885 } else if (!found) { \
2886 log(EVDNS_LOG_DEBUG,"Didn't find nameservers in %s/%s", \
2887 #k,#name); \
2890 if (((int)GetVersion()) > 0) { /* NT */
2891 HKEY nt_key = 0, interfaces_key = 0;
2893 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
2894 KEY_READ, &nt_key) != ERROR_SUCCESS) {
2895 log(EVDNS_LOG_DEBUG,"Couldn't open nt key, %d",(int)GetLastError());
2896 return -1;
2898 r = RegOpenKeyEx(nt_key, "Interfaces", 0,
2899 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
2900 &interfaces_key);
2901 if (r != ERROR_SUCCESS) {
2902 log(EVDNS_LOG_DEBUG,"Couldn't open interfaces key, %d",(int)GetLastError());
2903 return -1;
2905 TRY(nt_key, "NameServer");
2906 TRY(nt_key, "DhcpNameServer");
2907 TRY(interfaces_key, "NameServer");
2908 TRY(interfaces_key, "DhcpNameServer");
2909 RegCloseKey(interfaces_key);
2910 RegCloseKey(nt_key);
2911 } else {
2912 HKEY win_key = 0;
2913 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X_KEY, 0,
2914 KEY_READ, &win_key) != ERROR_SUCCESS) {
2915 log(EVDNS_LOG_DEBUG, "Couldn't open registry key, %d", (int)GetLastError());
2916 return -1;
2918 TRY(win_key, "NameServer");
2919 RegCloseKey(win_key);
2922 if (found == 0) {
2923 log(EVDNS_LOG_WARN,"Didn't find any nameservers.");
2926 return found ? 0 : -1;
2927 #undef TRY
2931 evdns_config_windows_nameservers(void)
2933 if (load_nameservers_with_getnetworkparams() == 0)
2934 return 0;
2935 return load_nameservers_from_registry();
2937 #endif
2940 evdns_init(void)
2942 int res = 0;
2943 #ifdef WIN32
2944 evdns_config_windows_nameservers();
2945 #else
2946 res = evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf");
2947 #endif
2949 return (res);
2952 const char *
2953 evdns_err_to_string(int err)
2955 switch (err) {
2956 case DNS_ERR_NONE: return "no error";
2957 case DNS_ERR_FORMAT: return "misformatted query";
2958 case DNS_ERR_SERVERFAILED: return "server failed";
2959 case DNS_ERR_NOTEXIST: return "name does not exist";
2960 case DNS_ERR_NOTIMPL: return "query not implemented";
2961 case DNS_ERR_REFUSED: return "refused";
2963 case DNS_ERR_TRUNCATED: return "reply truncated or ill-formed";
2964 case DNS_ERR_UNKNOWN: return "unknown";
2965 case DNS_ERR_TIMEOUT: return "request timed out";
2966 case DNS_ERR_SHUTDOWN: return "dns subsystem shut down";
2967 default: return "[Unknown error code]";
2971 void
2972 evdns_shutdown(int fail_requests)
2974 struct nameserver *server, *server_next;
2975 struct search_domain *dom, *dom_next;
2977 while (req_head) {
2978 if (fail_requests)
2979 reply_callback(req_head, 0, DNS_ERR_SHUTDOWN, NULL);
2980 request_finished(req_head, &req_head);
2982 while (req_waiting_head) {
2983 if (fail_requests)
2984 reply_callback(req_waiting_head, 0, DNS_ERR_SHUTDOWN, NULL);
2985 request_finished(req_waiting_head, &req_waiting_head);
2987 global_requests_inflight = global_requests_waiting = 0;
2989 for (server = server_head; server; server = server_next) {
2990 server_next = server->next;
2991 if (server->socket >= 0)
2992 CLOSE_SOCKET(server->socket);
2993 (void) event_del(&server->event);
2994 CLEAR(server);
2995 free(server);
2996 if (server_next == server_head)
2997 break;
2999 server_head = NULL;
3000 global_good_nameservers = 0;
3002 if (global_search_state) {
3003 for (dom = global_search_state->head; dom; dom = dom_next) {
3004 dom_next = dom->next;
3005 CLEAR(dom);
3006 free(dom);
3008 CLEAR(global_search_state);
3009 free(global_search_state);
3010 global_search_state = NULL;
3012 evdns_log_fn = NULL;
3015 #ifdef EVDNS_MAIN
3016 void
3017 main_callback(int result, char type, int count, int ttl,
3018 void *addrs, void *orig) {
3019 char *n = (char*)orig;
3020 int i;
3021 for (i = 0; i < count; ++i) {
3022 if (type == DNS_IPv4_A) {
3023 printf("%s: %s\n", n, debug_ntoa(((u32*)addrs)[i]));
3024 } else if (type == DNS_PTR) {
3025 printf("%s: %s\n", n, ((char**)addrs)[i]);
3028 if (!count) {
3029 printf("%s: No answer (%d)\n", n, result);
3031 fflush(stdout);
3033 void
3034 evdns_server_callback(struct evdns_server_request *req, void *data)
3036 int i, r;
3037 (void)data;
3038 /* dummy; give 192.168.11.11 as an answer for all A questions,
3039 * give foo.bar.example.com as an answer for all PTR questions. */
3040 for (i = 0; i < req->nquestions; ++i) {
3041 u32 ans = htonl(0xc0a80b0bUL);
3042 if (req->questions[i]->type == EVDNS_TYPE_A &&
3043 req->questions[i]->class == EVDNS_CLASS_INET) {
3044 printf(" -- replying for %s (A)\n", req->questions[i]->name);
3045 r = evdns_server_request_add_a_reply(req, req->questions[i]->name,
3046 1, &ans, 10);
3047 if (r<0)
3048 printf("eeep, didn't work.\n");
3049 } else if (req->questions[i]->type == EVDNS_TYPE_PTR &&
3050 req->questions[i]->class == EVDNS_CLASS_INET) {
3051 printf(" -- replying for %s (PTR)\n", req->questions[i]->name);
3052 r = evdns_server_request_add_ptr_reply(req, NULL, req->questions[i]->name,
3053 "foo.bar.example.com", 10);
3054 } else {
3055 printf(" -- skipping %s [%d %d]\n", req->questions[i]->name,
3056 req->questions[i]->type, req->questions[i]->class);
3060 r = evdns_request_respond(req, 0);
3061 if (r<0)
3062 printf("eeek, couldn't send reply.\n");
3065 void
3066 logfn(int is_warn, const char *msg) {
3067 (void) is_warn;
3068 fprintf(stderr, "%s\n", msg);
3071 main(int c, char **v) {
3072 int idx;
3073 int reverse = 0, verbose = 1, servertest = 0;
3074 if (c<2) {
3075 fprintf(stderr, "syntax: %s [-x] [-v] hostname\n", v[0]);
3076 fprintf(stderr, "syntax: %s [-servertest]\n", v[0]);
3077 return 1;
3079 idx = 1;
3080 while (idx < c && v[idx][0] == '-') {
3081 if (!strcmp(v[idx], "-x"))
3082 reverse = 1;
3083 else if (!strcmp(v[idx], "-v"))
3084 verbose = 1;
3085 else if (!strcmp(v[idx], "-servertest"))
3086 servertest = 1;
3087 else
3088 fprintf(stderr, "Unknown option %s\n", v[idx]);
3089 ++idx;
3091 event_init();
3092 if (verbose)
3093 evdns_set_log_fn(logfn);
3094 evdns_resolv_conf_parse(DNS_OPTION_NAMESERVERS, "/etc/resolv.conf");
3095 if (servertest) {
3096 int sock;
3097 struct sockaddr_in my_addr;
3098 sock = socket(PF_INET, SOCK_DGRAM, 0);
3099 fcntl(sock, F_SETFL, O_NONBLOCK);
3100 my_addr.sin_family = AF_INET;
3101 my_addr.sin_port = htons(10053);
3102 my_addr.sin_addr.s_addr = INADDR_ANY;
3103 if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr))<0) {
3104 perror("bind");
3105 exit(1);
3107 evdns_add_server_port(sock, 0, evdns_server_callback, NULL);
3109 for (; idx < c; ++idx) {
3110 if (reverse) {
3111 struct in_addr addr;
3112 if (!inet_aton(v[idx], &addr)) {
3113 fprintf(stderr, "Skipping non-IP %s\n", v[idx]);
3114 continue;
3116 fprintf(stderr, "resolving %s...\n",v[idx]);
3117 evdns_resolve_reverse(&addr, 0, main_callback, v[idx]);
3118 } else {
3119 fprintf(stderr, "resolving (fwd) %s...\n",v[idx]);
3120 evdns_resolve_ipv4(v[idx], 0, main_callback, v[idx]);
3123 fflush(stdout);
3124 event_dispatch();
3125 return 0;
3127 #endif
3129 // Local Variables:
3130 // tab-width: 4
3131 // c-basic-offset: 4
3132 // indent-tabs-mode: t
3133 // End: