r14602@catbus: nickm | 2007-08-16 13:33:27 -0400
[tor.git] / src / or / eventdns.c
blobbde976981171921460c7af57b996cd654a7c6dbf
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 "eventdns_tor.h"
36 #include <sys/types.h>
37 //#define NDEBUG
39 #ifndef DNS_USE_CPU_CLOCK_FOR_ID
40 #ifndef DNS_USE_GETTIMEOFDAY_FOR_ID
41 #ifndef DNS_USE_OPENSSL_FOR_ID
42 #error Must configure at least one id generation method.
43 #error Please see the documentation.
44 #endif
45 #endif
46 #endif
48 // #define _POSIX_C_SOURCE 200507
49 #define _GNU_SOURCE
51 #ifdef DNS_USE_CPU_CLOCK_FOR_ID
52 #ifdef DNS_USE_OPENSSL_FOR_ID
53 #error Multiple id options selected
54 #endif
55 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
56 #error Multiple id options selected
57 #endif
58 #include <time.h>
59 #endif
61 #ifdef DNS_USE_OPENSSL_FOR_ID
62 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
63 #error Multiple id options selected
64 #endif
65 #include <openssl/rand.h>
66 #endif
68 #define _FORTIFY_SOURCE 3
70 #include <string.h>
71 #include <fcntl.h>
72 #include <sys/time.h>
73 #ifdef HAVE_STDINT_H
74 #include <stdint.h>
75 #endif
76 #include <stdlib.h>
77 #include <string.h>
78 #include <errno.h>
79 #include <assert.h>
80 #include <unistd.h>
81 #include <limits.h>
82 #include <sys/stat.h>
83 #include <ctype.h>
84 #include <stdio.h>
85 #include <stdarg.h>
87 #include "eventdns.h"
88 #ifdef WIN32
89 #include <windows.h>
90 #include <winsock2.h>
91 #include <iphlpapi.h>
92 #else
93 #include <sys/socket.h>
94 #include <netinet/in.h>
95 #include <arpa/inet.h>
96 #endif
98 #ifdef HAVE_NETINET_IN6_H
99 #include <netinet/in6.h>
100 #endif
102 #ifdef WIN32
103 typedef int socklen_t;
104 #endif
106 #define EVDNS_LOG_DEBUG 0
107 #define EVDNS_LOG_WARN 1
109 #ifndef HOST_NAME_MAX
110 #define HOST_NAME_MAX 255
111 #endif
113 #ifndef NDEBUG
114 #include <stdio.h>
115 #endif
117 #undef MIN
118 #define MIN(a,b) ((a)<(b)?(a):(b))
120 #if 0
121 #ifdef __USE_ISOC99B
122 // libevent doesn't work without this
123 typedef uint8_t u_char;
124 typedef unsigned int uint;
125 #endif
126 #endif
127 #include <event.h>
129 #define u64 uint64_t
130 #define u32 uint32_t
131 #define u16 uint16_t
132 #define u8 uint8_t
134 #define MAX_ADDRS 4 // maximum number of addresses from a single packet
135 // which we bother recording
137 #define TYPE_A EVDNS_TYPE_A
138 #define TYPE_PTR EVDNS_TYPE_PTR
139 #define TYPE_AAAA EVDNS_TYPE_AAAA
141 #define CLASS_INET EVDNS_CLASS_INET
143 #define CLEAR(x) do { memset((x), 0, sizeof(*(x))); } while(0)
145 struct request {
146 u8 *request; // the dns packet data
147 unsigned int request_len;
148 int reissue_count;
149 int tx_count; // the number of times that this packet has been sent
150 unsigned int request_type; // TYPE_PTR or TYPE_A
151 void *user_pointer; // the pointer given to us for this request
152 evdns_callback_type user_callback;
153 struct nameserver *ns; // the server which we last sent it
155 // elements used by the searching code
156 int search_index;
157 struct search_state *search_state;
158 char *search_origname; // needs to be free()ed
159 int search_flags;
161 // these objects are kept in a circular list
162 struct request *next, *prev;
164 struct event timeout_event;
166 u16 trans_id; // the transaction id
167 char request_appended; // true if the request pointer is data which follows this struct
168 char transmit_me; // needs to be transmitted
171 #ifndef HAVE_STRUCT_IN6_ADDR
172 struct in6_addr {
173 u8 s6_addr[16];
175 #endif
177 struct reply {
178 unsigned int type;
179 unsigned int have_answer;
180 union {
181 struct {
182 u32 addrcount;
183 u32 addresses[MAX_ADDRS];
184 } a;
185 struct {
186 u32 addrcount;
187 struct in6_addr addresses[MAX_ADDRS];
188 } aaaa;
189 struct {
190 char name[HOST_NAME_MAX];
191 } ptr;
192 } data;
195 struct nameserver {
196 int socket; // a connected UDP socket
197 u32 address;
198 int failed_times; // number of times which we have given this server a chance
199 int timedout; // number of times in a row a request has timed out
200 struct event event;
201 // these objects are kept in a circular list
202 struct nameserver *next, *prev;
203 struct event timeout_event; // used to keep the timeout for
204 // when we next probe this server.
205 // Valid if state == 0
206 char state; // zero if we think that this server is down
207 char choked; // true if we have an EAGAIN from this server's socket
208 char write_waiting; // true if we are waiting for EV_WRITE events
211 static struct request *req_head = NULL, *req_waiting_head = NULL;
212 static struct nameserver *server_head = NULL;
214 // Represents a local port where we're listening for DNS requests. Right now,
215 // only UDP is supported.
216 struct evdns_server_port {
217 int socket; // socket we use to read queries and write replies.
218 int refcnt; // reference count.
219 char choked; // Are we currently blocked from writing?
220 char closing; // Are we trying to close this port, pending writes?
221 evdns_request_callback_fn_type user_callback; // Fn to handle requests
222 void *user_data; // Opaque pointer passed to user_callback
223 struct event event; // Read/write event
224 // circular list of replies that we want to write.
225 struct server_request *pending_replies;
228 // Represents part of a reply being built. (That is, a single RR.)
229 struct server_reply_item {
230 struct server_reply_item *next; // next item in sequence.
231 char *name; // name part of the RR
232 u16 type : 16; // The RR type
233 u16 class : 16; // The RR class (usually CLASS_INET)
234 u32 ttl; // The RR TTL
235 char is_name; // True iff data is a label
236 u16 datalen; // Length of data; -1 if data is a label
237 void *data; // The contents of the RR
240 // Represents a request that we've received as a DNS server, and holds
241 // the components of the reply as we're constructing it.
242 struct server_request {
243 // Pointers to the next and previous entries on the list of replies
244 // that we're waiting to write. Only set if we have tried to respond
245 // and gotten EAGAIN.
246 struct server_request *next_pending;
247 struct server_request *prev_pending;
249 u16 trans_id; // Transaction id.
250 struct evdns_server_port *port; // Which port received this request on?
251 struct sockaddr_storage addr; // Where to send the response
252 socklen_t addrlen; // length of addr
254 int n_answer; // how many answer RRs have been set?
255 int n_authority; // how many authority RRs have been set?
256 int n_additional; // how many additional RRs have been set?
258 struct server_reply_item *answer; // linked list of answer RRs
259 struct server_reply_item *authority; // linked list of authority RRs
260 struct server_reply_item *additional; // linked list of additional RRs
262 // Constructed response. Only set once we're ready to send a reply.
263 // Once this is set, the RR fields are cleared, and no more should be set.
264 char *response;
265 size_t response_len;
267 // Caller-visible fields: flags, questions.
268 struct evdns_server_request base;
271 // helper macro
272 #define OFFSET_OF(st, member) ((off_t) (((char*)&((st*)0)->member)-(char*)0))
274 // Given a pointer to an evdns_server_request, get the corresponding
275 // server_request.
276 #define TO_SERVER_REQUEST(base_ptr) \
277 ((struct server_request*) \
278 (((char*)(base_ptr) - OFFSET_OF(struct server_request, base))))
280 // The number of good nameservers that we have
281 static int global_good_nameservers = 0;
283 // inflight requests are contained in the req_head list
284 // and are actually going out across the network
285 static int global_requests_inflight = 0;
286 // requests which aren't inflight are in the waiting list
287 // and are counted here
288 static int global_requests_waiting = 0;
290 static int global_max_requests_inflight = 64;
292 static struct timeval global_timeout = {5, 0}; // 5 seconds
293 static int global_max_reissues = 1; // a reissue occurs when we get some errors from the server
294 static int global_max_retransmits = 3; // number of times we'll retransmit a request which timed out
295 // number of timeouts in a row before we consider this server to be down
296 static int global_max_nameserver_timeout = 3;
298 // These are the timeout values for nameservers. If we find a nameserver is down
299 // we try to probe it at intervals as given below. Values are in seconds.
300 static const struct timeval global_nameserver_timeouts[] = {{10, 0}, {60, 0}, {300, 0}, {900, 0}, {3600, 0}};
301 static const int global_nameserver_timeouts_length = sizeof(global_nameserver_timeouts)/sizeof(struct timeval);
303 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"};
305 static struct nameserver *nameserver_pick(void);
306 static void evdns_request_insert(struct request *req, struct request **head);
307 static void nameserver_ready_callback(int fd, short events, void *arg);
308 static int evdns_transmit(void);
309 static int evdns_request_transmit(struct request *req);
310 static void nameserver_send_probe(struct nameserver *const ns);
311 static void search_request_finished(struct request *const);
312 static int search_try_next(struct request *const req);
313 static int search_request_new(int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg);
314 static void evdns_requests_pump_waiting_queue(void);
315 static u16 transaction_id_pick(void);
316 static struct request *request_new(int type, const char *name, int flags, evdns_callback_type callback, void *ptr);
317 static void request_submit(struct request *req);
319 static int server_request_free(struct server_request *req);
320 static void server_request_free_answers(struct server_request *req);
321 static void server_port_free(struct evdns_server_port *port);
322 static void server_port_ready_callback(int fd, short events, void *arg);
324 static int strtoint(const char *const str);
326 #ifdef WIN32
327 static int
328 last_error(int sock)
330 int optval, optvallen=sizeof(optval);
331 int err = WSAGetLastError();
332 if (err == WSAEWOULDBLOCK && sock >= 0) {
333 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
334 &optvallen))
335 return err;
336 if (optval)
337 return optval;
339 return err;
342 static int
343 error_is_eagain(int err)
345 return err == EAGAIN || err == WSAEWOULDBLOCK;
347 static int
348 inet_aton(const char *c, struct in_addr *addr)
350 uint32_t r;
351 if (strcmp(c, "255.255.255.255") == 0) {
352 addr->s_addr = 0xffffffffu;
353 } else {
354 r = inet_addr(c);
355 if (r == INADDR_NONE)
356 return 0;
357 addr->s_addr = r;
359 return 1;
361 #define CLOSE_SOCKET(x) closesocket(x)
362 #else
363 #define last_error(sock) (errno)
364 #define error_is_eagain(err) ((err) == EAGAIN)
365 #define CLOSE_SOCKET(x) close(x)
366 #endif
368 #define ISSPACE(c) isspace((int)(unsigned char)(c))
369 #define ISDIGIT(c) isdigit((int)(unsigned char)(c))
371 #ifndef NDEBUG
372 static const char *
373 debug_ntoa(u32 address)
375 static char buf[32];
376 u32 a = ntohl(address);
377 snprintf(buf, sizeof(buf), "%d.%d.%d.%d",
378 (int)(u8)((a>>24)&0xff),
379 (int)(u8)((a>>16)&0xff),
380 (int)(u8)((a>>8 )&0xff),
381 (int)(u8)((a )&0xff));
382 return buf;
384 #endif
386 static evdns_debug_log_fn_type evdns_log_fn = NULL;
388 void
389 evdns_set_log_fn(evdns_debug_log_fn_type fn)
391 evdns_log_fn = fn;
394 #ifdef __GNUC__
395 #define EVDNS_LOG_CHECK __attribute__ ((format(printf, 2, 3)))
396 #else
397 #define EVDNS_LOG_CHECK
398 #endif
400 static void _evdns_log(int warn, const char *fmt, ...) EVDNS_LOG_CHECK;
401 static void
402 _evdns_log(int warn, const char *fmt, ...)
404 va_list args;
405 static char buf[512];
406 if (!evdns_log_fn)
407 return;
408 va_start(args,fmt);
409 #ifdef WIN32
410 _vsnprintf(buf, sizeof(buf), fmt, args);
411 #else
412 vsnprintf(buf, sizeof(buf), fmt, args);
413 #endif
414 buf[sizeof(buf)-1] = '\0';
415 evdns_log_fn(warn, buf);
416 va_end(args);
419 #define log _evdns_log
421 // This walks the list of inflight requests to find the
422 // one with a matching transaction id. Returns NULL on
423 // failure
424 static struct request *
425 request_find_from_trans_id(u16 trans_id) {
426 struct request *req = req_head, *const started_at = req_head;
428 if (req) {
429 do {
430 if (req->trans_id == trans_id) return req;
431 req = req->next;
432 } while (req != started_at);
435 return NULL;
438 // a libevent callback function which is called when a nameserver
439 // has gone down and we want to test if it has came back to life yet
440 static void
441 nameserver_prod_callback(int fd, short events, void *arg) {
442 struct nameserver *const ns = (struct nameserver *) arg;
443 (void)fd;
444 (void)events;
446 nameserver_send_probe(ns);
449 // a libevent callback which is called when a nameserver probe (to see if
450 // it has come back to life) times out. We increment the count of failed_times
451 // and wait longer to send the next probe packet.
452 static void
453 nameserver_probe_failed(struct nameserver *const ns) {
454 const struct timeval * timeout;
455 (void) evtimer_del(&ns->timeout_event);
456 CLEAR(&ns->timeout_event);
457 if (ns->state == 1) {
458 // This can happen if the nameserver acts in a way which makes us mark
459 // it as bad and then starts sending good replies.
460 return;
463 timeout =
464 &global_nameserver_timeouts[MIN(ns->failed_times,
465 global_nameserver_timeouts_length - 1)];
466 ns->failed_times++;
468 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
469 if (evtimer_add(&ns->timeout_event, (struct timeval *) timeout) < 0) {
470 log(EVDNS_LOG_WARN,
471 "Error from libevent when adding timer event for %s",
472 debug_ntoa(ns->address));
473 // ???? Do more?
477 // called when a nameserver has been deemed to have failed. For example, too
478 // many packets have timed out etc
479 static void
480 nameserver_failed(struct nameserver *const ns, const char *msg) {
481 struct request *req, *started_at;
482 // if this nameserver has already been marked as failed
483 // then don't do anything
484 if (!ns->state) return;
486 log(EVDNS_LOG_WARN, "Nameserver %s has failed: %s",
487 debug_ntoa(ns->address), msg);
488 global_good_nameservers--;
489 assert(global_good_nameservers >= 0);
490 if (global_good_nameservers == 0) {
491 log(EVDNS_LOG_WARN, "All nameservers have failed");
494 ns->state = 0;
495 ns->failed_times = 1;
497 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
498 if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
499 log(EVDNS_LOG_WARN,
500 "Error from libevent when adding timer event for %s",
501 debug_ntoa(ns->address));
502 // ???? Do more?
505 // walk the list of inflight requests to see if any can be reassigned to
506 // a different server. Requests in the waiting queue don't have a
507 // nameserver assigned yet
509 // if we don't have *any* good nameservers then there's no point
510 // trying to reassign requests to one
511 if (!global_good_nameservers) return;
513 req = req_head;
514 started_at = req_head;
515 if (req) {
516 do {
517 if (req->tx_count == 0 && req->ns == ns) {
518 // still waiting to go out, can be moved
519 // to another server
520 req->ns = nameserver_pick();
522 req = req->next;
523 } while (req != started_at);
527 static void
528 nameserver_up(struct nameserver *const ns) {
529 if (ns->state) return;
530 log(EVDNS_LOG_WARN, "Nameserver %s is back up",
531 debug_ntoa(ns->address));
532 evtimer_del(&ns->timeout_event);
533 CLEAR(&ns->timeout_event);
534 ns->state = 1;
535 ns->failed_times = 0;
536 ns->timedout = 0;
537 global_good_nameservers++;
540 static void
541 request_trans_id_set(struct request *const req, const u16 trans_id) {
542 req->trans_id = trans_id;
543 *((u16 *) req->request) = htons(trans_id);
546 // Called to remove a request from a list and dealloc it.
547 // head is a pointer to the head of the list it should be
548 // removed from or NULL if the request isn't in a list.
549 static void
550 request_finished(struct request *const req, struct request **head) {
551 if (head) {
552 if (req->next == req) {
553 // only item in the list
554 *head = NULL;
555 } else {
556 req->next->prev = req->prev;
557 req->prev->next = req->next;
558 if (*head == req) *head = req->next;
562 log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
563 (unsigned long) req);
564 evtimer_del(&req->timeout_event);
565 CLEAR(&req->timeout_event);
567 search_request_finished(req);
568 global_requests_inflight--;
570 if (!req->request_appended) {
571 // need to free the request data on it's own
572 free(req->request);
573 } else {
574 // the request data is appended onto the header
575 // so everything gets free()ed when we:
578 CLEAR(req);
579 free(req);
581 evdns_requests_pump_waiting_queue();
584 // This is called when a server returns a funny error code.
585 // We try the request again with another server.
587 // return:
588 // 0 ok
589 // 1 failed/reissue is pointless
590 static int
591 request_reissue(struct request *req) {
592 const struct nameserver *const last_ns = req->ns;
593 // the last nameserver should have been marked as failing
594 // by the caller of this function, therefore pick will try
595 // not to return it
596 req->ns = nameserver_pick();
597 if (req->ns == last_ns) {
598 // ... but pick did return it
599 // not a lot of point in trying again with the
600 // same server
601 return 1;
604 req->reissue_count++;
605 req->tx_count = 0;
606 req->transmit_me = 1;
608 return 0;
611 // this function looks for space on the inflight queue and promotes
612 // requests from the waiting queue if it can.
613 static void
614 evdns_requests_pump_waiting_queue(void) {
615 while (global_requests_inflight < global_max_requests_inflight &&
616 global_requests_waiting) {
617 struct request *req;
618 // move a request from the waiting queue to the inflight queue
619 assert(req_waiting_head);
620 if (req_waiting_head->next == req_waiting_head) {
621 // only one item in the queue
622 req = req_waiting_head;
623 req_waiting_head = NULL;
624 } else {
625 req = req_waiting_head;
626 req->next->prev = req->prev;
627 req->prev->next = req->next;
628 req_waiting_head = req->next;
631 global_requests_waiting--;
632 global_requests_inflight++;
634 req->ns = nameserver_pick();
635 request_trans_id_set(req, transaction_id_pick());
637 evdns_request_insert(req, &req_head);
638 evdns_request_transmit(req);
639 evdns_transmit();
643 static void
644 reply_callback(struct request *const req, u32 ttl, u32 err, struct reply *reply) {
645 switch (req->request_type) {
646 case TYPE_A:
647 if (reply)
648 req->user_callback(DNS_ERR_NONE, DNS_IPv4_A,
649 reply->data.a.addrcount, ttl,
650 reply->data.a.addresses,
651 req->user_pointer);
652 else
653 req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
654 return;
655 case TYPE_PTR:
656 if (reply) {
657 char *name = reply->data.ptr.name;
658 req->user_callback(DNS_ERR_NONE, DNS_PTR, 1, ttl,
659 &name, req->user_pointer);
660 } else {
661 req->user_callback(err, 0, 0, 0, NULL,
662 req->user_pointer);
664 return;
665 case TYPE_AAAA:
666 if (reply)
667 req->user_callback(DNS_ERR_NONE, DNS_IPv6_AAAA,
668 reply->data.aaaa.addrcount, ttl,
669 reply->data.aaaa.addresses,
670 req->user_pointer);
671 else
672 req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
673 return;
675 assert(0);
678 // this processes a parsed reply packet
679 static void
680 reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply) {
681 int error;
682 static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED};
684 if (flags & 0x020f || !reply || !reply->have_answer) {
685 // there was an error
686 if (flags & 0x0200) {
687 error = DNS_ERR_TRUNCATED;
688 } else {
689 u16 error_code = (flags & 0x000f) - 1;
690 if (error_code > 4) {
691 error = DNS_ERR_UNKNOWN;
692 } else {
693 error = error_codes[error_code];
697 switch(error) {
698 case DNS_ERR_NOTIMPL:
699 case DNS_ERR_REFUSED:
700 // we regard these errors as marking a bad nameserver
701 if (req->reissue_count < global_max_reissues) {
702 char msg[64];
703 snprintf(msg, sizeof(msg), "Bad response %d (%s)",
704 error, evdns_err_to_string(error));
705 nameserver_failed(req->ns, msg);
706 if (!request_reissue(req)) return;
708 break;
709 case DNS_ERR_SERVERFAILED:
710 // rcode 2 (servfailed) sometimes means "we are broken" and
711 // sometimes (with some binds) means "that request was very
712 // confusing." Treat this as a timeout, not a failure.
713 /*XXXX refactor the parts of */
714 log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
715 "will allow the request to time out.",
716 debug_ntoa(req->ns->address));
717 break;
718 default:
719 // we got a good reply from the nameserver
720 nameserver_up(req->ns);
723 if (req->search_state && req->request_type != TYPE_PTR) {
724 // if we have a list of domains to search in, try the next one
725 if (!search_try_next(req)) {
726 // a new request was issued so this request is finished and
727 // the user callback will be made when that request (or a
728 // child of it) finishes.
729 request_finished(req, &req_head);
730 return;
734 // all else failed. Pass the failure up
735 reply_callback(req, 0, error, NULL);
736 request_finished(req, &req_head);
737 } else {
738 // all ok, tell the user
739 reply_callback(req, ttl, 0, reply);
740 nameserver_up(req->ns);
741 request_finished(req, &req_head);
745 static inline int
746 name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
747 int name_end = -1;
748 int j = *idx;
749 int ptr_count = 0;
750 #define GET32(x) do { if (j + 4 > length) goto err; memcpy(&_t32, packet + j, 4); j += 4; x = ntohl(_t32); } while(0);
751 #define GET16(x) do { if (j + 2 > length) goto err; memcpy(&_t, packet + j, 2); j += 2; x = ntohs(_t); } while(0);
752 #define GET8(x) do { if (j >= length) goto err; x = packet[j++]; } while(0);
754 char *cp = name_out;
755 const char *const end = name_out + name_out_len;
757 // Normally, names are a series of length prefixed strings terminated
758 // with a length of 0 (the lengths are u8's < 63).
759 // However, the length can start with a pair of 1 bits and that
760 // means that the next 14 bits are a pointer within the current
761 // packet.
763 for(;;) {
764 u8 label_len;
765 if (j >= length) return -1;
766 GET8(label_len);
767 if (!label_len) break;
768 if (label_len & 0xc0) {
769 u8 ptr_low;
770 GET8(ptr_low);
771 if (name_end < 0) name_end = j;
772 j = (((int)label_len & 0x3f) << 8) + ptr_low;
773 /* Make sure that the target offset is in-bounds. */
774 if (j < 0 || j >= length) return -1;
775 /* If we've jumped more times than there are characters in the
776 * message, we must have a loop. */
777 if (++ptr_count > length) return -1;
778 continue;
780 if (label_len > 63) return -1;
781 if (cp != name_out) {
782 if (cp + 1 >= end) return -1;
783 *cp++ = '.';
785 if (cp + label_len >= end) return -1;
786 memcpy(cp, packet + j, label_len);
787 cp += label_len;
788 j += label_len;
790 if (cp >= end) return -1;
791 *cp = '\0';
792 if (name_end < 0)
793 *idx = j;
794 else
795 *idx = name_end;
796 return 0;
797 err:
798 return -1;
801 // parses a raw reply from a nameserver.
802 static int
803 reply_parse(u8 *packet, int length) {
804 int j = 0; // index into packet
805 u16 _t; // used by the macros
806 u32 _t32; // used by the macros
807 char tmp_name[256]; // used by the macros
809 u16 trans_id, questions, answers, authority, additional, datalength;
810 u16 flags = 0;
811 u32 ttl, ttl_r = 0xffffffff;
812 struct reply reply;
813 struct request *req = NULL;
814 unsigned int i;
816 GET16(trans_id);
817 GET16(flags);
818 GET16(questions);
819 GET16(answers);
820 GET16(authority);
821 GET16(additional);
822 (void) authority; /* suppress "unused variable" warnings. */
823 (void) additional; /* suppress "unused variable" warnings. */
825 req = request_find_from_trans_id(trans_id);
826 /* if no request, can't do anything. */
827 if (!req) return -1;
829 memset(&reply, 0, sizeof(reply));
831 /* if not an answer, it doesn't go with any of our requests. */
832 if (!(flags & 0x8000)) return -1; // must be an answer
833 if (flags & 0x020f) {
834 // there was an error
835 goto err;
837 // if (!answers) return; // must have an answer of some form
839 // This macro skips a name in the DNS reply.
840 #define SKIP_NAME \
841 do { tmp_name[0] = '\0'; \
842 if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0) \
843 goto err; \
844 } while(0);
846 reply.type = req->request_type;
848 // skip over each question in the reply
849 for (i = 0; i < questions; ++i) {
850 // the question looks like
851 // <label:name><u16:type><u16:class>
852 SKIP_NAME;
853 j += 4;
854 if (j >= length) goto err;
857 // now we have the answer section which looks like
858 // <label:name><u16:type><u16:class><u32:ttl><u16:len><data...>
860 for (i = 0; i < answers; ++i) {
861 u16 type, class;
863 // XXX I'd be more comfortable if we actually checked the name
864 // here. -NM
865 SKIP_NAME;
866 GET16(type);
867 GET16(class);
868 GET32(ttl);
869 GET16(datalength);
871 if (type == TYPE_A && class == CLASS_INET) {
872 int addrcount, addrtocopy;
873 if (req->request_type != TYPE_A) {
874 j += datalength; continue;
876 if ((datalength & 3) != 0) /* not an even number of As. */
877 goto err;
878 addrcount = datalength >> 2;
879 addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
881 ttl_r = MIN(ttl_r, ttl);
882 // we only bother with the first four addresses.
883 if (j + 4*addrtocopy > length) goto err;
884 memcpy(&reply.data.a.addresses[reply.data.a.addrcount],
885 packet + j, 4*addrtocopy);
886 j += 4*addrtocopy;
887 reply.data.a.addrcount += addrtocopy;
888 reply.have_answer = 1;
889 if (reply.data.a.addrcount == MAX_ADDRS) break;
890 } else if (type == TYPE_PTR && class == CLASS_INET) {
891 if (req->request_type != TYPE_PTR) {
892 j += datalength; continue;
894 if (name_parse(packet, length, &j, reply.data.ptr.name,
895 sizeof(reply.data.ptr.name))<0)
896 goto err;
897 ttl_r = MIN(ttl_r, ttl);
898 reply.have_answer = 1;
899 break;
900 } else if (type == TYPE_AAAA && class == CLASS_INET) {
901 int addrcount, addrtocopy;
902 if (req->request_type != TYPE_AAAA) {
903 j += datalength; continue;
905 if ((datalength & 15) != 0) /* not an even number of AAAAs. */
906 goto err;
907 addrcount = datalength >> 4; // each address is 16 bytes long
908 addrtocopy = MIN(MAX_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount);
909 ttl_r = MIN(ttl_r, ttl);
911 // we only bother with the first four addresses.
912 if (j + 16*addrtocopy > length) goto err;
913 memcpy(&reply.data.aaaa.addresses[reply.data.aaaa.addrcount],
914 packet + j, 16*addrtocopy);
915 reply.data.aaaa.addrcount += addrtocopy;
916 j += 16*addrtocopy;
917 reply.have_answer = 1;
918 if (reply.data.aaaa.addrcount == MAX_ADDRS) break;
919 } else {
920 // skip over any other type of resource
921 j += datalength;
925 reply_handle(req, flags, ttl_r, &reply);
926 return 0;
927 err:
928 if (req)
929 reply_handle(req, flags, 0, NULL);
930 return -1;
933 // Parse a raw request (packet,length) sent to a nameserver port (port) from
934 // a DNS client (addr,addrlen), and if it's well-formed, call the corresponding
935 // callback.
936 static int
937 request_parse(u8 *packet, int length, struct evdns_server_port *port, struct sockaddr *addr, socklen_t addrlen)
939 int j = 0; // index into packet
940 u16 _t; // used by the macros
941 char tmp_name[256]; // used by the macros
943 int i;
944 u16 trans_id, flags, questions, answers, authority, additional;
945 struct server_request *server_req = NULL;
947 // Get the header fields
948 GET16(trans_id);
949 GET16(flags);
950 GET16(questions);
951 GET16(answers);
952 GET16(authority);
953 GET16(additional);
955 if (flags & 0x8000) return -1; // Must not be an answer.
956 if (flags & 0x7800) return -1; // only standard queries are supported
957 flags &= 0x0300; // Only TC and RD get preserved.
959 server_req = malloc(sizeof(struct server_request));
960 if (server_req == NULL) return -1;
961 memset(server_req, 0, sizeof(struct server_request));
963 server_req->trans_id = trans_id;
964 memcpy(&server_req->addr, addr, addrlen);
965 server_req->addrlen = addrlen;
967 server_req->base.flags = flags;
968 server_req->base.nquestions = 0;
969 server_req->base.questions = malloc(sizeof(struct evdns_server_question *) * questions);
970 if (server_req->base.questions == NULL)
971 goto err;
973 for (i = 0; i < questions; ++i) {
974 u16 type, class;
975 struct evdns_server_question *q;
976 int namelen;
977 if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)
978 goto err;
979 GET16(type);
980 GET16(class);
981 namelen = strlen(tmp_name);
982 q = malloc(sizeof(struct evdns_server_question) + namelen);
983 if (!q)
984 goto err;
985 q->type = type;
986 q->class = class;
987 memcpy(q->name, tmp_name, namelen+1);
988 server_req->base.questions[server_req->base.nquestions++] = q;
991 // Ignore answers, authority, and additional.
993 server_req->port = port;
994 port->refcnt++;
995 port->user_callback(&(server_req->base), port->user_data);
997 return 0;
998 err:
999 if (server_req) {
1000 if (server_req->base.questions) {
1001 for (i = 0; i < server_req->base.nquestions; ++i)
1002 free(server_req->base.questions[i]);
1003 free(server_req->base.questions);
1005 CLEAR(server_req);
1006 free(server_req);
1008 return -1;
1010 #undef SKIP_NAME
1011 #undef GET32
1012 #undef GET16
1013 #undef GET8
1016 // Try to choose a strong transaction id which isn't already in flight
1017 static u16
1018 transaction_id_pick(void) {
1019 for (;;) {
1020 const struct request *req = req_head, *started_at;
1021 #ifdef DNS_USE_CPU_CLOCK_FOR_ID
1022 struct timespec ts;
1023 u16 trans_id;
1024 #ifdef CLOCK_MONOTONIC
1025 if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
1026 #else
1027 if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
1028 #endif
1029 event_err(1, "clock_gettime");
1030 trans_id = ts.tv_nsec & 0xffff;
1031 #endif
1033 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
1034 struct timeval tv;
1035 u16 trans_id;
1036 gettimeofday(&tv, NULL);
1037 trans_id = tv.tv_usec & 0xffff;
1038 #endif
1040 #ifdef DNS_USE_OPENSSL_FOR_ID
1041 u16 trans_id;
1042 if (RAND_pseudo_bytes((u8 *) &trans_id, 2) == -1) {
1043 /* // in the case that the RAND call fails we back
1044 // down to using gettimeofday.
1045 struct timeval tv;
1046 gettimeofday(&tv, NULL);
1047 trans_id = tv.tv_usec & 0xffff; */
1048 abort();
1050 #endif
1052 if (trans_id == 0xffff) continue;
1053 // now check to see if that id is already inflight
1054 req = started_at = req_head;
1055 if (req) {
1056 do {
1057 if (req->trans_id == trans_id) break;
1058 req = req->next;
1059 } while (req != started_at);
1061 // we didn't find it, so this is a good id
1062 if (req == started_at) return trans_id;
1066 // choose a namesever to use. This function will try to ignore
1067 // nameservers which we think are down and load balance across the rest
1068 // by updating the server_head global each time.
1069 static struct nameserver *
1070 nameserver_pick(void) {
1071 struct nameserver *started_at = server_head, *picked;
1072 if (!server_head) return NULL;
1074 // if we don't have any good nameservers then there's no
1075 // point in trying to find one.
1076 if (!global_good_nameservers) {
1077 server_head = server_head->next;
1078 return server_head;
1081 // remember that nameservers are in a circular list
1082 for (;;) {
1083 if (server_head->state) {
1084 // we think this server is currently good
1085 picked = server_head;
1086 server_head = server_head->next;
1087 return picked;
1090 server_head = server_head->next;
1091 if (server_head == started_at) {
1092 // all the nameservers seem to be down
1093 // so we just return this one and hope for the
1094 // best
1095 assert(global_good_nameservers == 0);
1096 picked = server_head;
1097 server_head = server_head->next;
1098 return picked;
1103 // this is called when a namesever socket is ready for reading
1104 static void
1105 nameserver_read(struct nameserver *ns) {
1106 u8 packet[1500];
1108 for (;;) {
1109 const int r = recv(ns->socket, packet, sizeof(packet), 0);
1110 if (r < 0) {
1111 int err = last_error(ns->socket);
1112 if (error_is_eagain(err)) return;
1113 nameserver_failed(ns, strerror(err));
1114 return;
1116 ns->timedout = 0;
1117 reply_parse(packet, r);
1121 // Read a packet from a DNS client on a server port s, parse it, and
1122 // act accordingly.
1123 static void
1124 server_port_read(struct evdns_server_port *s) {
1125 u8 packet[1500];
1126 struct sockaddr_storage addr;
1127 socklen_t addrlen;
1128 int r;
1130 for (;;) {
1131 addrlen = sizeof(struct sockaddr_storage);
1132 r = recvfrom(s->socket, packet, sizeof(packet), 0,
1133 (struct sockaddr*) &addr, &addrlen);
1134 if (r < 0) {
1135 int err = last_error(s->socket);
1136 if (error_is_eagain(err)) return;
1137 log(EVDNS_LOG_WARN, "Error %s (%d) while reading request.",
1138 strerror(err), err);
1139 return;
1141 request_parse(packet, r, s, (struct sockaddr*) &addr, addrlen);
1145 // Try to write all pending replies on a given DNS server port.
1146 static void
1147 server_port_flush(struct evdns_server_port *port)
1149 while (port->pending_replies) {
1150 struct server_request *req = port->pending_replies;
1151 int r = sendto(port->socket, req->response, req->response_len, 0,
1152 (struct sockaddr*) &req->addr, req->addrlen);
1153 if (r < 0) {
1154 int err = last_error(port->socket);
1155 if (error_is_eagain(err))
1156 return;
1157 log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", strerror(err), err);
1159 if (server_request_free(req)) {
1160 // we released the last reference to req->port.
1161 return;
1165 // We have no more pending requests; stop listening for 'writeable' events.
1166 (void) event_del(&port->event);
1167 CLEAR(&port->event);
1168 event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
1169 server_port_ready_callback, port);
1170 if (event_add(&port->event, NULL) < 0) {
1171 log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server.");
1172 // ???? Do more?
1176 // set if we are waiting for the ability to write to this server.
1177 // if waiting is true then we ask libevent for EV_WRITE events, otherwise
1178 // we stop these events.
1179 static void
1180 nameserver_write_waiting(struct nameserver *ns, char waiting) {
1181 if (ns->write_waiting == waiting) return;
1183 ns->write_waiting = waiting;
1184 (void) event_del(&ns->event);
1185 CLEAR(&ns->event);
1186 event_set(&ns->event, ns->socket, EV_READ | (waiting ? EV_WRITE : 0) | EV_PERSIST,
1187 nameserver_ready_callback, ns);
1188 if (event_add(&ns->event, NULL) < 0) {
1189 log(EVDNS_LOG_WARN, "Error from libevent when adding event for %s",
1190 debug_ntoa(ns->address));
1191 // ???? Do more?
1195 // a callback function. Called by libevent when the kernel says that
1196 // a nameserver socket is ready for writing or reading
1197 static void
1198 nameserver_ready_callback(int fd, short events, void *arg) {
1199 struct nameserver *ns = (struct nameserver *) arg;
1200 (void)fd;
1202 if (events & EV_WRITE) {
1203 ns->choked = 0;
1204 if (!evdns_transmit()) {
1205 nameserver_write_waiting(ns, 0);
1208 if (events & EV_READ) {
1209 nameserver_read(ns);
1213 // a callback function. Called by libevent when the kernel says that
1214 // a server socket is ready for writing or reading.
1215 static void
1216 server_port_ready_callback(int fd, short events, void *arg) {
1217 struct evdns_server_port *port = (struct evdns_server_port *) arg;
1218 (void) fd;
1220 if (events & EV_WRITE) {
1221 port->choked = 0;
1222 server_port_flush(port);
1224 if (events & EV_READ) {
1225 server_port_read(port);
1229 /* This is an inefficient representation; only use it via the dnslabel_table_*
1230 * functions, so that is can be safely replaced with something smarter later. */
1231 #define MAX_LABELS 128
1232 // Structures used to implement name compression
1233 struct dnslabel_entry { char *v; int pos; };
1234 struct dnslabel_table {
1235 int n_labels; // number of current entries
1236 // map from name to position in message
1237 struct dnslabel_entry labels[MAX_LABELS];
1240 // Initialize dnslabel_table.
1241 static void
1242 dnslabel_table_init(struct dnslabel_table *table)
1244 table->n_labels = 0;
1247 // Free all storage held by table, but not the table itself.
1248 static void
1249 dnslabel_clear(struct dnslabel_table *table)
1251 int i;
1252 for (i = 0; i < table->n_labels; ++i)
1253 free(table->labels[i].v);
1254 table->n_labels = 0;
1257 // return the position of the label in the current message, or -1 if the label
1258 // hasn't been used yet.
1259 static int
1260 dnslabel_table_get_pos(const struct dnslabel_table *table, const char *label)
1262 int i;
1263 for (i = 0; i < table->n_labels; ++i) {
1264 if (!strcmp(label, table->labels[i].v))
1265 return table->labels[i].pos;
1267 return -1;
1270 // remember that we've used the label at position pos
1271 static int
1272 dnslabel_table_add(struct dnslabel_table *table, const char *label, int pos)
1274 char *v;
1275 int p;
1276 if (table->n_labels == MAX_LABELS)
1277 return (-1);
1278 v = strdup(label);
1279 if (v == NULL)
1280 return (-1);
1281 p = table->n_labels++;
1282 table->labels[p].v = v;
1283 table->labels[p].pos = pos;
1285 return (0);
1288 // Converts a string to a length-prefixed set of DNS labels, starting
1289 // at buf[j]. name and buf must not overlap. name_len should be the length
1290 // of name. table is optional, and is used for compression.
1292 // Input: abc.def
1293 // Output: <3>abc<3>def<0>
1295 // Returns the first index after the encoded name, or negative on error.
1296 // -1 label was > 63 bytes
1297 // -2 name too long to fit in buffer.
1299 static off_t
1300 dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j,
1301 const char *name, const int name_len,
1302 struct dnslabel_table *table) {
1303 const char *end = name + name_len;
1304 int ref = 0;
1305 u16 _t;
1307 #define APPEND16(x) do { \
1308 if (j + 2 > (off_t)buf_len) \
1309 goto overflow; \
1310 _t = htons(x); \
1311 memcpy(buf + j, &_t, 2); \
1312 j += 2; \
1313 } while (0)
1314 #define APPEND32(x) do { \
1315 if (j + 4 > (off_t)buf_len) \
1316 goto overflow; \
1317 _t32 = htonl(x); \
1318 memcpy(buf + j, &_t32, 4); \
1319 j += 4; \
1320 } while (0)
1322 if (name_len > 255) return -2;
1324 for (;;) {
1325 const char *const start = name;
1326 if (table && (ref = dnslabel_table_get_pos(table, name)) >= 0) {
1327 APPEND16(ref | 0xc000);
1328 return j;
1330 name = strchr(name, '.');
1331 if (!name) {
1332 const unsigned int label_len = end - start;
1333 if (label_len > 63) return -1;
1334 if ((size_t)(j+label_len+1) > buf_len) return -2;
1335 if (table) dnslabel_table_add(table, start, j);
1336 buf[j++] = label_len;
1338 memcpy(buf + j, start, end - start);
1339 j += end - start;
1340 break;
1341 } else {
1342 // append length of the label.
1343 const unsigned int label_len = name - start;
1344 if (label_len > 63) return -1;
1345 if ((size_t)(j+label_len+1) > buf_len) return -2;
1346 if (table) dnslabel_table_add(table, start, j);
1347 buf[j++] = label_len;
1349 memcpy(buf + j, start, name - start);
1350 j += name - start;
1351 // hop over the '.'
1352 name++;
1356 // the labels must be terminated by a 0.
1357 // It's possible that the name ended in a .
1358 // in which case the zero is already there
1359 if (!j || buf[j-1]) buf[j++] = 0;
1360 return j;
1361 overflow:
1362 return (-2);
1365 // Finds the length of a dns request for a DNS name of the given
1366 // length. The actual request may be smaller than the value returned
1367 // here
1368 static int
1369 evdns_request_len(const int name_len) {
1370 return 96 + // length of the DNS standard header
1371 name_len + 2 +
1372 4; // space for the resource type
1375 // build a dns request packet into buf. buf should be at least as long
1376 // as evdns_request_len told you it should be.
1378 // Returns the amount of space used. Negative on error.
1379 static int
1380 evdns_request_data_build(const char *const name, const int name_len,
1381 const u16 trans_id, const u16 type, const u16 class,
1382 u8 *const buf, size_t buf_len) {
1383 off_t j = 0; // current offset into buf
1384 u16 _t; // used by the macros
1386 APPEND16(trans_id);
1387 APPEND16(0x0100); // standard query, recusion needed
1388 APPEND16(1); // one question
1389 APPEND16(0); // no answers
1390 APPEND16(0); // no authority
1391 APPEND16(0); // no additional
1393 j = dnsname_to_labels(buf, buf_len, j, name, name_len, NULL);
1394 if (j < 0) {
1395 return (int)j;
1398 APPEND16(type);
1399 APPEND16(class);
1401 return (int)j;
1402 overflow:
1403 return (-1);
1406 // exported function
1407 struct evdns_server_port *
1408 evdns_add_server_port(int socket, int is_tcp, evdns_request_callback_fn_type cb, void *user_data)
1410 struct evdns_server_port *port;
1411 if (!(port = malloc(sizeof(struct evdns_server_port))))
1412 return NULL;
1413 memset(port, 0, sizeof(struct evdns_server_port));
1415 assert(!is_tcp); // TCP sockets not yet implemented
1416 port->socket = socket;
1417 port->refcnt = 1;
1418 port->choked = 0;
1419 port->closing = 0;
1420 port->user_callback = cb;
1421 port->user_data = user_data;
1422 port->pending_replies = NULL;
1424 event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
1425 server_port_ready_callback, port);
1426 event_add(&port->event, NULL); // check return.
1427 return port;
1430 // exported function
1431 void
1432 evdns_close_server_port(struct evdns_server_port *port)
1434 if (--port->refcnt == 0)
1435 server_port_free(port);
1436 port->closing = 1;
1439 // exported function
1441 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)
1443 struct server_request *req = TO_SERVER_REQUEST(_req);
1444 struct server_reply_item **itemp, *item;
1445 int *countp;
1447 if (req->response) /* have we already answered? */
1448 return (-1);
1450 switch (section) {
1451 case EVDNS_ANSWER_SECTION:
1452 itemp = &req->answer;
1453 countp = &req->n_answer;
1454 break;
1455 case EVDNS_AUTHORITY_SECTION:
1456 itemp = &req->authority;
1457 countp = &req->n_authority;
1458 break;
1459 case EVDNS_ADDITIONAL_SECTION:
1460 itemp = &req->additional;
1461 countp = &req->n_additional;
1462 break;
1463 default:
1464 return (-1);
1466 while (*itemp) {
1467 itemp = &((*itemp)->next);
1469 item = malloc(sizeof(struct server_reply_item));
1470 if (!item)
1471 return -1;
1472 CLEAR(item);
1473 item->next = NULL;
1474 if (!(item->name = strdup(name))) {
1475 CLEAR(item);
1476 free(item);
1477 return -1;
1479 item->type = type;
1480 item->class = class;
1481 item->ttl = ttl;
1482 item->is_name = is_name != 0;
1483 item->datalen = 0;
1484 item->data = NULL;
1485 if (data) {
1486 if (item->is_name) {
1487 if (!(item->data = strdup(data))) {
1488 free(item->name);
1489 CLEAR(item);
1490 free(item);
1491 return -1;
1493 item->datalen = -1;
1494 } else {
1495 if (!(item->data = malloc(datalen))) {
1496 free(item->name);
1497 CLEAR(item);
1498 free(item);
1499 return -1;
1501 item->datalen = datalen;
1502 memcpy(item->data, data, datalen);
1506 *itemp = item;
1507 ++(*countp);
1508 return 0;
1511 // exported function
1513 evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
1515 return evdns_server_request_add_reply(
1516 req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
1517 ttl, n*4, 0, addrs);
1520 // exported function
1522 evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
1524 return evdns_server_request_add_reply(
1525 req, EVDNS_ANSWER_SECTION, name, TYPE_AAAA, CLASS_INET,
1526 ttl, n*16, 0, addrs);
1529 // exported function
1531 evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl)
1533 u32 a;
1534 char buf[32];
1535 assert(in || inaddr_name);
1536 assert(!(in && inaddr_name));
1537 if (in) {
1538 a = ntohl(in->s_addr);
1539 snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
1540 (int)(u8)((a )&0xff),
1541 (int)(u8)((a>>8 )&0xff),
1542 (int)(u8)((a>>16)&0xff),
1543 (int)(u8)((a>>24)&0xff));
1544 inaddr_name = buf;
1546 return evdns_server_request_add_reply(
1547 req, EVDNS_ANSWER_SECTION, inaddr_name, TYPE_PTR, CLASS_INET,
1548 ttl, -1, 1, hostname);
1551 // exported function
1553 evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl)
1555 return evdns_server_request_add_reply(
1556 req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
1557 ttl, -1, 1, cname);
1561 static int
1562 evdns_server_request_format_response(struct server_request *req, int err)
1564 unsigned char buf[1500];
1565 size_t buf_len = sizeof(buf);
1566 off_t j = 0, r;
1567 u16 _t;
1568 u32 _t32;
1569 int i;
1570 u16 flags;
1571 struct dnslabel_table table;
1573 if (err < 0 || err > 15) return -1;
1575 /* Set response bit and error code; copy OPCODE and RD fields from
1576 * question; copy RA and AA if set by caller. */
1577 flags = req->base.flags;
1578 flags |= (0x8000 | err);
1580 dnslabel_table_init(&table);
1581 APPEND16(req->trans_id);
1582 APPEND16(flags);
1583 APPEND16(req->base.nquestions);
1584 APPEND16(req->n_answer);
1585 APPEND16(req->n_authority);
1586 APPEND16(req->n_additional);
1588 /* Add questions. */
1589 for (i=0; i < req->base.nquestions; ++i) {
1590 const char *s = req->base.questions[i]->name;
1591 j = dnsname_to_labels(buf, buf_len, j, s, strlen(s), &table);
1592 if (j < 0) {
1593 dnslabel_clear(&table);
1594 return (int) j;
1596 APPEND16(req->base.questions[i]->type);
1597 APPEND16(req->base.questions[i]->class);
1600 /* Add answer, authority, and additional sections. */
1601 for (i=0; i<3; ++i) {
1602 struct server_reply_item *item;
1603 if (i==0)
1604 item = req->answer;
1605 else if (i==1)
1606 item = req->authority;
1607 else
1608 item = req->additional;
1609 while (item) {
1610 r = dnsname_to_labels(buf, buf_len, j, item->name, strlen(item->name), &table);
1611 if (r < 0)
1612 goto overflow;
1613 j = r;
1615 APPEND16(item->type);
1616 APPEND16(item->class);
1617 APPEND32(item->ttl);
1618 if (item->is_name) {
1619 off_t len_idx = j, name_start;
1620 j += 2;
1621 name_start = j;
1622 r = dnsname_to_labels(buf, buf_len, j, item->data, strlen(item->data), &table);
1623 if (r < 0)
1624 goto overflow;
1625 j = r;
1626 _t = htons( (j-name_start) );
1627 memcpy(buf+len_idx, &_t, 2);
1628 } else {
1629 APPEND16(item->datalen);
1630 if (j+item->datalen > (off_t)buf_len)
1631 goto overflow;
1632 memcpy(buf+j, item->data, item->datalen);
1633 j += item->datalen;
1635 item = item->next;
1639 if (j > 512) {
1640 overflow:
1641 j = 512;
1642 buf[3] |= 0x02; /* set the truncated bit. */
1645 req->response_len = j;
1647 if (!(req->response = malloc(req->response_len))) {
1648 server_request_free_answers(req);
1649 dnslabel_clear(&table);
1650 return (-1);
1652 memcpy(req->response, buf, req->response_len);
1653 server_request_free_answers(req);
1654 dnslabel_clear(&table);
1655 return (0);
1658 // exported function
1660 evdns_server_request_respond(struct evdns_server_request *_req, int err)
1662 struct server_request *req = TO_SERVER_REQUEST(_req);
1663 struct evdns_server_port *port = req->port;
1664 int r;
1665 if (!req->response) {
1666 if ((r = evdns_server_request_format_response(req, err))<0)
1667 return r;
1670 r = sendto(port->socket, req->response, req->response_len, 0,
1671 (struct sockaddr*) &req->addr, req->addrlen);
1672 if (r<0) {
1673 int err = last_error(port->socket);
1674 if (! error_is_eagain(err))
1675 return -1;
1677 if (port->pending_replies) {
1678 req->prev_pending = port->pending_replies->prev_pending;
1679 req->next_pending = port->pending_replies;
1680 req->prev_pending->next_pending =
1681 req->next_pending->prev_pending = req;
1682 } else {
1683 req->prev_pending = req->next_pending = req;
1684 port->pending_replies = req;
1685 port->choked = 1;
1687 (void) event_del(&port->event);
1688 CLEAR(&port->event);
1689 event_set(&port->event, port->socket, (port->closing?0:EV_READ) | EV_WRITE | EV_PERSIST, server_port_ready_callback, port);
1691 if (event_add(&port->event, NULL) < 0) {
1692 log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server");
1697 return 1;
1699 if (server_request_free(req))
1700 return 0;
1702 if (req->port->pending_replies)
1703 server_port_flush(port);
1705 return 0;
1708 // Free all storage held by RRs in req.
1709 static void
1710 server_request_free_answers(struct server_request *req)
1712 struct server_reply_item *victim, *next, **list;
1713 int i;
1714 for (i = 0; i < 3; ++i) {
1715 if (i==0)
1716 list = &req->answer;
1717 else if (i==1)
1718 list = &req->authority;
1719 else
1720 list = &req->additional;
1722 victim = *list;
1723 while (victim) {
1724 next = victim->next;
1725 free(victim->name);
1726 if (victim->data)
1727 free(victim->data);
1728 /* XXXX free(victim?) -NM */
1729 victim = next;
1731 *list = NULL;
1735 // Free all storage held by req, and remove links to it.
1736 // return true iff we just wound up freeing the server_port.
1737 static int
1738 server_request_free(struct server_request *req)
1740 int i, rc=1;
1741 if (req->base.questions) {
1742 for (i = 0; i < req->base.nquestions; ++i)
1743 free(req->base.questions[i]);
1746 if (req->port) {
1747 if (req->port->pending_replies == req) {
1748 if (req->next_pending)
1749 req->port->pending_replies = req->next_pending;
1750 else
1751 req->port->pending_replies = NULL;
1753 rc = --req->port->refcnt;
1756 if (req->response) {
1757 free(req->response);
1760 server_request_free_answers(req);
1762 if (req->next_pending && req->next_pending != req) {
1763 req->next_pending->prev_pending = req->prev_pending;
1764 req->prev_pending->next_pending = req->next_pending;
1767 if (rc == 0) {
1768 server_port_free(req->port);
1769 CLEAR(req);
1770 free(req);
1771 return (1);
1773 CLEAR(req);
1774 free(req);
1775 return (0);
1778 // Free all storage held by an evdns_server_port. Only called when
1779 static void
1780 server_port_free(struct evdns_server_port *port)
1782 assert(port);
1783 assert(!port->refcnt);
1784 assert(!port->pending_replies);
1785 if (port->socket > 0) {
1786 CLOSE_SOCKET(port->socket);
1787 port->socket = -1;
1789 (void) event_del(&port->event);
1790 CLEAR(&port->event);
1791 // XXXX actually free the port? -NM
1794 // exported function
1796 evdns_server_request_drop(struct evdns_server_request *_req)
1798 struct server_request *req = TO_SERVER_REQUEST(_req);
1799 server_request_free(req);
1800 return 0;
1803 #undef APPEND16
1804 #undef APPEND32
1806 // this is a libevent callback function which is called when a request
1807 // has timed out.
1808 static void
1809 evdns_request_timeout_callback(int fd, short events, void *arg) {
1810 struct request *const req = (struct request *) arg;
1811 (void) fd;
1812 (void) events;
1814 log(EVDNS_LOG_DEBUG, "Request %lx timed out", (unsigned long) arg);
1816 req->ns->timedout++;
1817 if (req->ns->timedout > global_max_nameserver_timeout) {
1818 req->ns->timedout = 0;
1819 nameserver_failed(req->ns, "request timed out.");
1822 (void) evtimer_del(&req->timeout_event);
1823 CLEAR(&req->timeout_event);
1824 if (req->tx_count >= global_max_retransmits) {
1825 // this request has failed
1826 reply_callback(req, 0, DNS_ERR_TIMEOUT, NULL);
1827 request_finished(req, &req_head);
1828 } else {
1829 // retransmit it
1830 evdns_request_transmit(req);
1834 // try to send a request to a given server.
1836 // return:
1837 // 0 ok
1838 // 1 temporary failure
1839 // 2 other failure
1840 static int
1841 evdns_request_transmit_to(struct request *req, struct nameserver *server) {
1842 const int r = send(server->socket, req->request, req->request_len, 0);
1843 if (r < 0) {
1844 int err = last_error(server->socket);
1845 if (error_is_eagain(err)) return 1;
1846 nameserver_failed(req->ns, strerror(err));
1847 return 2;
1848 } else if (r != (int)req->request_len) {
1849 return 1; // short write
1850 } else {
1851 return 0;
1855 // try to send a request, updating the fields of the request
1856 // as needed
1858 // return:
1859 // 0 ok
1860 // 1 failed
1861 static int
1862 evdns_request_transmit(struct request *req) {
1863 int retcode = 0, r;
1865 // if we fail to send this packet then this flag marks it
1866 // for evdns_transmit
1867 req->transmit_me = 1;
1868 if (req->trans_id == 0xffff) abort();
1870 if (req->ns->choked) {
1871 // don't bother trying to write to a socket
1872 // which we have had EAGAIN from
1873 return 1;
1876 r = evdns_request_transmit_to(req, req->ns);
1877 switch (r) {
1878 case 1:
1879 // temp failure
1880 req->ns->choked = 1;
1881 nameserver_write_waiting(req->ns, 1);
1882 return 1;
1883 case 2:
1884 // failed in some other way
1885 retcode = 1;
1886 break;
1887 default:
1888 // transmitted; we need to check for timeout.
1889 log(EVDNS_LOG_DEBUG,
1890 "Setting timeout for request %lx", (unsigned long) req);
1891 evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
1892 if (evtimer_add(&req->timeout_event, &global_timeout) < 0) {
1893 log(EVDNS_LOG_WARN,
1894 "Error from libevent when adding timer for request %lx",
1895 (unsigned long) req);
1896 // ???? Do more?
1900 req->tx_count++;
1901 req->transmit_me = 0;
1902 return retcode;
1905 static void
1906 nameserver_probe_callback(int result, char type, int count, int ttl, void *addresses, void *arg) {
1907 struct nameserver *const ns = (struct nameserver *) arg;
1908 (void) type;
1909 (void) count;
1910 (void) ttl;
1911 (void) addresses;
1913 if (result == DNS_ERR_NONE || result == DNS_ERR_NOTEXIST) {
1914 // this is a good reply
1915 nameserver_up(ns);
1916 } else nameserver_probe_failed(ns);
1919 static void
1920 nameserver_send_probe(struct nameserver *const ns) {
1921 struct request *req;
1922 // here we need to send a probe to a given nameserver
1923 // in the hope that it is up now.
1925 log(EVDNS_LOG_DEBUG, "Sending probe to %s", debug_ntoa(ns->address));
1927 req = request_new(TYPE_A, "www.google.com", DNS_QUERY_NO_SEARCH, nameserver_probe_callback, ns);
1928 if (!req) return;
1929 // we force this into the inflight queue no matter what
1930 request_trans_id_set(req, transaction_id_pick());
1931 req->ns = ns;
1932 request_submit(req);
1935 // returns:
1936 // 0 didn't try to transmit anything
1937 // 1 tried to transmit something
1938 static int
1939 evdns_transmit(void) {
1940 char did_try_to_transmit = 0;
1942 if (req_head) {
1943 struct request *const started_at = req_head, *req = req_head;
1944 // first transmit all the requests which are currently waiting
1945 do {
1946 if (req->transmit_me) {
1947 did_try_to_transmit = 1;
1948 evdns_request_transmit(req);
1951 req = req->next;
1952 } while (req != started_at);
1955 return did_try_to_transmit;
1958 // exported function
1960 evdns_count_nameservers(void)
1962 const struct nameserver *server = server_head;
1963 int n = 0;
1964 if (!server)
1965 return 0;
1966 do {
1967 ++n;
1968 server = server->next;
1969 } while (server != server_head);
1970 return n;
1973 // exported function
1975 evdns_clear_nameservers_and_suspend(void)
1977 struct nameserver *server = server_head, *started_at = server_head;
1978 struct request *req = req_head, *req_started_at = req_head;
1980 if (!server)
1981 return 0;
1982 while (1) {
1983 struct nameserver *next = server->next;
1984 (void) event_del(&server->event);
1985 CLEAR(&server->event);
1986 (void) evtimer_del(&server->timeout_event);
1987 CLEAR(&server->timeout_event);
1988 if (server->socket >= 0)
1989 CLOSE_SOCKET(server->socket);
1990 CLEAR(server);
1991 free(server);
1992 if (next == started_at)
1993 break;
1994 server = next;
1996 server_head = NULL;
1997 global_good_nameservers = 0;
1999 while (req) {
2000 struct request *next = req->next;
2001 req->tx_count = req->reissue_count = 0;
2002 req->ns = NULL;
2003 // ???? What to do about searches?
2004 (void) evtimer_del(&req->timeout_event);
2005 CLEAR(&req->timeout_event);
2006 req->trans_id = 0;
2007 req->transmit_me = 0;
2009 global_requests_waiting++;
2010 evdns_request_insert(req, &req_waiting_head);
2011 /* We want to insert these suspended elements at the front of
2012 * the waiting queue, since they were pending before any of
2013 * the waiting entries were added. This is a circular list,
2014 * so we can just shift the start back by one.*/
2015 req_waiting_head = req_waiting_head->prev;
2017 if (next == req_started_at)
2018 break;
2019 req = next;
2021 req_head = NULL;
2022 global_requests_inflight = 0;
2024 return 0;
2028 // exported function
2030 evdns_resume(void)
2032 evdns_requests_pump_waiting_queue();
2033 return 0;
2036 static int
2037 _evdns_nameserver_add_impl(unsigned long int address, int port) {
2038 // first check to see if we already have this nameserver
2040 const struct nameserver *server = server_head, *const started_at = server_head;
2041 struct nameserver *ns;
2042 struct sockaddr_in sin;
2043 int err = 0;
2044 if (server) {
2045 do {
2046 if (server->address == address) return 3;
2047 server = server->next;
2048 } while (server != started_at);
2051 ns = (struct nameserver *) malloc(sizeof(struct nameserver));
2052 if (!ns) return -1;
2054 memset(ns, 0, sizeof(struct nameserver));
2056 ns->socket = socket(PF_INET, SOCK_DGRAM, 0);
2057 if (ns->socket < 0) { err = 1; goto out1; }
2058 #ifdef WIN32
2060 u_long nonblocking = 1;
2061 ioctlsocket(ns->socket, FIONBIO, &nonblocking);
2063 #else
2064 fcntl(ns->socket, F_SETFL, O_NONBLOCK);
2065 #endif
2066 sin.sin_addr.s_addr = address;
2067 sin.sin_port = htons(port);
2068 sin.sin_family = AF_INET;
2069 if (connect(ns->socket, (struct sockaddr *) &sin, sizeof(sin)) != 0) {
2070 err = 2;
2071 goto out2;
2074 ns->address = address;
2075 ns->state = 1;
2076 event_set(&ns->event, ns->socket, EV_READ | EV_PERSIST, nameserver_ready_callback, ns);
2077 if (event_add(&ns->event, NULL) < 0) {
2078 err = 2;
2079 goto out2;
2082 log(EVDNS_LOG_DEBUG, "Added nameserver %s", debug_ntoa(address));
2084 // insert this nameserver into the list of them
2085 if (!server_head) {
2086 ns->next = ns->prev = ns;
2087 server_head = ns;
2088 } else {
2089 ns->next = server_head->next;
2090 ns->prev = server_head;
2091 server_head->next = ns;
2092 if (server_head->prev == server_head) {
2093 server_head->prev = ns;
2097 global_good_nameservers++;
2099 return 0;
2101 out2:
2102 CLOSE_SOCKET(ns->socket);
2103 out1:
2104 CLEAR(ns);
2105 free(ns);
2106 log(EVDNS_LOG_WARN, "Unable to add nameserver %s: error %d", debug_ntoa(address), err);
2107 return err;
2110 // exported function
2112 evdns_nameserver_add(unsigned long int address) {
2113 return _evdns_nameserver_add_impl(address, 53);
2116 // exported function
2118 evdns_nameserver_ip_add(const char *ip_as_string) {
2119 struct in_addr ina;
2120 int port;
2121 char buf[20];
2122 const char *cp;
2123 cp = strchr(ip_as_string, ':');
2124 if (! cp) {
2125 cp = ip_as_string;
2126 port = 53;
2127 } else {
2128 port = strtoint(cp+1);
2129 if (port < 0 || port > 65535) {
2130 return 4;
2132 if ((cp-ip_as_string) >= (int)sizeof(buf)) {
2133 return 4;
2135 memcpy(buf, ip_as_string, cp-ip_as_string);
2136 buf[cp-ip_as_string] = '\0';
2137 cp = buf;
2139 if (!inet_aton(cp, &ina)) {
2140 return 4;
2142 return _evdns_nameserver_add_impl(ina.s_addr, port);
2145 // insert into the tail of the queue
2146 static void
2147 evdns_request_insert(struct request *req, struct request **head) {
2148 if (!*head) {
2149 *head = req;
2150 req->next = req->prev = req;
2151 return;
2154 req->prev = (*head)->prev;
2155 req->prev->next = req;
2156 req->next = *head;
2157 (*head)->prev = req;
2160 static int
2161 string_num_dots(const char *s) {
2162 int count = 0;
2163 while ((s = strchr(s, '.'))) {
2164 s++;
2165 count++;
2167 return count;
2170 static struct request *
2171 request_new(int type, const char *name, int flags,
2172 evdns_callback_type callback, void *user_ptr) {
2173 const char issuing_now =
2174 (global_requests_inflight < global_max_requests_inflight) ? 1 : 0;
2176 const int name_len = strlen(name);
2177 const int request_max_len = evdns_request_len(name_len);
2178 const u16 trans_id = issuing_now ? transaction_id_pick() : 0xffff;
2179 // the request data is alloced in a single block with the header
2180 struct request *const req =
2181 (struct request *) malloc(sizeof(struct request) + request_max_len);
2182 int rlen;
2183 (void) flags;
2185 if (!req) return NULL;
2186 memset(req, 0, sizeof(struct request));
2188 // request data lives just after the header
2189 req->request = ((u8 *) req) + sizeof(struct request);
2190 // denotes that the request data shouldn't be free()ed
2191 req->request_appended = 1;
2192 rlen = evdns_request_data_build(name, name_len, trans_id,
2193 type, CLASS_INET, req->request, request_max_len);
2194 if (rlen < 0)
2195 goto err1;
2196 req->request_len = rlen;
2197 req->trans_id = trans_id;
2198 req->tx_count = 0;
2199 req->request_type = type;
2200 req->user_pointer = user_ptr;
2201 req->user_callback = callback;
2202 req->ns = issuing_now ? nameserver_pick() : NULL;
2203 req->next = req->prev = NULL;
2205 return req;
2206 err1:
2207 CLEAR(req);
2208 free(req);
2209 return NULL;
2212 static void
2213 request_submit(struct request *const req) {
2214 if (req->ns) {
2215 // if it has a nameserver assigned then this is going
2216 // straight into the inflight queue
2217 evdns_request_insert(req, &req_head);
2218 global_requests_inflight++;
2219 evdns_request_transmit(req);
2220 } else {
2221 evdns_request_insert(req, &req_waiting_head);
2222 global_requests_waiting++;
2226 // exported function
2227 int evdns_resolve_ipv4(const char *name, int flags,
2228 evdns_callback_type callback, void *ptr) {
2229 log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
2230 if (flags & DNS_QUERY_NO_SEARCH) {
2231 struct request *const req =
2232 request_new(TYPE_A, name, flags, callback, ptr);
2233 if (req == NULL)
2234 return (1);
2235 request_submit(req);
2236 return (0);
2237 } else {
2238 return (search_request_new(TYPE_A, name, flags, callback, ptr));
2242 // exported function
2243 int evdns_resolve_ipv6(const char *name, int flags,
2244 evdns_callback_type callback, void *ptr) {
2245 log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
2246 if (flags & DNS_QUERY_NO_SEARCH) {
2247 struct request *const req =
2248 request_new(TYPE_AAAA, name, flags, callback, ptr);
2249 if (req == NULL)
2250 return (1);
2251 request_submit(req);
2252 return (0);
2253 } else {
2254 return (search_request_new(TYPE_AAAA, name, flags, callback, ptr));
2258 int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
2259 char buf[32];
2260 struct request *req;
2261 u32 a;
2262 assert(in);
2263 a = ntohl(in->s_addr);
2264 snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
2265 (int)(u8)((a )&0xff),
2266 (int)(u8)((a>>8 )&0xff),
2267 (int)(u8)((a>>16)&0xff),
2268 (int)(u8)((a>>24)&0xff));
2269 log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
2270 req = request_new(TYPE_PTR, buf, flags, callback, ptr);
2271 if (!req) return 1;
2272 request_submit(req);
2273 return 0;
2276 int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
2277 char buf[64];
2278 char *cp;
2279 struct request *req;
2280 int i;
2281 assert(in);
2282 cp = buf;
2283 for (i=15; i >= 0; --i) {
2284 u8 byte = in->s6_addr[i];
2285 *cp++ = "0123456789abcdef"[byte & 0x0f];
2286 *cp++ = '.';
2287 *cp++ = "0123456789abcdef"[byte >> 4];
2288 *cp++ = '.';
2290 assert(cp + strlen(".ip6.arpa") < buf+sizeof(buf));
2291 memcpy(cp, ".ip6.arpa", strlen(".ip6.arpa")+1);
2292 log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
2293 req = request_new(TYPE_PTR, buf, flags, callback, ptr);
2294 if (!req) return 1;
2295 request_submit(req);
2296 return 0;
2300 /////////////////////////////////////////////////////////////////////
2301 // Search support
2303 // the libc resolver has support for searching a number of domains
2304 // to find a name. If nothing else then it takes the single domain
2305 // from the gethostname() call.
2307 // It can also be configured via the domain and search options in a
2308 // resolv.conf.
2310 // The ndots option controls how many dots it takes for the resolver
2311 // to decide that a name is non-local and so try a raw lookup first.
2313 struct search_domain {
2314 int len;
2315 struct search_domain *next;
2316 // the text string is appended to this structure
2319 struct search_state {
2320 int refcount;
2321 int ndots;
2322 int num_domains;
2323 struct search_domain *head;
2326 static struct search_state *global_search_state = NULL;
2328 static void
2329 search_state_decref(struct search_state *const state) {
2330 if (!state) return;
2331 state->refcount--;
2332 if (!state->refcount) {
2333 struct search_domain *next, *dom;
2334 for (dom = state->head; dom; dom = next) {
2335 next = dom->next;
2336 CLEAR(dom);
2337 free(dom);
2339 CLEAR(state);
2340 free(state);
2344 static struct search_state *
2345 search_state_new(void) {
2346 struct search_state *state = (struct search_state *) malloc(sizeof(struct search_state));
2347 if (!state) return NULL;
2348 memset(state, 0, sizeof(struct search_state));
2349 state->refcount = 1;
2350 state->ndots = 1;
2352 return state;
2355 static void
2356 search_postfix_clear(void) {
2357 search_state_decref(global_search_state);
2359 global_search_state = search_state_new();
2362 // exported function
2363 void
2364 evdns_search_clear(void) {
2365 search_postfix_clear();
2368 static void
2369 search_postfix_add(const char *domain) {
2370 int domain_len;
2371 struct search_domain *sdomain;
2372 while (domain[0] == '.') domain++;
2373 domain_len = strlen(domain);
2375 if (!global_search_state) global_search_state = search_state_new();
2376 if (!global_search_state) return;
2377 global_search_state->num_domains++;
2379 sdomain = (struct search_domain *) malloc(sizeof(struct search_domain) + domain_len);
2380 if (!sdomain) return;
2381 memcpy( ((u8 *) sdomain) + sizeof(struct search_domain), domain, domain_len);
2382 sdomain->next = global_search_state->head;
2383 sdomain->len = domain_len;
2385 global_search_state->head = sdomain;
2388 // reverse the order of members in the postfix list. This is needed because,
2389 // when parsing resolv.conf we push elements in the wrong order
2390 static void
2391 search_reverse(void) {
2392 struct search_domain *cur, *prev = NULL, *next;
2393 cur = global_search_state->head;
2394 while (cur) {
2395 next = cur->next;
2396 cur->next = prev;
2397 prev = cur;
2398 cur = next;
2401 global_search_state->head = prev;
2404 // exported function
2405 void
2406 evdns_search_add(const char *domain) {
2407 search_postfix_add(domain);
2410 // exported function
2411 void
2412 evdns_search_ndots_set(const int ndots) {
2413 if (!global_search_state) global_search_state = search_state_new();
2414 if (!global_search_state) return;
2415 global_search_state->ndots = ndots;
2418 static void
2419 search_set_from_hostname(void) {
2420 char hostname[HOST_NAME_MAX + 1], *domainname;
2422 search_postfix_clear();
2423 if (gethostname(hostname, sizeof(hostname))) return;
2424 domainname = strchr(hostname, '.');
2425 if (!domainname) return;
2426 search_postfix_add(domainname);
2429 // warning: returns malloced string
2430 static char *
2431 search_make_new(const struct search_state *const state, int n, const char *const base_name) {
2432 const int base_len = strlen(base_name);
2433 const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
2434 struct search_domain *dom;
2436 for (dom = state->head; dom; dom = dom->next) {
2437 if (!n--) {
2438 // this is the postfix we want
2439 // the actual postfix string is kept at the end of the structure
2440 const u8 *const postfix = ((u8 *) dom) + sizeof(struct search_domain);
2441 const int postfix_len = dom->len;
2442 char *const newname = (char *) malloc(base_len + need_to_append_dot + postfix_len + 1);
2443 if (!newname) return NULL;
2444 memcpy(newname, base_name, base_len);
2445 if (need_to_append_dot) newname[base_len] = '.';
2446 memcpy(newname + base_len + need_to_append_dot, postfix, postfix_len);
2447 newname[base_len + need_to_append_dot + postfix_len] = 0;
2448 return newname;
2452 // we ran off the end of the list and still didn't find the requested string
2453 abort();
2454 return NULL; /* unreachable; stops warnings in some compilers. */
2457 static int
2458 search_request_new(int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg) {
2459 assert(type == TYPE_A || type == TYPE_AAAA);
2460 if ( ((flags & DNS_QUERY_NO_SEARCH) == 0) &&
2461 global_search_state &&
2462 global_search_state->num_domains) {
2463 // we have some domains to search
2464 struct request *req;
2465 if (string_num_dots(name) >= global_search_state->ndots) {
2466 req = request_new(type, name, flags, user_callback, user_arg);
2467 if (!req) return 1;
2468 req->search_index = -1;
2469 } else {
2470 char *const new_name = search_make_new(global_search_state, 0, name);
2471 if (!new_name) return 1;
2472 req = request_new(type, new_name, flags, user_callback, user_arg);
2473 free(new_name);
2474 if (!req) return 1;
2475 req->search_index = 0;
2477 req->search_origname = strdup(name);
2478 req->search_state = global_search_state;
2479 req->search_flags = flags;
2480 global_search_state->refcount++;
2481 request_submit(req);
2482 return 0;
2483 } else {
2484 struct request *const req = request_new(type, name, flags, user_callback, user_arg);
2485 if (!req) return 1;
2486 request_submit(req);
2487 return 0;
2491 // this is called when a request has failed to find a name. We need to check
2492 // if it is part of a search and, if so, try the next name in the list
2493 // returns:
2494 // 0 another request has been submitted
2495 // 1 no more requests needed
2496 static int
2497 search_try_next(struct request *const req) {
2498 if (req->search_state) {
2499 // it is part of a search
2500 char *new_name;
2501 struct request *newreq;
2502 req->search_index++;
2503 if (req->search_index >= req->search_state->num_domains) {
2504 // no more postfixes to try, however we may need to try
2505 // this name without a postfix
2506 if (string_num_dots(req->search_origname) < req->search_state->ndots) {
2507 // yep, we need to try it raw
2508 struct request *const newreq = request_new(req->request_type, req->search_origname, req->search_flags, req->user_callback, req->user_pointer);
2509 log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", req->search_origname);
2510 if (newreq) {
2511 request_submit(newreq);
2512 return 0;
2515 return 1;
2518 new_name = search_make_new(req->search_state, req->search_index, req->search_origname);
2519 if (!new_name) return 1;
2520 log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, req->search_index);
2521 newreq = request_new(req->request_type, new_name, req->search_flags, req->user_callback, req->user_pointer);
2522 free(new_name);
2523 if (!newreq) return 1;
2524 newreq->search_origname = req->search_origname;
2525 req->search_origname = NULL;
2526 newreq->search_state = req->search_state;
2527 newreq->search_flags = req->search_flags;
2528 newreq->search_index = req->search_index;
2529 newreq->search_state->refcount++;
2530 request_submit(newreq);
2531 return 0;
2533 return 1;
2536 static void
2537 search_request_finished(struct request *const req) {
2538 if (req->search_state) {
2539 search_state_decref(req->search_state);
2540 req->search_state = NULL;
2542 if (req->search_origname) {
2543 free(req->search_origname);
2544 req->search_origname = NULL;
2548 /////////////////////////////////////////////////////////////////////
2549 // Parsing resolv.conf files
2551 static void
2552 evdns_resolv_set_defaults(int flags) {
2553 // if the file isn't found then we assume a local resolver
2554 if (flags & DNS_OPTION_SEARCH) search_set_from_hostname();
2555 if (flags & DNS_OPTION_NAMESERVERS) evdns_nameserver_ip_add("127.0.0.1");
2558 #ifndef HAVE_STRTOK_R
2559 static char *
2560 strtok_r(char *s, const char *delim, char **state) {
2561 (void)state;
2562 return strtok(s, delim);
2564 #endif
2566 // helper version of atoi which returns -1 on error
2567 static int
2568 strtoint(const char *const str) {
2569 char *endptr;
2570 const int r = strtol(str, &endptr, 10);
2571 if (*endptr) return -1;
2572 return r;
2575 // helper version of atoi that returns -1 on error and clips to bounds.
2576 static int
2577 strtoint_clipped(const char *const str, int min, int max)
2579 int r = strtoint(str);
2580 if (r == -1)
2581 return r;
2582 else if (r<min)
2583 return min;
2584 else if (r>max)
2585 return max;
2586 else
2587 return r;
2590 // exported function
2592 evdns_set_option(const char *option, const char *val, int flags)
2594 if (!strncmp(option, "ndots:", 6)) {
2595 const int ndots = strtoint(val);
2596 if (ndots == -1) return -1;
2597 if (!(flags & DNS_OPTION_SEARCH)) return 0;
2598 log(EVDNS_LOG_DEBUG, "Setting ndots to %d", ndots);
2599 if (!global_search_state) global_search_state = search_state_new();
2600 if (!global_search_state) return -1;
2601 global_search_state->ndots = ndots;
2602 } else if (!strncmp(option, "timeout:", 8)) {
2603 const int timeout = strtoint(val);
2604 if (timeout == -1) return -1;
2605 if (!(flags & DNS_OPTION_MISC)) return 0;
2606 log(EVDNS_LOG_DEBUG, "Setting timeout to %d", timeout);
2607 global_timeout.tv_sec = timeout;
2608 } else if (!strncmp(option, "max-timeouts:", 12)) {
2609 const int maxtimeout = strtoint_clipped(val, 1, 255);
2610 if (maxtimeout == -1) return -1;
2611 if (!(flags & DNS_OPTION_MISC)) return 0;
2612 log(EVDNS_LOG_DEBUG, "Setting maximum allowed timeouts to %d",
2613 maxtimeout);
2614 global_max_nameserver_timeout = maxtimeout;
2615 } else if (!strncmp(option, "max-inflight:", 13)) {
2616 const int maxinflight = strtoint_clipped(val, 1, 65000);
2617 if (maxinflight == -1) return -1;
2618 if (!(flags & DNS_OPTION_MISC)) return 0;
2619 log(EVDNS_LOG_DEBUG, "Setting maximum inflight requests to %d",
2620 maxinflight);
2621 global_max_requests_inflight = maxinflight;
2622 } else if (!strncmp(option, "attempts:", 9)) {
2623 int retries = strtoint(val);
2624 if (retries == -1) return -1;
2625 if (retries > 255) retries = 255;
2626 if (!(flags & DNS_OPTION_MISC)) return 0;
2627 log(EVDNS_LOG_DEBUG, "Setting retries to %d", retries);
2628 global_max_retransmits = retries;
2630 return 0;
2633 static void
2634 resolv_conf_parse_line(char *const start, int flags) {
2635 char *strtok_state;
2636 static const char *const delims = " \t";
2637 #define NEXT_TOKEN strtok_r(NULL, delims, &strtok_state)
2639 char *const first_token = strtok_r(start, delims, &strtok_state);
2640 if (!first_token) return;
2642 if (!strcmp(first_token, "nameserver") && (flags & DNS_OPTION_NAMESERVERS)) {
2643 const char *const nameserver = NEXT_TOKEN;
2644 struct in_addr ina;
2646 if (inet_aton(nameserver, &ina)) {
2647 // address is valid
2648 evdns_nameserver_add(ina.s_addr);
2650 } else if (!strcmp(first_token, "domain") && (flags & DNS_OPTION_SEARCH)) {
2651 const char *const domain = NEXT_TOKEN;
2652 if (domain) {
2653 search_postfix_clear();
2654 search_postfix_add(domain);
2656 } else if (!strcmp(first_token, "search") && (flags & DNS_OPTION_SEARCH)) {
2657 const char *domain;
2658 search_postfix_clear();
2660 while ((domain = NEXT_TOKEN)) {
2661 search_postfix_add(domain);
2663 search_reverse();
2664 } else if (!strcmp(first_token, "options")) {
2665 const char *option;
2666 while ((option = NEXT_TOKEN)) {
2667 const char *val = strchr(option, ':');
2668 evdns_set_option(option, val ? val+1 : "", flags);
2671 #undef NEXT_TOKEN
2674 // exported function
2675 // returns:
2676 // 0 no errors
2677 // 1 failed to open file
2678 // 2 failed to stat file
2679 // 3 file too large
2680 // 4 out of memory
2681 // 5 short read from file
2683 evdns_resolv_conf_parse(int flags, const char *const filename) {
2684 struct stat st;
2685 int fd, n, r;
2686 u8 *resolv;
2687 char *start;
2688 int err = 0;
2690 log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
2692 fd = open(filename, O_RDONLY);
2693 if (fd < 0) {
2694 evdns_resolv_set_defaults(flags);
2695 return 1;
2698 if (fstat(fd, &st)) { err = 2; goto out1; }
2699 if (!st.st_size) {
2700 evdns_resolv_set_defaults(flags);
2701 err = (flags & DNS_OPTION_NAMESERVERS) ? 6 : 0;
2702 goto out1;
2704 if (st.st_size > 65535) { err = 3; goto out1; } // no resolv.conf should be any bigger
2706 resolv = (u8 *) malloc((size_t)st.st_size + 1);
2707 if (!resolv) { err = 4; goto out1; }
2709 n = 0;
2710 while ((r = read(fd, resolv+n, (size_t)st.st_size-n)) > 0) {
2711 n += r;
2712 if (n == st.st_size)
2713 break;
2714 assert(n < st.st_size);
2716 if (r < 0) { err = 5; goto out2; }
2717 resolv[n] = 0; // we malloced an extra byte; this should be fine.
2719 start = (char *) resolv;
2720 for (;;) {
2721 char *const newline = strchr(start, '\n');
2722 if (!newline) {
2723 resolv_conf_parse_line(start, flags);
2724 break;
2725 } else {
2726 *newline = 0;
2727 resolv_conf_parse_line(start, flags);
2728 start = newline + 1;
2732 if (!server_head && (flags & DNS_OPTION_NAMESERVERS)) {
2733 // no nameservers were configured.
2734 evdns_nameserver_ip_add("127.0.0.1");
2735 err = 6;
2737 if (flags & DNS_OPTION_SEARCH && (!global_search_state || global_search_state->num_domains == 0)) {
2738 search_set_from_hostname();
2741 out2:
2742 free(resolv);
2743 out1:
2744 close(fd);
2745 return err;
2748 #ifdef WIN32
2749 // Add multiple nameservers from a space-or-comma-separated list.
2750 static int
2751 evdns_nameserver_ip_add_line(const char *ips) {
2752 const char *addr;
2753 char *buf;
2754 int r;
2755 while (*ips) {
2756 while (ISSPACE(*ips) || *ips == ',' || *ips == '\t')
2757 ++ips;
2758 addr = ips;
2759 while (ISDIGIT(*ips) || *ips == '.' || *ips == ':')
2760 ++ips;
2761 buf = malloc(ips-addr+1);
2762 if (!buf) return 4;
2763 memcpy(buf, addr, ips-addr);
2764 buf[ips-addr] = '\0';
2765 r = evdns_nameserver_ip_add(buf);
2766 free(buf);
2767 if (r) return r;
2769 return 0;
2772 typedef DWORD(WINAPI *GetNetworkParams_fn_t)(FIXED_INFO *, DWORD*);
2774 // Use the windows GetNetworkParams interface in iphlpapi.dll to
2775 // figure out what our nameservers are.
2776 static int
2777 load_nameservers_with_getnetworkparams(void)
2779 // Based on MSDN examples and inspection of c-ares code.
2780 FIXED_INFO *fixed;
2781 HMODULE handle = 0;
2782 ULONG size = sizeof(FIXED_INFO);
2783 void *buf = NULL;
2784 int status = 0, r, added_any;
2785 IP_ADDR_STRING *ns;
2786 GetNetworkParams_fn_t fn;
2788 /* XXXX Possibly, we should hardcode the location of this DLL. */
2789 if (!(handle = LoadLibrary("iphlpapi.dll"))) {
2790 log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
2791 //right now status = 0, doesn't that mean "good" - mikec
2792 status = -1;
2793 goto done;
2795 if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, "GetNetworkParams"))) {
2796 log(EVDNS_LOG_WARN, "Could not get address of function.");
2797 //same as above
2798 status = -1;
2799 goto done;
2802 buf = malloc(size);
2803 if (!buf) { status = 4; goto done; }
2804 fixed = buf;
2805 r = fn(fixed, &size);
2806 if (r != ERROR_SUCCESS && r != ERROR_BUFFER_OVERFLOW) {
2807 status = -1;
2808 goto done;
2810 if (r != ERROR_SUCCESS) {
2811 free(buf);
2812 buf = malloc(size);
2813 if (!buf) { status = 4; goto done; }
2814 fixed = buf;
2815 r = fn(fixed, &size);
2816 if (r != ERROR_SUCCESS) {
2817 log(EVDNS_LOG_DEBUG, "fn() failed.");
2818 status = -1;
2819 goto done;
2823 assert(fixed);
2824 added_any = 0;
2825 ns = &(fixed->DnsServerList);
2826 while (ns) {
2827 r = evdns_nameserver_ip_add_line(ns->IpAddress.String);
2828 if (r) {
2829 log(EVDNS_LOG_DEBUG,"Could not add nameserver %s to list,error: %d",
2830 (ns->IpAddress.String),(int)GetLastError());
2831 status = r;
2832 goto done;
2833 } else {
2834 log(EVDNS_LOG_DEBUG,"Succesfully added %s as nameserver",ns->IpAddress.String);
2837 added_any++;
2838 ns = ns->Next;
2841 if (!added_any) {
2842 log(EVDNS_LOG_DEBUG, "No nameservers added.");
2843 status = -1;
2846 done:
2847 if (buf)
2848 free(buf);
2849 if (handle)
2850 FreeLibrary(handle);
2851 return status;
2854 static int
2855 config_nameserver_from_reg_key(HKEY key, const char *subkey)
2857 char *buf;
2858 DWORD bufsz = 0, type = 0;
2859 int status = 0;
2861 if (RegQueryValueEx(key, subkey, 0, &type, NULL, &bufsz)
2862 != ERROR_MORE_DATA)
2863 return -1;
2864 if (!(buf = malloc(bufsz)))
2865 return -1;
2867 if (RegQueryValueEx(key, subkey, 0, &type, (LPBYTE)buf, &bufsz)
2868 == ERROR_SUCCESS && bufsz > 1) {
2869 status = evdns_nameserver_ip_add_line(buf);
2872 free(buf);
2873 return status;
2876 #define SERVICES_KEY "System\\CurrentControlSet\\Services\\"
2877 #define WIN_NS_9X_KEY SERVICES_KEY "VxD\\MSTCP"
2878 #define WIN_NS_NT_KEY SERVICES_KEY "Tcpip\\Parameters"
2880 static int
2881 load_nameservers_from_registry(void)
2883 int found = 0;
2884 int r;
2885 #define TRY(k, name) \
2886 if (!found && config_nameserver_from_reg_key(k,name) == 0) { \
2887 log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name); \
2888 found = 1; \
2889 } else if (!found) { \
2890 log(EVDNS_LOG_DEBUG,"Didn't find nameservers in %s/%s", \
2891 #k,#name); \
2894 if (((int)GetVersion()) > 0) { /* NT */
2895 HKEY nt_key = 0, interfaces_key = 0;
2897 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
2898 KEY_READ, &nt_key) != ERROR_SUCCESS) {
2899 log(EVDNS_LOG_DEBUG,"Couldn't open nt key, %d",(int)GetLastError());
2900 return -1;
2902 r = RegOpenKeyEx(nt_key, "Interfaces", 0,
2903 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
2904 &interfaces_key);
2905 if (r != ERROR_SUCCESS) {
2906 log(EVDNS_LOG_DEBUG,"Couldn't open interfaces key, %d",(int)GetLastError());
2907 return -1;
2909 TRY(nt_key, "NameServer");
2910 TRY(nt_key, "DhcpNameServer");
2911 TRY(interfaces_key, "NameServer");
2912 TRY(interfaces_key, "DhcpNameServer");
2913 RegCloseKey(interfaces_key);
2914 RegCloseKey(nt_key);
2915 } else {
2916 HKEY win_key = 0;
2917 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X_KEY, 0,
2918 KEY_READ, &win_key) != ERROR_SUCCESS) {
2919 log(EVDNS_LOG_DEBUG, "Couldn't open registry key, %d", (int)GetLastError());
2920 return -1;
2922 TRY(win_key, "NameServer");
2923 RegCloseKey(win_key);
2926 if (found == 0) {
2927 log(EVDNS_LOG_WARN,"Didn't find any nameservers.");
2930 return found ? 0 : -1;
2931 #undef TRY
2935 evdns_config_windows_nameservers(void)
2937 if (load_nameservers_with_getnetworkparams() == 0)
2938 return 0;
2939 return load_nameservers_from_registry();
2941 #endif
2944 evdns_init(void)
2946 int res = 0;
2947 #ifdef WIN32
2948 evdns_config_windows_nameservers();
2949 #else
2950 res = evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf");
2951 #endif
2953 return (res);
2956 const char *
2957 evdns_err_to_string(int err)
2959 switch (err) {
2960 case DNS_ERR_NONE: return "no error";
2961 case DNS_ERR_FORMAT: return "misformatted query";
2962 case DNS_ERR_SERVERFAILED: return "server failed";
2963 case DNS_ERR_NOTEXIST: return "name does not exist";
2964 case DNS_ERR_NOTIMPL: return "query not implemented";
2965 case DNS_ERR_REFUSED: return "refused";
2967 case DNS_ERR_TRUNCATED: return "reply truncated or ill-formed";
2968 case DNS_ERR_UNKNOWN: return "unknown";
2969 case DNS_ERR_TIMEOUT: return "request timed out";
2970 case DNS_ERR_SHUTDOWN: return "dns subsystem shut down";
2971 default: return "[Unknown error code]";
2975 void
2976 evdns_shutdown(int fail_requests)
2978 struct nameserver *server, *server_next;
2979 struct search_domain *dom, *dom_next;
2981 while (req_head) {
2982 if (fail_requests)
2983 reply_callback(req_head, 0, DNS_ERR_SHUTDOWN, NULL);
2984 request_finished(req_head, &req_head);
2986 while (req_waiting_head) {
2987 if (fail_requests)
2988 reply_callback(req_waiting_head, 0, DNS_ERR_SHUTDOWN, NULL);
2989 request_finished(req_waiting_head, &req_waiting_head);
2991 global_requests_inflight = global_requests_waiting = 0;
2993 for (server = server_head; server; server = server_next) {
2994 server_next = server->next;
2995 if (server->socket >= 0)
2996 CLOSE_SOCKET(server->socket);
2997 (void) event_del(&server->event);
2998 CLEAR(server);
2999 free(server);
3000 if (server_next == server_head)
3001 break;
3003 server_head = NULL;
3004 global_good_nameservers = 0;
3006 if (global_search_state) {
3007 for (dom = global_search_state->head; dom; dom = dom_next) {
3008 dom_next = dom->next;
3009 CLEAR(dom);
3010 free(dom);
3012 CLEAR(global_search_state);
3013 free(global_search_state);
3014 global_search_state = NULL;
3016 evdns_log_fn = NULL;
3019 #ifdef EVDNS_MAIN
3020 void
3021 main_callback(int result, char type, int count, int ttl,
3022 void *addrs, void *orig) {
3023 char *n = (char*)orig;
3024 int i;
3025 for (i = 0; i < count; ++i) {
3026 if (type == DNS_IPv4_A) {
3027 printf("%s: %s\n", n, debug_ntoa(((u32*)addrs)[i]));
3028 } else if (type == DNS_PTR) {
3029 printf("%s: %s\n", n, ((char**)addrs)[i]);
3032 if (!count) {
3033 printf("%s: No answer (%d)\n", n, result);
3035 fflush(stdout);
3037 void
3038 evdns_server_callback(struct evdns_server_request *req, void *data)
3040 int i, r;
3041 (void)data;
3042 /* dummy; give 192.168.11.11 as an answer for all A questions,
3043 * give foo.bar.example.com as an answer for all PTR questions. */
3044 for (i = 0; i < req->nquestions; ++i) {
3045 u32 ans = htonl(0xc0a80b0bUL);
3046 if (req->questions[i]->type == EVDNS_TYPE_A &&
3047 req->questions[i]->class == EVDNS_CLASS_INET) {
3048 printf(" -- replying for %s (A)\n", req->questions[i]->name);
3049 r = evdns_server_request_add_a_reply(req, req->questions[i]->name,
3050 1, &ans, 10);
3051 if (r<0)
3052 printf("eeep, didn't work.\n");
3053 } else if (req->questions[i]->type == EVDNS_TYPE_PTR &&
3054 req->questions[i]->class == EVDNS_CLASS_INET) {
3055 printf(" -- replying for %s (PTR)\n", req->questions[i]->name);
3056 r = evdns_server_request_add_ptr_reply(req, NULL, req->questions[i]->name,
3057 "foo.bar.example.com", 10);
3058 } else {
3059 printf(" -- skipping %s [%d %d]\n", req->questions[i]->name,
3060 req->questions[i]->type, req->questions[i]->class);
3064 r = evdns_request_respond(req, 0);
3065 if (r<0)
3066 printf("eeek, couldn't send reply.\n");
3069 void
3070 logfn(int is_warn, const char *msg) {
3071 (void) is_warn;
3072 fprintf(stderr, "%s\n", msg);
3075 main(int c, char **v) {
3076 int idx;
3077 int reverse = 0, verbose = 1, servertest = 0;
3078 if (c<2) {
3079 fprintf(stderr, "syntax: %s [-x] [-v] hostname\n", v[0]);
3080 fprintf(stderr, "syntax: %s [-servertest]\n", v[0]);
3081 return 1;
3083 idx = 1;
3084 while (idx < c && v[idx][0] == '-') {
3085 if (!strcmp(v[idx], "-x"))
3086 reverse = 1;
3087 else if (!strcmp(v[idx], "-v"))
3088 verbose = 1;
3089 else if (!strcmp(v[idx], "-servertest"))
3090 servertest = 1;
3091 else
3092 fprintf(stderr, "Unknown option %s\n", v[idx]);
3093 ++idx;
3095 event_init();
3096 if (verbose)
3097 evdns_set_log_fn(logfn);
3098 evdns_resolv_conf_parse(DNS_OPTION_NAMESERVERS, "/etc/resolv.conf");
3099 if (servertest) {
3100 int sock;
3101 struct sockaddr_in my_addr;
3102 sock = socket(PF_INET, SOCK_DGRAM, 0);
3103 fcntl(sock, F_SETFL, O_NONBLOCK);
3104 my_addr.sin_family = AF_INET;
3105 my_addr.sin_port = htons(10053);
3106 my_addr.sin_addr.s_addr = INADDR_ANY;
3107 if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr))<0) {
3108 perror("bind");
3109 exit(1);
3111 evdns_add_server_port(sock, 0, evdns_server_callback, NULL);
3113 for (; idx < c; ++idx) {
3114 if (reverse) {
3115 struct in_addr addr;
3116 if (!inet_aton(v[idx], &addr)) {
3117 fprintf(stderr, "Skipping non-IP %s\n", v[idx]);
3118 continue;
3120 fprintf(stderr, "resolving %s...\n",v[idx]);
3121 evdns_resolve_reverse(&addr, 0, main_callback, v[idx]);
3122 } else {
3123 fprintf(stderr, "resolving (fwd) %s...\n",v[idx]);
3124 evdns_resolve_ipv4(v[idx], 0, main_callback, v[idx]);
3127 fflush(stdout);
3128 event_dispatch();
3129 return 0;
3131 #endif
3133 // Local Variables:
3134 // tab-width: 4
3135 // c-basic-offset: 4
3136 // indent-tabs-mode: t
3137 // End: