r11919@Kushana: nickm | 2007-01-10 13:32:48 -0500
[tor.git] / src / or / eventdns.c
blob34767a42766f250970464e31481c64762448bccd
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 #ifdef WIN32
326 static int
327 last_error(int sock)
329 int optval, optvallen=sizeof(optval);
330 int err = WSAGetLastError();
331 if (err == WSAEWOULDBLOCK && sock >= 0) {
332 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
333 &optvallen))
334 return err;
335 if (optval)
336 return optval;
338 return err;
341 static int
342 error_is_eagain(int err)
344 return err == EAGAIN || err == WSAEWOULDBLOCK;
346 static int
347 inet_aton(const char *c, struct in_addr *addr)
349 uint32_t r;
350 if (strcmp(c, "255.255.255.255") == 0) {
351 addr->s_addr = 0xffffffffu;
352 } else {
353 r = inet_addr(c);
354 if (r == INADDR_NONE)
355 return 0;
356 addr->s_addr = r;
358 return 1;
360 #define CLOSE_SOCKET(x) closesocket(x)
361 #else
362 #define last_error(sock) (errno)
363 #define error_is_eagain(err) ((err) == EAGAIN)
364 #define CLOSE_SOCKET(x) close(x)
365 #endif
367 #define ISSPACE(c) isspace((int)(unsigned char)(c))
368 #define ISDIGIT(c) isdigit((int)(unsigned char)(c))
370 #ifndef NDEBUG
371 static const char *
372 debug_ntoa(u32 address)
374 static char buf[32];
375 u32 a = ntohl(address);
376 sprintf(buf, "%d.%d.%d.%d",
377 (int)(u8)((a>>24)&0xff),
378 (int)(u8)((a>>16)&0xff),
379 (int)(u8)((a>>8 )&0xff),
380 (int)(u8)((a )&0xff));
381 return buf;
383 #endif
385 static evdns_debug_log_fn_type evdns_log_fn = NULL;
387 void
388 evdns_set_log_fn(evdns_debug_log_fn_type fn)
390 evdns_log_fn = fn;
393 #ifdef __GNUC__
394 #define EVDNS_LOG_CHECK __attribute__ ((format(printf, 2, 3)))
395 #else
396 #define EVDNS_LOG_CHECK
397 #endif
399 static void _evdns_log(int warn, const char *fmt, ...) EVDNS_LOG_CHECK;
400 static void
401 _evdns_log(int warn, const char *fmt, ...)
403 va_list args;
404 static char buf[512];
405 if (!evdns_log_fn)
406 return;
407 va_start(args,fmt);
408 #ifdef WIN32
409 _vsnprintf(buf, sizeof(buf), fmt, args);
410 #else
411 vsnprintf(buf, sizeof(buf), fmt, args);
412 #endif
413 buf[sizeof(buf)-1] = '\0';
414 evdns_log_fn(warn, buf);
415 va_end(args);
418 #define log _evdns_log
420 // This walks the list of inflight requests to find the
421 // one with a matching transaction id. Returns NULL on
422 // failure
423 static struct request *
424 request_find_from_trans_id(u16 trans_id) {
425 struct request *req = req_head, *const started_at = req_head;
427 if (req) {
428 do {
429 if (req->trans_id == trans_id) return req;
430 req = req->next;
431 } while (req != started_at);
434 return NULL;
437 // a libevent callback function which is called when a nameserver
438 // has gone down and we want to test if it has came back to life yet
439 static void
440 nameserver_prod_callback(int fd, short events, void *arg) {
441 struct nameserver *const ns = (struct nameserver *) arg;
442 (void)fd;
443 (void)events;
445 nameserver_send_probe(ns);
448 // a libevent callback which is called when a nameserver probe (to see if
449 // it has come back to life) times out. We increment the count of failed_times
450 // and wait longer to send the next probe packet.
451 static void
452 nameserver_probe_failed(struct nameserver *const ns) {
453 const struct timeval * timeout;
454 (void) evtimer_del(&ns->timeout_event);
455 CLEAR(&ns->timeout_event);
456 if (ns->state == 1) {
457 // This can happen if the nameserver acts in a way which makes us mark
458 // it as bad and then starts sending good replies.
459 return;
462 timeout =
463 &global_nameserver_timeouts[MIN(ns->failed_times,
464 global_nameserver_timeouts_length - 1)];
465 ns->failed_times++;
467 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
468 if (evtimer_add(&ns->timeout_event, (struct timeval *) timeout) < 0) {
469 log(EVDNS_LOG_WARN,
470 "Error from libevent when adding timer event for %s",
471 debug_ntoa(ns->address));
472 // ???? Do more?
476 // called when a nameserver has been deemed to have failed. For example, too
477 // many packets have timed out etc
478 static void
479 nameserver_failed(struct nameserver *const ns, const char *msg) {
480 struct request *req, *started_at;
481 // if this nameserver has already been marked as failed
482 // then don't do anything
483 if (!ns->state) return;
485 log(EVDNS_LOG_WARN, "Nameserver %s has failed: %s",
486 debug_ntoa(ns->address), msg);
487 global_good_nameservers--;
488 assert(global_good_nameservers >= 0);
489 if (global_good_nameservers == 0) {
490 log(EVDNS_LOG_WARN, "All nameservers have failed");
493 ns->state = 0;
494 ns->failed_times = 1;
496 evtimer_set(&ns->timeout_event, nameserver_prod_callback, ns);
497 if (evtimer_add(&ns->timeout_event, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
498 log(EVDNS_LOG_WARN,
499 "Error from libevent when adding timer event for %s",
500 debug_ntoa(ns->address));
501 // ???? Do more?
504 // walk the list of inflight requests to see if any can be reassigned to
505 // a different server. Requests in the waiting queue don't have a
506 // nameserver assigned yet
508 // if we don't have *any* good nameservers then there's no point
509 // trying to reassign requests to one
510 if (!global_good_nameservers) return;
512 req = req_head;
513 started_at = req_head;
514 if (req) {
515 do {
516 if (req->tx_count == 0 && req->ns == ns) {
517 // still waiting to go out, can be moved
518 // to another server
519 req->ns = nameserver_pick();
521 req = req->next;
522 } while (req != started_at);
526 static void
527 nameserver_up(struct nameserver *const ns) {
528 if (ns->state) return;
529 log(EVDNS_LOG_WARN, "Nameserver %s is back up",
530 debug_ntoa(ns->address));
531 evtimer_del(&ns->timeout_event);
532 CLEAR(&ns->timeout_event);
533 ns->state = 1;
534 ns->failed_times = 0;
535 ns->timedout = 0;
536 global_good_nameservers++;
539 static void
540 request_trans_id_set(struct request *const req, const u16 trans_id) {
541 req->trans_id = trans_id;
542 *((u16 *) req->request) = htons(trans_id);
545 // Called to remove a request from a list and dealloc it.
546 // head is a pointer to the head of the list it should be
547 // removed from or NULL if the request isn't in a list.
548 static void
549 request_finished(struct request *const req, struct request **head) {
550 if (head) {
551 if (req->next == req) {
552 // only item in the list
553 *head = NULL;
554 } else {
555 req->next->prev = req->prev;
556 req->prev->next = req->next;
557 if (*head == req) *head = req->next;
561 log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
562 (unsigned long) req);
563 evtimer_del(&req->timeout_event);
564 CLEAR(&req->timeout_event);
566 search_request_finished(req);
567 global_requests_inflight--;
569 if (!req->request_appended) {
570 // need to free the request data on it's own
571 free(req->request);
572 } else {
573 // the request data is appended onto the header
574 // so everything gets free()ed when we:
577 CLEAR(req);
578 free(req);
580 evdns_requests_pump_waiting_queue();
583 // This is called when a server returns a funny error code.
584 // We try the request again with another server.
586 // return:
587 // 0 ok
588 // 1 failed/reissue is pointless
589 static int
590 request_reissue(struct request *req) {
591 const struct nameserver *const last_ns = req->ns;
592 // the last nameserver should have been marked as failing
593 // by the caller of this function, therefore pick will try
594 // not to return it
595 req->ns = nameserver_pick();
596 if (req->ns == last_ns) {
597 // ... but pick did return it
598 // not a lot of point in trying again with the
599 // same server
600 return 1;
603 req->reissue_count++;
604 req->tx_count = 0;
605 req->transmit_me = 1;
607 return 0;
610 // this function looks for space on the inflight queue and promotes
611 // requests from the waiting queue if it can.
612 static void
613 evdns_requests_pump_waiting_queue(void) {
614 while (global_requests_inflight < global_max_requests_inflight &&
615 global_requests_waiting) {
616 struct request *req;
617 // move a request from the waiting queue to the inflight queue
618 assert(req_waiting_head);
619 if (req_waiting_head->next == req_waiting_head) {
620 // only one item in the queue
621 req = req_waiting_head;
622 req_waiting_head = NULL;
623 } else {
624 req = req_waiting_head;
625 req->next->prev = req->prev;
626 req->prev->next = req->next;
627 req_waiting_head = req->next;
630 global_requests_waiting--;
631 global_requests_inflight++;
633 req->ns = nameserver_pick();
634 request_trans_id_set(req, transaction_id_pick());
636 evdns_request_insert(req, &req_head);
637 evdns_request_transmit(req);
638 evdns_transmit();
642 static void
643 reply_callback(struct request *const req, u32 ttl, u32 err, struct reply *reply) {
644 switch (req->request_type) {
645 case TYPE_A:
646 if (reply)
647 req->user_callback(DNS_ERR_NONE, DNS_IPv4_A,
648 reply->data.a.addrcount, ttl,
649 reply->data.a.addresses,
650 req->user_pointer);
651 else
652 req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
653 return;
654 case TYPE_PTR:
655 if (reply) {
656 char *name = reply->data.ptr.name;
657 req->user_callback(DNS_ERR_NONE, DNS_PTR, 1, ttl,
658 &name, req->user_pointer);
659 } else {
660 req->user_callback(err, 0, 0, 0, NULL,
661 req->user_pointer);
663 return;
664 case TYPE_AAAA:
665 if (reply)
666 req->user_callback(DNS_ERR_NONE, DNS_IPv6_AAAA,
667 reply->data.aaaa.addrcount, ttl,
668 reply->data.aaaa.addresses,
669 req->user_pointer);
670 else
671 req->user_callback(err, 0, 0, 0, NULL, req->user_pointer);
673 assert(0);
676 // this processes a parsed reply packet
677 static void
678 reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply) {
679 int error;
680 static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED};
682 if (flags & 0x020f || !reply || !reply->have_answer) {
683 // there was an error
684 if (flags & 0x0200) {
685 error = DNS_ERR_TRUNCATED;
686 } else {
687 u16 error_code = (flags & 0x000f) - 1;
688 if (error_code > 4) {
689 error = DNS_ERR_UNKNOWN;
690 } else {
691 error = error_codes[error_code];
695 switch(error) {
696 case DNS_ERR_SERVERFAILED:
697 case DNS_ERR_NOTIMPL:
698 case DNS_ERR_REFUSED:
699 // we regard these errors as marking a bad nameserver
700 if (req->reissue_count < global_max_reissues) {
701 char msg[64];
702 snprintf(msg, sizeof(msg), "Bad response %d (%s)",
703 error, evdns_err_to_string(error));
704 nameserver_failed(req->ns, msg);
705 if (!request_reissue(req)) return;
707 break;
708 default:
709 // we got a good reply from the nameserver
710 nameserver_up(req->ns);
713 if (req->search_state && req->request_type != TYPE_PTR) {
714 // if we have a list of domains to search in, try the next one
715 if (!search_try_next(req)) {
716 // a new request was issued so this request is finished and
717 // the user callback will be made when that request (or a
718 // child of it) finishes.
719 request_finished(req, &req_head);
720 return;
724 // all else failed. Pass the failure up
725 reply_callback(req, 0, error, NULL);
726 request_finished(req, &req_head);
727 } else {
728 // all ok, tell the user
729 reply_callback(req, ttl, 0, reply);
730 nameserver_up(req->ns);
731 request_finished(req, &req_head);
735 static inline int
736 name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
737 int name_end = -1;
738 int j = *idx;
739 #define GET32(x) do { if (j + 4 > length) goto err; memcpy(&_t32, packet + j, 4); j += 4; x = ntohl(_t32); } while(0);
740 #define GET16(x) do { if (j + 2 > length) goto err; memcpy(&_t, packet + j, 2); j += 2; x = ntohs(_t); } while(0);
741 #define GET8(x) do { if (j >= length) goto err; x = packet[j++]; } while(0);
743 char *cp = name_out;
744 const char *const end = name_out + name_out_len;
746 // Normally, names are a series of length prefixed strings terminated
747 // with a length of 0 (the lengths are u8's < 63).
748 // However, the length can start with a pair of 1 bits and that
749 // means that the next 14 bits are a pointer within the current
750 // packet.
752 for(;;) {
753 u8 label_len;
754 if (j >= length) return -1;
755 GET8(label_len);
756 if (!label_len) break;
757 if (label_len & 0xc0) {
758 u8 ptr_low;
759 GET8(ptr_low);
760 if (name_end < 0) name_end = j;
761 j = (((int)label_len & 0x3f) << 8) + ptr_low;
762 if (j < 0 || j >= length) return -1;
763 continue;
765 if (label_len > 63) return -1;
766 if (cp != name_out) {
767 if (cp + 1 >= end) return -1;
768 *cp++ = '.';
770 if (cp + label_len >= end) return -1;
771 memcpy(cp, packet + j, label_len);
772 cp += label_len;
773 j += label_len;
775 if (cp >= end) return -1;
776 *cp = '\0';
777 if (name_end < 0)
778 *idx = j;
779 else
780 *idx = name_end;
781 return 0;
782 err:
783 return -1;
786 // parses a raw request from a nameserver.
787 static int
788 reply_parse(u8 *packet, int length) {
789 int j = 0; // index into packet
790 u16 _t; // used by the macros
791 u32 _t32; // used by the macros
792 char tmp_name[256]; // used by the macros
794 u16 trans_id, flags, questions, answers, authority, additional, datalength;
795 u32 ttl, ttl_r = 0xffffffff;
796 struct reply reply;
797 struct request *req;
798 unsigned int i;
800 GET16(trans_id);
801 GET16(flags);
802 GET16(questions);
803 GET16(answers);
804 GET16(authority);
805 GET16(additional);
806 (void) authority; /* suppress "unused variable" warnings. */
807 (void) additional; /* suppress "unused variable" warnings. */
809 req = request_find_from_trans_id(trans_id);
810 if (!req) return -1;
811 // XXXX012 should the other return points also call reply_handle? -NM
813 memset(&reply, 0, sizeof(reply));
815 if (!(flags & 0x8000)) return -1; // must be an answer
816 if (flags & 0x020f) {
817 // there was an error
818 reply_handle(req, flags, 0, NULL);
819 return -1;
821 // if (!answers) return; // must have an answer of some form
823 // This macro skips a name in the DNS reply.
824 #define SKIP_NAME \
825 do { tmp_name[0] = '\0'; \
826 if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0) \
827 goto err; \
828 } while(0);
830 reply.type = req->request_type;
832 // skip over each question in the reply
833 for (i = 0; i < questions; ++i) {
834 // the question looks like
835 // <label:name><u16:type><u16:class>
836 SKIP_NAME;
837 j += 4;
838 if (j >= length) return -1;
841 // now we have the answer section which looks like
842 // <label:name><u16:type><u16:class><u32:ttl><u16:len><data...>
844 for (i = 0; i < answers; ++i) {
845 u16 type, class;
847 // XXX I'd be more comfortable if we actually checked the name
848 // here. -NM
849 SKIP_NAME;
850 GET16(type);
851 GET16(class);
852 GET32(ttl);
853 GET16(datalength);
855 if (type == TYPE_A && class == CLASS_INET) {
856 int addrcount, addrtocopy;
857 if (req->request_type != TYPE_A) {
858 j += datalength; continue;
860 // XXXX do something sane with malformed A answers.
861 addrcount = datalength >> 2;
862 addrtocopy = MIN(MAX_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
864 ttl_r = MIN(ttl_r, ttl);
865 // we only bother with the first four addresses.
866 if (j + 4*addrtocopy > length) return -1;
867 memcpy(&reply.data.a.addresses[reply.data.a.addrcount],
868 packet + j, 4*addrtocopy);
869 j += 4*addrtocopy;
870 reply.data.a.addrcount += addrtocopy;
871 reply.have_answer = 1;
872 if (reply.data.a.addrcount == MAX_ADDRS) break;
873 } else if (type == TYPE_PTR && class == CLASS_INET) {
874 if (req->request_type != TYPE_PTR) {
875 j += datalength; continue;
877 if (name_parse(packet, length, &j, reply.data.ptr.name,
878 sizeof(reply.data.ptr.name))<0)
879 return -1;
880 reply.have_answer = 1;
881 break;
882 } else if (type == TYPE_AAAA && class == CLASS_INET) {
883 int addrcount, addrtocopy;
884 if (req->request_type != TYPE_AAAA) {
885 j += datalength; continue;
887 // XXXX do something sane with malformed AAAA answers.
888 addrcount = datalength >> 4; // each address is 16 bytes long
889 addrtocopy = MIN(MAX_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount);
890 ttl_r = MIN(ttl_r, ttl);
892 // we only bother with the first four addresses.
893 if (j + 16*addrtocopy > length) return -1;
894 memcpy(&reply.data.aaaa.addresses[reply.data.aaaa.addrcount],
895 packet + j, 16*addrtocopy);
896 reply.data.aaaa.addrcount += addrtocopy;
897 j += 16*addrtocopy;
898 reply.have_answer = 1;
899 if (reply.data.a.addrcount == MAX_ADDRS) break;
900 } else {
901 // skip over any other type of resource
902 j += datalength;
906 reply_handle(req, flags, ttl_r, &reply);
907 return 0;
908 err:
909 return -1;
912 // Parse a raw request (packet,length) sent to a nameserver port (port) from
913 // a DNS client (addr,addrlen), and if it's well-formed, call the corresponding
914 // callback.
915 static int
916 request_parse(u8 *packet, int length, struct evdns_server_port *port, struct sockaddr *addr, socklen_t addrlen)
918 int j = 0; // index into packet
919 u16 _t; // used by the macros
920 char tmp_name[256]; // used by the macros
922 int i;
923 u16 trans_id, flags, questions, answers, authority, additional;
924 struct server_request *server_req = NULL;
926 // Get the header fields
927 GET16(trans_id);
928 GET16(flags);
929 GET16(questions);
930 GET16(answers);
931 GET16(authority);
932 GET16(additional);
934 if (flags & 0x8000) return -1; // Must not be an answer.
935 if (flags & 0x7800) return -1; // only standard queries are supported
936 flags &= 0x0300; // Only TC and RD get preserved.
938 server_req = malloc(sizeof(struct server_request));
939 if (server_req == NULL) return -1;
940 memset(server_req, 0, sizeof(struct server_request));
942 server_req->trans_id = trans_id;
943 memcpy(&server_req->addr, addr, addrlen);
944 server_req->addrlen = addrlen;
946 server_req->base.flags = flags;
947 server_req->base.nquestions = 0;
948 server_req->base.questions = malloc(sizeof(struct evdns_server_question *) * questions);
949 if (server_req->base.questions == NULL)
950 goto err;
952 for (i = 0; i < questions; ++i) {
953 u16 type, class;
954 struct evdns_server_question *q;
955 int namelen;
956 if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)
957 goto err;
958 GET16(type);
959 GET16(class);
960 namelen = strlen(tmp_name);
961 q = malloc(sizeof(struct evdns_server_question) + namelen);
962 if (!q)
963 goto err;
964 q->type = type;
965 q->class = class;
966 memcpy(q->name, tmp_name, namelen+1);
967 server_req->base.questions[server_req->base.nquestions++] = q;
970 // Ignore answers, authority, and additional.
972 server_req->port = port;
973 port->refcnt++;
974 port->user_callback(&(server_req->base), port->user_data);
976 return 0;
977 err:
978 if (server_req) {
979 if (server_req->base.questions) {
980 for (i = 0; i < server_req->base.nquestions; ++i)
981 free(server_req->base.questions[i]);
982 free(server_req->base.questions);
984 CLEAR(server_req);
985 free(server_req);
987 return -1;
989 #undef SKIP_NAME
990 #undef GET32
991 #undef GET16
992 #undef GET8
995 // Try to choose a strong transaction id which isn't already in flight
996 static u16
997 transaction_id_pick(void) {
998 for (;;) {
999 const struct request *req = req_head, *started_at;
1000 #ifdef DNS_USE_CPU_CLOCK_FOR_ID
1001 struct timespec ts;
1002 u16 trans_id;
1003 #ifdef CLOCK_MONOTONIC
1004 if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
1005 #else
1006 if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
1007 #endif
1008 event_err(1, "clock_gettime");
1009 trans_id = ts.tv_nsec & 0xffff;
1010 #endif
1012 #ifdef DNS_USE_GETTIMEOFDAY_FOR_ID
1013 struct timeval tv;
1014 u16 trans_id;
1015 gettimeofday(&tv, NULL);
1016 trans_id = tv.tv_usec & 0xffff;
1017 #endif
1019 #ifdef DNS_USE_OPENSSL_FOR_ID
1020 u16 trans_id;
1021 if (RAND_pseudo_bytes((u8 *) &trans_id, 2) == -1) {
1022 /* // in the case that the RAND call fails we back
1023 // down to using gettimeofday.
1024 struct timeval tv;
1025 gettimeofday(&tv, NULL);
1026 trans_id = tv.tv_usec & 0xffff; */
1027 abort();
1029 #endif
1031 if (trans_id == 0xffff) continue;
1032 // now check to see if that id is already inflight
1033 req = started_at = req_head;
1034 if (req) {
1035 do {
1036 if (req->trans_id == trans_id) break;
1037 req = req->next;
1038 } while (req != started_at);
1040 // we didn't find it, so this is a good id
1041 if (req == started_at) return trans_id;
1045 // choose a namesever to use. This function will try to ignore
1046 // nameservers which we think are down and load balance across the rest
1047 // by updating the server_head global each time.
1048 static struct nameserver *
1049 nameserver_pick(void) {
1050 struct nameserver *started_at = server_head, *picked;
1051 if (!server_head) return NULL;
1053 // if we don't have any good nameservers then there's no
1054 // point in trying to find one.
1055 if (!global_good_nameservers) {
1056 server_head = server_head->next;
1057 return server_head;
1060 // remember that nameservers are in a circular list
1061 for (;;) {
1062 if (server_head->state) {
1063 // we think this server is currently good
1064 picked = server_head;
1065 server_head = server_head->next;
1066 return picked;
1069 server_head = server_head->next;
1070 if (server_head == started_at) {
1071 // all the nameservers seem to be down
1072 // so we just return this one and hope for the
1073 // best
1074 assert(global_good_nameservers == 0);
1075 picked = server_head;
1076 server_head = server_head->next;
1077 return picked;
1082 // this is called when a namesever socket is ready for reading
1083 static void
1084 nameserver_read(struct nameserver *ns) {
1085 u8 packet[1500];
1087 for (;;) {
1088 const int r = recv(ns->socket, packet, sizeof(packet), 0);
1089 if (r < 0) {
1090 int err = last_error(ns->socket);
1091 if (error_is_eagain(err)) return;
1092 nameserver_failed(ns, strerror(err));
1093 return;
1095 ns->timedout = 0;
1096 reply_parse(packet, r);
1100 // Read a packet from a DNS client on a server port s, parse it, and
1101 // act accordingly.
1102 static void
1103 server_port_read(struct evdns_server_port *s) {
1104 u8 packet[1500];
1105 struct sockaddr_storage addr;
1106 socklen_t addrlen;
1107 int r;
1109 for (;;) {
1110 addrlen = sizeof(struct sockaddr_storage);
1111 r = recvfrom(s->socket, packet, sizeof(packet), 0,
1112 (struct sockaddr*) &addr, &addrlen);
1113 if (r < 0) {
1114 int err = last_error(s->socket);
1115 if (error_is_eagain(err)) return;
1116 log(EVDNS_LOG_WARN, "Error %s (%d) while reading request.",
1117 strerror(err), err);
1118 return;
1120 request_parse(packet, r, s, (struct sockaddr*) &addr, addrlen);
1124 // Try to write all pending replies on a given DNS server port.
1125 static void
1126 server_port_flush(struct evdns_server_port *port)
1128 while (port->pending_replies) {
1129 struct server_request *req = port->pending_replies;
1130 int r = sendto(port->socket, req->response, req->response_len, 0,
1131 (struct sockaddr*) &req->addr, req->addrlen);
1132 if (r < 0) {
1133 int err = last_error(port->socket);
1134 if (error_is_eagain(err))
1135 return;
1136 log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", strerror(err), err);
1138 if (server_request_free(req)) {
1139 // we released the last reference to req->port.
1140 return;
1144 // We have no more pending requests; stop listening for 'writeable' events.
1145 (void) event_del(&port->event);
1146 CLEAR(&port->event);
1147 event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
1148 server_port_ready_callback, port);
1149 if (event_add(&port->event, NULL) < 0) {
1150 log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server.");
1151 // ???? Do more?
1155 // set if we are waiting for the ability to write to this server.
1156 // if waiting is true then we ask libevent for EV_WRITE events, otherwise
1157 // we stop these events.
1158 static void
1159 nameserver_write_waiting(struct nameserver *ns, char waiting) {
1160 if (ns->write_waiting == waiting) return;
1162 ns->write_waiting = waiting;
1163 (void) event_del(&ns->event);
1164 CLEAR(&ns->event);
1165 event_set(&ns->event, ns->socket, EV_READ | (waiting ? EV_WRITE : 0) | EV_PERSIST,
1166 nameserver_ready_callback, ns);
1167 if (event_add(&ns->event, NULL) < 0) {
1168 log(EVDNS_LOG_WARN, "Error from libevent when adding event for %s",
1169 debug_ntoa(ns->address));
1170 // ???? Do more?
1174 // a callback function. Called by libevent when the kernel says that
1175 // a nameserver socket is ready for writing or reading
1176 static void
1177 nameserver_ready_callback(int fd, short events, void *arg) {
1178 struct nameserver *ns = (struct nameserver *) arg;
1179 (void)fd;
1181 if (events & EV_WRITE) {
1182 ns->choked = 0;
1183 if (!evdns_transmit()) {
1184 nameserver_write_waiting(ns, 0);
1187 if (events & EV_READ) {
1188 nameserver_read(ns);
1192 // a callback function. Called by libevent when the kernel says that
1193 // a server socket is ready for writing or reading.
1194 static void
1195 server_port_ready_callback(int fd, short events, void *arg) {
1196 struct evdns_server_port *port = (struct evdns_server_port *) arg;
1197 (void) fd;
1199 if (events & EV_WRITE) {
1200 port->choked = 0;
1201 server_port_flush(port);
1203 if (events & EV_READ) {
1204 server_port_read(port);
1208 /* This is an inefficient representation; only use it via the dnslabel_table_*
1209 * functions, so that is can be safely replaced with something smarter later. */
1210 #define MAX_LABELS 128
1211 // Structures used to implement name compression
1212 struct dnslabel_entry { char *v; int pos; };
1213 struct dnslabel_table {
1214 int n_labels; // number of current entries
1215 // map from name to position in message
1216 struct dnslabel_entry labels[MAX_LABELS];
1219 // Initialize dnslabel_table.
1220 static void
1221 dnslabel_table_init(struct dnslabel_table *table)
1223 table->n_labels = 0;
1226 // Free all storage held by table, but not the table itself.
1227 static void
1228 dnslabel_clear(struct dnslabel_table *table)
1230 int i;
1231 for (i = 0; i < table->n_labels; ++i)
1232 free(table->labels[i].v);
1233 table->n_labels = 0;
1236 // return the position of the label in the current message, or -1 if the label
1237 // hasn't been used yet.
1238 static int
1239 dnslabel_table_get_pos(const struct dnslabel_table *table, const char *label)
1241 int i;
1242 for (i = 0; i < table->n_labels; ++i) {
1243 if (!strcmp(label, table->labels[i].v))
1244 return table->labels[i].pos;
1246 return -1;
1249 // remember that we've used the label at position pos
1250 static int
1251 dnslabel_table_add(struct dnslabel_table *table, const char *label, int pos)
1253 char *v;
1254 int p;
1255 if (table->n_labels == MAX_LABELS)
1256 return (-1);
1257 v = strdup(label);
1258 if (v == NULL)
1259 return (-1);
1260 p = table->n_labels++;
1261 table->labels[p].v = v;
1262 table->labels[p].pos = pos;
1264 return (0);
1267 // Converts a string to a length-prefixed set of DNS labels, starting
1268 // at buf[j]. name and buf must not overlap. name_len should be the length
1269 // of name. table is optional, and is used for compression.
1271 // Input: abc.def
1272 // Output: <3>abc<3>def<0>
1274 // Returns the first index after the encoded name, or negative on error.
1275 // -1 label was > 63 bytes
1276 // -2 name too long to fit in buffer.
1278 static off_t
1279 dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j,
1280 const char *name, const int name_len,
1281 struct dnslabel_table *table) {
1282 const char *end = name + name_len;
1283 int ref = 0;
1284 u16 _t;
1286 #define APPEND16(x) do { \
1287 if (j + 2 > (off_t)buf_len) \
1288 goto overflow; \
1289 _t = htons(x); \
1290 memcpy(buf + j, &_t, 2); \
1291 j += 2; \
1292 } while (0)
1293 #define APPEND32(x) do { \
1294 if (j + 4 > (off_t)buf_len) \
1295 goto overflow; \
1296 _t32 = htonl(x); \
1297 memcpy(buf + j, &_t32, 4); \
1298 j += 4; \
1299 } while (0)
1301 if (name_len > 255) return -2;
1303 for (;;) {
1304 const char *const start = name;
1305 if (table && (ref = dnslabel_table_get_pos(table, name)) >= 0) {
1306 APPEND16(ref | 0xc000);
1307 return j;
1309 name = strchr(name, '.');
1310 if (!name) {
1311 const unsigned int label_len = end - start;
1312 if (label_len > 63) return -1;
1313 if ((size_t)(j+label_len+1) > buf_len) return -2;
1314 if (table) dnslabel_table_add(table, start, j);
1315 buf[j++] = label_len;
1317 memcpy(buf + j, start, end - start);
1318 j += end - start;
1319 break;
1320 } else {
1321 // append length of the label.
1322 const unsigned int label_len = name - start;
1323 if (label_len > 63) return -1;
1324 if ((size_t)(j+label_len+1) > buf_len) return -2;
1325 if (table) dnslabel_table_add(table, start, j);
1326 buf[j++] = label_len;
1328 memcpy(buf + j, start, name - start);
1329 j += name - start;
1330 // hop over the '.'
1331 name++;
1335 // the labels must be terminated by a 0.
1336 // It's possible that the name ended in a .
1337 // in which case the zero is already there
1338 if (!j || buf[j-1]) buf[j++] = 0;
1339 return j;
1340 overflow:
1341 return (-2);
1344 // Finds the length of a dns request for a DNS name of the given
1345 // length. The actual request may be smaller than the value returned
1346 // here
1347 static int
1348 evdns_request_len(const int name_len) {
1349 return 96 + // length of the DNS standard header
1350 name_len + 2 +
1351 4; // space for the resource type
1354 // build a dns request packet into buf. buf should be at least as long
1355 // as evdns_request_len told you it should be.
1357 // Returns the amount of space used. Negative on error.
1358 static int
1359 evdns_request_data_build(const char *const name, const int name_len,
1360 const u16 trans_id, const u16 type, const u16 class,
1361 u8 *const buf, size_t buf_len) {
1362 off_t j = 0; // current offset into buf
1363 u16 _t; // used by the macros
1365 APPEND16(trans_id);
1366 APPEND16(0x0100); // standard query, recusion needed
1367 APPEND16(1); // one question
1368 APPEND16(0); // no answers
1369 APPEND16(0); // no authority
1370 APPEND16(0); // no additional
1372 j = dnsname_to_labels(buf, buf_len, j, name, name_len, NULL);
1373 if (j < 0) {
1374 return (int)j;
1377 APPEND16(type);
1378 APPEND16(class);
1380 return (int)j;
1381 overflow:
1382 return (-1);
1385 // exported function
1386 struct evdns_server_port *
1387 evdns_add_server_port(int socket, int is_tcp, evdns_request_callback_fn_type cb, void *user_data)
1389 struct evdns_server_port *port;
1390 if (!(port = malloc(sizeof(struct evdns_server_port))))
1391 return NULL;
1392 memset(port, 0, sizeof(struct evdns_server_port));
1394 assert(!is_tcp); // TCP sockets not yet implemented
1395 port->socket = socket;
1396 port->refcnt = 1;
1397 port->choked = 0;
1398 port->closing = 0;
1399 port->user_callback = cb;
1400 port->user_data = user_data;
1401 port->pending_replies = NULL;
1403 event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
1404 server_port_ready_callback, port);
1405 event_add(&port->event, NULL); // check return.
1406 return port;
1409 // exported function
1410 void
1411 evdns_close_server_port(struct evdns_server_port *port)
1413 if (--port->refcnt == 0)
1414 server_port_free(port);
1415 port->closing = 1;
1418 // exported function
1420 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)
1422 struct server_request *req = TO_SERVER_REQUEST(_req);
1423 struct server_reply_item **itemp, *item;
1424 int *countp;
1426 if (req->response) /* have we already answered? */
1427 return (-1);
1429 switch (section) {
1430 case EVDNS_ANSWER_SECTION:
1431 itemp = &req->answer;
1432 countp = &req->n_answer;
1433 break;
1434 case EVDNS_AUTHORITY_SECTION:
1435 itemp = &req->authority;
1436 countp = &req->n_authority;
1437 break;
1438 case EVDNS_ADDITIONAL_SECTION:
1439 itemp = &req->additional;
1440 countp = &req->n_additional;
1441 break;
1442 default:
1443 return (-1);
1445 while (*itemp) {
1446 itemp = &((*itemp)->next);
1448 item = malloc(sizeof(struct server_reply_item));
1449 if (!item)
1450 return -1;
1451 CLEAR(item);
1452 item->next = NULL;
1453 if (!(item->name = strdup(name))) {
1454 CLEAR(item);
1455 free(item);
1456 return -1;
1458 item->type = type;
1459 item->class = class;
1460 item->ttl = ttl;
1461 item->is_name = is_name != 0;
1462 item->datalen = 0;
1463 item->data = NULL;
1464 if (data) {
1465 if (item->is_name) {
1466 if (!(item->data = strdup(data))) {
1467 free(item->name);
1468 CLEAR(item);
1469 free(item);
1470 return -1;
1472 item->datalen = -1;
1473 } else {
1474 if (!(item->data = malloc(datalen))) {
1475 free(item->name);
1476 CLEAR(item);
1477 free(item);
1478 return -1;
1480 item->datalen = datalen;
1481 memcpy(item->data, data, datalen);
1485 *itemp = item;
1486 ++(*countp);
1487 return 0;
1490 // exported function
1492 evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
1494 return evdns_server_request_add_reply(
1495 req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
1496 ttl, n*4, 0, addrs);
1499 // exported function
1501 evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl)
1503 return evdns_server_request_add_reply(
1504 req, EVDNS_ANSWER_SECTION, name, TYPE_AAAA, CLASS_INET,
1505 ttl, n*16, 0, addrs);
1508 // exported function
1510 evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl)
1512 u32 a;
1513 char buf[32];
1514 assert(in || inaddr_name);
1515 assert(!(in && inaddr_name));
1516 if (in) {
1517 a = ntohl(in->s_addr);
1518 sprintf(buf, "%d.%d.%d.%d.in-addr.arpa",
1519 (int)(u8)((a )&0xff),
1520 (int)(u8)((a>>8 )&0xff),
1521 (int)(u8)((a>>16)&0xff),
1522 (int)(u8)((a>>24)&0xff));
1523 inaddr_name = buf;
1525 return evdns_server_request_add_reply(
1526 req, EVDNS_ANSWER_SECTION, inaddr_name, TYPE_PTR, CLASS_INET,
1527 ttl, -1, 1, hostname);
1530 // exported function
1532 evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl)
1534 return evdns_server_request_add_reply(
1535 req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
1536 ttl, -1, 1, cname);
1540 static int
1541 evdns_server_request_format_response(struct server_request *req, int err)
1543 unsigned char buf[1500];
1544 size_t buf_len = sizeof(buf);
1545 off_t j = 0, r;
1546 u16 _t;
1547 u32 _t32;
1548 int i;
1549 u16 flags;
1550 struct dnslabel_table table;
1552 if (err < 0 || err > 15) return -1;
1554 /* Set response bit and error code; copy OPCODE and RD fields from
1555 * question; copy RA and AA if set by caller. */
1556 flags = req->base.flags;
1557 flags |= (0x8000 | err);
1559 dnslabel_table_init(&table);
1560 APPEND16(req->trans_id);
1561 APPEND16(flags);
1562 APPEND16(req->base.nquestions);
1563 APPEND16(req->n_answer);
1564 APPEND16(req->n_authority);
1565 APPEND16(req->n_additional);
1567 /* Add questions. */
1568 for (i=0; i < req->base.nquestions; ++i) {
1569 const char *s = req->base.questions[i]->name;
1570 j = dnsname_to_labels(buf, buf_len, j, s, strlen(s), &table);
1571 if (j < 0) {
1572 dnslabel_clear(&table);
1573 return (int) j;
1575 APPEND16(req->base.questions[i]->type);
1576 APPEND16(req->base.questions[i]->class);
1579 /* Add answer, authority, and additional sections. */
1580 for (i=0; i<3; ++i) {
1581 struct server_reply_item *item;
1582 if (i==0)
1583 item = req->answer;
1584 else if (i==1)
1585 item = req->authority;
1586 else
1587 item = req->additional;
1588 while (item) {
1589 r = dnsname_to_labels(buf, buf_len, j, item->name, strlen(item->name), &table);
1590 if (r < 0)
1591 goto overflow;
1592 j = r;
1594 APPEND16(item->type);
1595 APPEND16(item->class);
1596 APPEND32(item->ttl);
1597 if (item->is_name) {
1598 off_t len_idx = j, name_start;
1599 j += 2;
1600 name_start = j;
1601 r = dnsname_to_labels(buf, buf_len, j, item->data, strlen(item->data), &table);
1602 if (r < 0)
1603 goto overflow;
1604 j = r;
1605 _t = htons( (j-name_start) );
1606 memcpy(buf+len_idx, &_t, 2);
1607 } else {
1608 APPEND16(item->datalen);
1609 if (j+item->datalen > (off_t)buf_len)
1610 goto overflow;
1611 memcpy(buf+j, item->data, item->datalen);
1612 j += item->datalen;
1614 item = item->next;
1618 if (j > 512) {
1619 overflow:
1620 j = 512;
1621 buf[3] |= 0x02; /* set the truncated bit. */
1624 req->response_len = j;
1626 if (!(req->response = malloc(req->response_len))) {
1627 server_request_free_answers(req);
1628 dnslabel_clear(&table);
1629 return (-1);
1631 memcpy(req->response, buf, req->response_len);
1632 server_request_free_answers(req);
1633 dnslabel_clear(&table);
1634 return (0);
1637 // exported function
1639 evdns_server_request_respond(struct evdns_server_request *_req, int err)
1641 struct server_request *req = TO_SERVER_REQUEST(_req);
1642 struct evdns_server_port *port = req->port;
1643 int r;
1644 if (!req->response) {
1645 if ((r = evdns_server_request_format_response(req, err))<0)
1646 return r;
1649 r = sendto(port->socket, req->response, req->response_len, 0,
1650 (struct sockaddr*) &req->addr, req->addrlen);
1651 if (r<0) {
1652 int err = last_error(port->socket);
1653 if (! error_is_eagain(err))
1654 return -1;
1656 if (port->pending_replies) {
1657 req->prev_pending = port->pending_replies->prev_pending;
1658 req->next_pending = port->pending_replies;
1659 req->prev_pending->next_pending =
1660 req->next_pending->prev_pending = req;
1661 } else {
1662 req->prev_pending = req->next_pending = req;
1663 port->pending_replies = req;
1664 port->choked = 1;
1666 (void) event_del(&port->event);
1667 CLEAR(&port->event);
1668 event_set(&port->event, port->socket, (port->closing?0:EV_READ) | EV_WRITE | EV_PERSIST, server_port_ready_callback, port);
1670 if (event_add(&port->event, NULL) < 0) {
1671 log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server");
1676 return 1;
1678 if (server_request_free(req))
1679 return 0;
1681 if (req->port->pending_replies)
1682 server_port_flush(port);
1684 return 0;
1687 // Free all storage held by RRs in req.
1688 static void
1689 server_request_free_answers(struct server_request *req)
1691 struct server_reply_item *victim, *next, **list;
1692 int i;
1693 for (i = 0; i < 3; ++i) {
1694 if (i==0)
1695 list = &req->answer;
1696 else if (i==1)
1697 list = &req->authority;
1698 else
1699 list = &req->additional;
1701 victim = *list;
1702 while (victim) {
1703 next = victim->next;
1704 free(victim->name);
1705 if (victim->data)
1706 free(victim->data);
1707 /* XXXX free(victim?) -NM */
1708 victim = next;
1710 *list = NULL;
1714 // Free all storage held by req, and remove links to it.
1715 // return true iff we just wound up freeing the server_port.
1716 static int
1717 server_request_free(struct server_request *req)
1719 int i, rc=1;
1720 if (req->base.questions) {
1721 for (i = 0; i < req->base.nquestions; ++i)
1722 free(req->base.questions[i]);
1725 if (req->port) {
1726 if (req->port->pending_replies == req) {
1727 if (req->next_pending)
1728 req->port->pending_replies = req->next_pending;
1729 else
1730 req->port->pending_replies = NULL;
1732 rc = --req->port->refcnt;
1735 if (req->response) {
1736 free(req->response);
1739 server_request_free_answers(req);
1741 if (req->next_pending && req->next_pending != req) {
1742 req->next_pending->prev_pending = req->prev_pending;
1743 req->prev_pending->next_pending = req->next_pending;
1746 if (rc == 0) {
1747 server_port_free(req->port);
1748 CLEAR(req);
1749 free(req);
1750 return (1);
1752 CLEAR(req);
1753 free(req);
1754 return (0);
1757 // Free all storage held by an evdns_server_port. Only called when
1758 static void
1759 server_port_free(struct evdns_server_port *port)
1761 assert(port);
1762 assert(!port->refcnt);
1763 assert(!port->pending_replies);
1764 if (port->socket > 0) {
1765 CLOSE_SOCKET(port->socket);
1766 port->socket = -1;
1768 (void) event_del(&port->event);
1769 CLEAR(&port->event);
1770 // XXXX actually free the port? -NM
1773 // exported function
1775 evdns_server_request_drop(struct evdns_server_request *_req)
1777 struct server_request *req = TO_SERVER_REQUEST(_req);
1778 server_request_free(req);
1779 return 0;
1782 #undef APPEND16
1783 #undef APPEND32
1785 // this is a libevent callback function which is called when a request
1786 // has timed out.
1787 static void
1788 evdns_request_timeout_callback(int fd, short events, void *arg) {
1789 struct request *const req = (struct request *) arg;
1790 (void) fd;
1791 (void) events;
1793 log(EVDNS_LOG_DEBUG, "Request %lx timed out", (unsigned long) arg);
1795 req->ns->timedout++;
1796 if (req->ns->timedout > global_max_nameserver_timeout) {
1797 req->ns->timedout = 0;
1798 nameserver_failed(req->ns, "request timed out.");
1801 (void) evtimer_del(&req->timeout_event);
1802 CLEAR(&req->timeout_event);
1803 if (req->tx_count >= global_max_retransmits) {
1804 // this request has failed
1805 reply_callback(req, 0, DNS_ERR_TIMEOUT, NULL);
1806 request_finished(req, &req_head);
1807 } else {
1808 // retransmit it
1809 evdns_request_transmit(req);
1813 // try to send a request to a given server.
1815 // return:
1816 // 0 ok
1817 // 1 temporary failure
1818 // 2 other failure
1819 static int
1820 evdns_request_transmit_to(struct request *req, struct nameserver *server) {
1821 const int r = send(server->socket, req->request, req->request_len, 0);
1822 if (r < 0) {
1823 int err = last_error(server->socket);
1824 if (error_is_eagain(err)) return 1;
1825 nameserver_failed(req->ns, strerror(err));
1826 return 2;
1827 } else if (r != (int)req->request_len) {
1828 return 1; // short write
1829 } else {
1830 return 0;
1834 // try to send a request, updating the fields of the request
1835 // as needed
1837 // return:
1838 // 0 ok
1839 // 1 failed
1840 static int
1841 evdns_request_transmit(struct request *req) {
1842 int retcode = 0, r;
1844 // if we fail to send this packet then this flag marks it
1845 // for evdns_transmit
1846 req->transmit_me = 1;
1847 if (req->trans_id == 0xffff) abort();
1849 if (req->ns->choked) {
1850 // don't bother trying to write to a socket
1851 // which we have had EAGAIN from
1852 return 1;
1855 r = evdns_request_transmit_to(req, req->ns);
1856 switch (r) {
1857 case 1:
1858 // temp failure
1859 req->ns->choked = 1;
1860 nameserver_write_waiting(req->ns, 1);
1861 return 1;
1862 case 2:
1863 // failed in some other way
1864 retcode = 1;
1865 // fall through
1866 default:
1867 // all ok
1868 log(EVDNS_LOG_DEBUG,
1869 "Setting timeout for request %lx", (unsigned long) req);
1870 evtimer_set(&req->timeout_event, evdns_request_timeout_callback, req);
1871 if (evtimer_add(&req->timeout_event, &global_timeout) < 0) {
1872 log(EVDNS_LOG_WARN,
1873 "Error from libevent when adding timer for request %lx",
1874 (unsigned long) req);
1875 // ???? Do more?
1877 req->tx_count++;
1878 req->transmit_me = 0;
1879 return retcode;
1883 static void
1884 nameserver_probe_callback(int result, char type, int count, int ttl, void *addresses, void *arg) {
1885 struct nameserver *const ns = (struct nameserver *) arg;
1886 (void) type;
1887 (void) count;
1888 (void) ttl;
1889 (void) addresses;
1891 if (result == DNS_ERR_NONE || result == DNS_ERR_NOTEXIST) {
1892 // this is a good reply
1893 nameserver_up(ns);
1894 } else nameserver_probe_failed(ns);
1897 static void
1898 nameserver_send_probe(struct nameserver *const ns) {
1899 struct request *req;
1900 // here we need to send a probe to a given nameserver
1901 // in the hope that it is up now.
1903 log(EVDNS_LOG_DEBUG, "Sending probe to %s", debug_ntoa(ns->address));
1905 req = request_new(TYPE_A, "www.google.com", DNS_QUERY_NO_SEARCH, nameserver_probe_callback, ns);
1906 if (!req) return;
1907 // we force this into the inflight queue no matter what
1908 request_trans_id_set(req, transaction_id_pick());
1909 req->ns = ns;
1910 request_submit(req);
1913 // returns:
1914 // 0 didn't try to transmit anything
1915 // 1 tried to transmit something
1916 static int
1917 evdns_transmit(void) {
1918 char did_try_to_transmit = 0;
1920 if (req_head) {
1921 struct request *const started_at = req_head, *req = req_head;
1922 // first transmit all the requests which are currently waiting
1923 do {
1924 if (req->transmit_me) {
1925 did_try_to_transmit = 1;
1926 evdns_request_transmit(req);
1929 req = req->next;
1930 } while (req != started_at);
1933 return did_try_to_transmit;
1936 // exported function
1938 evdns_count_nameservers(void)
1940 const struct nameserver *server = server_head;
1941 int n = 0;
1942 if (!server)
1943 return 0;
1944 do {
1945 ++n;
1946 server = server->next;
1947 } while (server != server_head);
1948 return n;
1951 // exported function
1953 evdns_clear_nameservers_and_suspend(void)
1955 struct nameserver *server = server_head, *started_at = server_head;
1956 struct request *req = req_head, *req_started_at = req_head;
1958 if (!server)
1959 return 0;
1960 while (1) {
1961 struct nameserver *next = server->next;
1962 (void) event_del(&server->event);
1963 CLEAR(&server->event);
1964 (void) evtimer_del(&server->timeout_event);
1965 CLEAR(&server->timeout_event);
1966 if (server->socket >= 0)
1967 CLOSE_SOCKET(server->socket);
1968 CLEAR(server);
1969 free(server);
1970 if (next == started_at)
1971 break;
1972 server = next;
1974 server_head = NULL;
1975 global_good_nameservers = 0;
1977 while (req) {
1978 struct request *next = req->next;
1979 req->tx_count = req->reissue_count = 0;
1980 req->ns = NULL;
1981 // ???? What to do about searches?
1982 (void) evtimer_del(&req->timeout_event);
1983 CLEAR(&req->timeout_event);
1984 req->trans_id = 0;
1985 req->transmit_me = 0;
1987 global_requests_waiting++;
1988 evdns_request_insert(req, &req_waiting_head);
1989 /* We want to insert these suspended elements at the front of
1990 * the waiting queue, since they were pending before any of
1991 * the waiting entries were added. This is a circular list,
1992 * so we can just shift the start back by one.*/
1993 req_waiting_head = req_waiting_head->prev;
1995 if (next == req_started_at)
1996 break;
1997 req = next;
1999 req_head = NULL;
2000 global_requests_inflight = 0;
2002 return 0;
2006 // exported function
2008 evdns_resume(void)
2010 evdns_requests_pump_waiting_queue();
2011 return 0;
2014 // exported function
2016 evdns_nameserver_add(unsigned long int address) {
2017 // first check to see if we already have this nameserver
2019 const struct nameserver *server = server_head, *const started_at = server_head;
2020 struct nameserver *ns;
2021 struct sockaddr_in sin;
2022 int err = 0;
2023 if (server) {
2024 do {
2025 if (server->address == address) return 3;
2026 server = server->next;
2027 } while (server != started_at);
2030 ns = (struct nameserver *) malloc(sizeof(struct nameserver));
2031 if (!ns) return -1;
2033 memset(ns, 0, sizeof(struct nameserver));
2035 ns->socket = socket(PF_INET, SOCK_DGRAM, 0);
2036 if (ns->socket < 0) { err = 1; goto out1; }
2037 #ifdef WIN32
2039 u_long nonblocking = 1;
2040 ioctlsocket(ns->socket, FIONBIO, &nonblocking);
2042 #else
2043 fcntl(ns->socket, F_SETFL, O_NONBLOCK);
2044 #endif
2045 sin.sin_addr.s_addr = address;
2046 sin.sin_port = htons(53);
2047 sin.sin_family = AF_INET;
2048 if (connect(ns->socket, (struct sockaddr *) &sin, sizeof(sin)) != 0) {
2049 err = 2;
2050 goto out2;
2053 ns->address = address;
2054 ns->state = 1;
2055 event_set(&ns->event, ns->socket, EV_READ | EV_PERSIST, nameserver_ready_callback, ns);
2056 if (event_add(&ns->event, NULL) < 0) {
2057 err = 2;
2058 goto out2;
2061 log(EVDNS_LOG_DEBUG, "Added nameserver %s", debug_ntoa(address));
2063 // insert this nameserver into the list of them
2064 if (!server_head) {
2065 ns->next = ns->prev = ns;
2066 server_head = ns;
2067 } else {
2068 ns->next = server_head->next;
2069 ns->prev = server_head;
2070 server_head->next = ns;
2071 if (server_head->prev == server_head) {
2072 server_head->prev = ns;
2076 global_good_nameservers++;
2078 return 0;
2080 out2:
2081 CLOSE_SOCKET(ns->socket);
2082 out1:
2083 CLEAR(ns);
2084 free(ns);
2085 log(EVDNS_LOG_WARN, "Unable to add nameserver %s: error %d", debug_ntoa(address), err);
2086 return err;
2089 // exported function
2091 evdns_nameserver_ip_add(const char *ip_as_string) {
2092 struct in_addr ina;
2093 if (!inet_aton(ip_as_string, &ina))
2094 return 4;
2095 return evdns_nameserver_add(ina.s_addr);
2098 // insert into the tail of the queue
2099 static void
2100 evdns_request_insert(struct request *req, struct request **head) {
2101 if (!*head) {
2102 *head = req;
2103 req->next = req->prev = req;
2104 return;
2107 req->prev = (*head)->prev;
2108 req->prev->next = req;
2109 req->next = *head;
2110 (*head)->prev = req;
2113 static int
2114 string_num_dots(const char *s) {
2115 int count = 0;
2116 while ((s = strchr(s, '.'))) {
2117 s++;
2118 count++;
2120 return count;
2123 static struct request *
2124 request_new(int type, const char *name, int flags,
2125 evdns_callback_type callback, void *user_ptr) {
2126 const char issuing_now =
2127 (global_requests_inflight < global_max_requests_inflight) ? 1 : 0;
2129 const int name_len = strlen(name);
2130 const int request_max_len = evdns_request_len(name_len);
2131 const u16 trans_id = issuing_now ? transaction_id_pick() : 0xffff;
2132 // the request data is alloced in a single block with the header
2133 struct request *const req =
2134 (struct request *) malloc(sizeof(struct request) + request_max_len);
2135 int rlen;
2136 (void) flags;
2138 if (!req) return NULL;
2139 memset(req, 0, sizeof(struct request));
2141 // request data lives just after the header
2142 req->request = ((u8 *) req) + sizeof(struct request);
2143 // denotes that the request data shouldn't be free()ed
2144 req->request_appended = 1;
2145 rlen = evdns_request_data_build(name, name_len, trans_id,
2146 type, CLASS_INET, req->request, request_max_len);
2147 if (rlen < 0)
2148 goto err1;
2149 req->request_len = rlen;
2150 req->trans_id = trans_id;
2151 req->tx_count = 0;
2152 req->request_type = type;
2153 req->user_pointer = user_ptr;
2154 req->user_callback = callback;
2155 req->ns = issuing_now ? nameserver_pick() : NULL;
2156 req->next = req->prev = NULL;
2158 return req;
2159 err1:
2160 CLEAR(req);
2161 free(req);
2162 return NULL;
2165 static void
2166 request_submit(struct request *const req) {
2167 if (req->ns) {
2168 // if it has a nameserver assigned then this is going
2169 // straight into the inflight queue
2170 evdns_request_insert(req, &req_head);
2171 global_requests_inflight++;
2172 evdns_request_transmit(req);
2173 } else {
2174 evdns_request_insert(req, &req_waiting_head);
2175 global_requests_waiting++;
2179 // exported function
2180 int evdns_resolve_ipv4(const char *name, int flags,
2181 evdns_callback_type callback, void *ptr) {
2182 log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
2183 if (flags & DNS_QUERY_NO_SEARCH) {
2184 struct request *const req =
2185 request_new(TYPE_A, name, flags, callback, ptr);
2186 if (req == NULL)
2187 return (1);
2188 request_submit(req);
2189 return (0);
2190 } else {
2191 return (search_request_new(TYPE_A, name, flags, callback, ptr));
2195 // exported function
2196 int evdns_resolve_ipv6(const char *name, int flags,
2197 evdns_callback_type callback, void *ptr) {
2198 log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
2199 if (flags & DNS_QUERY_NO_SEARCH) {
2200 struct request *const req =
2201 request_new(TYPE_AAAA, name, flags, callback, ptr);
2202 if (req == NULL)
2203 return (1);
2204 request_submit(req);
2205 return (0);
2206 } else {
2207 return (search_request_new(TYPE_AAAA, name, flags, callback, ptr));
2211 int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
2212 char buf[32];
2213 struct request *req;
2214 u32 a;
2215 assert(in);
2216 a = ntohl(in->s_addr);
2217 sprintf(buf, "%d.%d.%d.%d.in-addr.arpa",
2218 (int)(u8)((a )&0xff),
2219 (int)(u8)((a>>8 )&0xff),
2220 (int)(u8)((a>>16)&0xff),
2221 (int)(u8)((a>>24)&0xff));
2222 log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
2223 req = request_new(TYPE_PTR, buf, flags, callback, ptr);
2224 if (!req) return 1;
2225 request_submit(req);
2226 return 0;
2229 int evdns_resolve_reverse_ipv6(struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
2230 char buf[64];
2231 char *cp;
2232 struct request *req;
2233 int i;
2234 assert(in);
2235 cp = buf;
2236 for (i=0; i < 16; ++i) {
2237 u8 byte = in->s6_addr[i];
2238 *cp++ = "0123456789abcdef"[byte >> 4];
2239 *cp++ = '.';
2240 *cp++ = "0123456789abcdef"[byte & 0x0f];
2241 *cp++ = '.';
2243 assert(cp + strlen(".ip6.arpa") < buf+sizeof(buf));
2244 strcpy(cp, ".ip6.arpa");
2245 log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
2246 req = request_new(TYPE_PTR, buf, flags, callback, ptr);
2247 if (!req) return 1;
2248 request_submit(req);
2249 return 0;
2253 /////////////////////////////////////////////////////////////////////
2254 // Search support
2256 // the libc resolver has support for searching a number of domains
2257 // to find a name. If nothing else then it takes the single domain
2258 // from the gethostname() call.
2260 // It can also be configured via the domain and search options in a
2261 // resolv.conf.
2263 // The ndots option controls how many dots it takes for the resolver
2264 // to decide that a name is non-local and so try a raw lookup first.
2266 struct search_domain {
2267 int len;
2268 struct search_domain *next;
2269 // the text string is appended to this structure
2272 struct search_state {
2273 int refcount;
2274 int ndots;
2275 int num_domains;
2276 struct search_domain *head;
2279 static struct search_state *global_search_state = NULL;
2281 static void
2282 search_state_decref(struct search_state *const state) {
2283 if (!state) return;
2284 state->refcount--;
2285 if (!state->refcount) {
2286 struct search_domain *next, *dom;
2287 for (dom = state->head; dom; dom = next) {
2288 next = dom->next;
2289 CLEAR(dom);
2290 free(dom);
2292 CLEAR(state);
2293 free(state);
2297 static struct search_state *
2298 search_state_new(void) {
2299 struct search_state *state = (struct search_state *) malloc(sizeof(struct search_state));
2300 if (!state) return NULL;
2301 memset(state, 0, sizeof(struct search_state));
2302 state->refcount = 1;
2303 state->ndots = 1;
2305 return state;
2308 static void
2309 search_postfix_clear(void) {
2310 search_state_decref(global_search_state);
2312 global_search_state = search_state_new();
2315 // exported function
2316 void
2317 evdns_search_clear(void) {
2318 search_postfix_clear();
2321 static void
2322 search_postfix_add(const char *domain) {
2323 int domain_len;
2324 struct search_domain *sdomain;
2325 while (domain[0] == '.') domain++;
2326 domain_len = strlen(domain);
2328 if (!global_search_state) global_search_state = search_state_new();
2329 if (!global_search_state) return;
2330 global_search_state->num_domains++;
2332 sdomain = (struct search_domain *) malloc(sizeof(struct search_domain) + domain_len);
2333 if (!sdomain) return;
2334 memcpy( ((u8 *) sdomain) + sizeof(struct search_domain), domain, domain_len);
2335 sdomain->next = global_search_state->head;
2336 sdomain->len = domain_len;
2338 global_search_state->head = sdomain;
2341 // reverse the order of members in the postfix list. This is needed because,
2342 // when parsing resolv.conf we push elements in the wrong order
2343 static void
2344 search_reverse(void) {
2345 struct search_domain *cur, *prev = NULL, *next;
2346 cur = global_search_state->head;
2347 while (cur) {
2348 next = cur->next;
2349 cur->next = prev;
2350 prev = cur;
2351 cur = next;
2354 global_search_state->head = prev;
2357 // exported function
2358 void
2359 evdns_search_add(const char *domain) {
2360 search_postfix_add(domain);
2363 // exported function
2364 void
2365 evdns_search_ndots_set(const int ndots) {
2366 if (!global_search_state) global_search_state = search_state_new();
2367 if (!global_search_state) return;
2368 global_search_state->ndots = ndots;
2371 static void
2372 search_set_from_hostname(void) {
2373 char hostname[HOST_NAME_MAX + 1], *domainname;
2375 search_postfix_clear();
2376 if (gethostname(hostname, sizeof(hostname))) return;
2377 domainname = strchr(hostname, '.');
2378 if (!domainname) return;
2379 search_postfix_add(domainname);
2382 // warning: returns malloced string
2383 static char *
2384 search_make_new(const struct search_state *const state, int n, const char *const base_name) {
2385 const int base_len = strlen(base_name);
2386 const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
2387 struct search_domain *dom;
2389 for (dom = state->head; dom; dom = dom->next) {
2390 if (!n--) {
2391 // this is the postfix we want
2392 // the actual postfix string is kept at the end of the structure
2393 const u8 *const postfix = ((u8 *) dom) + sizeof(struct search_domain);
2394 const int postfix_len = dom->len;
2395 char *const newname = (char *) malloc(base_len + need_to_append_dot + postfix_len + 1);
2396 if (!newname) return NULL;
2397 memcpy(newname, base_name, base_len);
2398 if (need_to_append_dot) newname[base_len] = '.';
2399 memcpy(newname + base_len + need_to_append_dot, postfix, postfix_len);
2400 newname[base_len + need_to_append_dot + postfix_len] = 0;
2401 return newname;
2405 // we ran off the end of the list and still didn't find the requested string
2406 abort();
2407 return NULL; /* unreachable; stops warnings in some compilers. */
2410 static int
2411 search_request_new(int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg) {
2412 assert(type == TYPE_A);
2413 if ( ((flags & DNS_QUERY_NO_SEARCH) == 0) &&
2414 global_search_state &&
2415 global_search_state->num_domains) {
2416 // we have some domains to search
2417 struct request *req;
2418 if (string_num_dots(name) >= global_search_state->ndots) {
2419 req = request_new(type, name, flags, user_callback, user_arg);
2420 if (!req) return 1;
2421 req->search_index = -1;
2422 } else {
2423 char *const new_name = search_make_new(global_search_state, 0, name);
2424 if (!new_name) return 1;
2425 req = request_new(type, new_name, flags, user_callback, user_arg);
2426 free(new_name);
2427 if (!req) return 1;
2428 req->search_index = 0;
2430 req->search_origname = strdup(name);
2431 req->search_state = global_search_state;
2432 req->search_flags = flags;
2433 global_search_state->refcount++;
2434 request_submit(req);
2435 return 0;
2436 } else {
2437 struct request *const req = request_new(type, name, flags, user_callback, user_arg);
2438 if (!req) return 1;
2439 request_submit(req);
2440 return 0;
2444 // this is called when a request has failed to find a name. We need to check
2445 // if it is part of a search and, if so, try the next name in the list
2446 // returns:
2447 // 0 another request has been submitted
2448 // 1 no more requests needed
2449 static int
2450 search_try_next(struct request *const req) {
2451 if (req->search_state) {
2452 // it is part of a search
2453 char *new_name;
2454 struct request *newreq;
2455 req->search_index++;
2456 if (req->search_index >= req->search_state->num_domains) {
2457 // no more postfixes to try, however we may need to try
2458 // this name without a postfix
2459 if (string_num_dots(req->search_origname) < req->search_state->ndots) {
2460 // yep, we need to try it raw
2461 struct request *const newreq = request_new(req->request_type, req->search_origname, req->search_flags, req->user_callback, req->user_pointer);
2462 log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", req->search_origname);
2463 if (newreq) {
2464 request_submit(newreq);
2465 return 0;
2468 return 1;
2471 new_name = search_make_new(req->search_state, req->search_index, req->search_origname);
2472 if (!new_name) return 1;
2473 log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, req->search_index);
2474 newreq = request_new(req->request_type, new_name, req->search_flags, req->user_callback, req->user_pointer);
2475 free(new_name);
2476 if (!newreq) return 1;
2477 newreq->search_origname = req->search_origname;
2478 req->search_origname = NULL;
2479 newreq->search_state = req->search_state;
2480 newreq->search_flags = req->search_flags;
2481 newreq->search_index = req->search_index;
2482 newreq->search_state->refcount++;
2483 request_submit(newreq);
2484 return 0;
2486 return 1;
2489 static void
2490 search_request_finished(struct request *const req) {
2491 if (req->search_state) {
2492 search_state_decref(req->search_state);
2493 req->search_state = NULL;
2495 if (req->search_origname) {
2496 free(req->search_origname);
2497 req->search_origname = NULL;
2501 /////////////////////////////////////////////////////////////////////
2502 // Parsing resolv.conf files
2504 static void
2505 evdns_resolv_set_defaults(int flags) {
2506 // if the file isn't found then we assume a local resolver
2507 if (flags & DNS_OPTION_SEARCH) search_set_from_hostname();
2508 if (flags & DNS_OPTION_NAMESERVERS) evdns_nameserver_ip_add("127.0.0.1");
2511 #ifndef HAVE_STRTOK_R
2512 static char *
2513 strtok_r(char *s, const char *delim, char **state) {
2514 return strtok(s, delim);
2516 #endif
2518 // helper version of atoi which returns -1 on error
2519 static int
2520 strtoint(const char *const str) {
2521 char *endptr;
2522 const int r = strtol(str, &endptr, 10);
2523 if (*endptr) return -1;
2524 return r;
2527 // helper version of atoi that returns -1 on error and clips to bounds.
2528 static int
2529 strtoint_clipped(const char *const str, int min, int max)
2531 int r = strtoint(str);
2532 if (r == -1)
2533 return r;
2534 else if (r<min)
2535 return min;
2536 else if (r>max)
2537 return max;
2538 else
2539 return r;
2542 // exported function
2544 evdns_set_option(const char *option, const char *val, int flags)
2546 if (!strncmp(option, "ndots:", 6)) {
2547 const int ndots = strtoint(val);
2548 if (ndots == -1) return -1;
2549 if (!(flags & DNS_OPTION_SEARCH)) return 0;
2550 log(EVDNS_LOG_DEBUG, "Setting ndots to %d", ndots);
2551 if (!global_search_state) global_search_state = search_state_new();
2552 if (!global_search_state) return -1;
2553 global_search_state->ndots = ndots;
2554 } else if (!strncmp(option, "timeout:", 8)) {
2555 const int timeout = strtoint(val);
2556 if (timeout == -1) return -1;
2557 if (!(flags & DNS_OPTION_MISC)) return 0;
2558 log(EVDNS_LOG_DEBUG, "Setting timeout to %d", timeout);
2559 global_timeout.tv_sec = timeout;
2560 } else if (!strncmp(option, "max-timeouts:", 12)) {
2561 const int maxtimeout = strtoint_clipped(val, 1, 255);
2562 if (maxtimeout == -1) return -1;
2563 if (!(flags & DNS_OPTION_MISC)) return 0;
2564 log(EVDNS_LOG_DEBUG, "Setting maximum allowed timeouts to %d",
2565 maxtimeout);
2566 global_max_nameserver_timeout = maxtimeout;
2567 } else if (!strncmp(option, "max-inflight:", 13)) {
2568 const int maxinflight = strtoint_clipped(val, 1, 65000);
2569 if (maxinflight == -1) return -1;
2570 if (!(flags & DNS_OPTION_MISC)) return 0;
2571 log(EVDNS_LOG_DEBUG, "Setting maximum inflight requests to %d",
2572 maxinflight);
2573 global_max_requests_inflight = maxinflight;
2574 } else if (!strncmp(option, "attempts:", 9)) {
2575 int retries = strtoint(val);
2576 if (retries == -1) return -1;
2577 if (retries > 255) retries = 255;
2578 if (!(flags & DNS_OPTION_MISC)) return 0;
2579 log(EVDNS_LOG_DEBUG, "Setting retries to %d", retries);
2580 global_max_retransmits = retries;
2582 return 0;
2585 static void
2586 resolv_conf_parse_line(char *const start, int flags) {
2587 char *strtok_state;
2588 static const char *const delims = " \t";
2589 #define NEXT_TOKEN strtok_r(NULL, delims, &strtok_state)
2591 char *const first_token = strtok_r(start, delims, &strtok_state);
2592 if (!first_token) return;
2594 if (!strcmp(first_token, "nameserver") && (flags & DNS_OPTION_NAMESERVERS)) {
2595 const char *const nameserver = NEXT_TOKEN;
2596 struct in_addr ina;
2598 if (inet_aton(nameserver, &ina)) {
2599 // address is valid
2600 evdns_nameserver_add(ina.s_addr);
2602 } else if (!strcmp(first_token, "domain") && (flags & DNS_OPTION_SEARCH)) {
2603 const char *const domain = NEXT_TOKEN;
2604 if (domain) {
2605 search_postfix_clear();
2606 search_postfix_add(domain);
2608 } else if (!strcmp(first_token, "search") && (flags & DNS_OPTION_SEARCH)) {
2609 const char *domain;
2610 search_postfix_clear();
2612 while ((domain = NEXT_TOKEN)) {
2613 search_postfix_add(domain);
2615 search_reverse();
2616 } else if (!strcmp(first_token, "options")) {
2617 const char *option;
2618 while ((option = NEXT_TOKEN)) {
2619 const char *val = strchr(option, ':');
2620 evdns_set_option(option, val ? val+1 : "", flags);
2623 #undef NEXT_TOKEN
2626 // exported function
2627 // returns:
2628 // 0 no errors
2629 // 1 failed to open file
2630 // 2 failed to stat file
2631 // 3 file too large
2632 // 4 out of memory
2633 // 5 short read from file
2635 evdns_resolv_conf_parse(int flags, const char *const filename) {
2636 struct stat st;
2637 int fd;
2638 u8 *resolv;
2639 char *start;
2640 int err = 0;
2642 log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
2644 fd = open(filename, O_RDONLY);
2645 if (fd < 0) {
2646 evdns_resolv_set_defaults(flags);
2647 return 1;
2650 if (fstat(fd, &st)) { err = 2; goto out1; }
2651 if (!st.st_size) {
2652 evdns_resolv_set_defaults(flags);
2653 err = (flags & DNS_OPTION_NAMESERVERS) ? 6 : 0;
2654 goto out1;
2656 if (st.st_size > 65535) { err = 3; goto out1; } // no resolv.conf should be any bigger
2658 resolv = (u8 *) malloc((size_t)st.st_size + 1);
2659 if (!resolv) { err = 4; goto out1; }
2661 if (read(fd, resolv, (size_t)st.st_size) != st.st_size) {
2662 err = 5; goto out2;
2664 resolv[st.st_size] = 0; // we malloced an extra byte
2666 start = (char *) resolv;
2667 for (;;) {
2668 char *const newline = strchr(start, '\n');
2669 if (!newline) {
2670 resolv_conf_parse_line(start, flags);
2671 break;
2672 } else {
2673 *newline = 0;
2674 resolv_conf_parse_line(start, flags);
2675 start = newline + 1;
2679 if (!server_head && (flags & DNS_OPTION_NAMESERVERS)) {
2680 // no nameservers were configured.
2681 evdns_nameserver_ip_add("127.0.0.1");
2682 err = 6;
2684 if (flags & DNS_OPTION_SEARCH && (!global_search_state || global_search_state->num_domains == 0)) {
2685 search_set_from_hostname();
2688 out2:
2689 free(resolv);
2690 out1:
2691 close(fd);
2692 return err;
2695 #ifdef WIN32
2696 // Add multiple nameservers from a space-or-comma-separated list.
2697 static int
2698 evdns_nameserver_ip_add_line(const char *ips) {
2699 const char *addr;
2700 char *buf;
2701 int r;
2702 while (*ips) {
2703 while (ISSPACE(*ips) || *ips == ',' || *ips == '\t')
2704 ++ips;
2705 addr = ips;
2706 while (ISDIGIT(*ips) || *ips == '.')
2707 ++ips;
2708 buf = malloc(ips-addr+1);
2709 if (!buf) return 4;
2710 memcpy(buf, addr, ips-addr);
2711 buf[ips-addr] = '\0';
2712 r = evdns_nameserver_ip_add(buf);
2713 free(buf);
2714 if (r) return r;
2716 return 0;
2719 typedef DWORD(WINAPI *GetNetworkParams_fn_t)(FIXED_INFO *, DWORD*);
2721 // Use the windows GetNetworkParams interface in iphlpapi.dll to
2722 // figure out what our nameservers are.
2723 static int
2724 load_nameservers_with_getnetworkparams(void)
2726 // Based on MSDN examples and inspection of c-ares code.
2727 FIXED_INFO *fixed;
2728 HMODULE handle = 0;
2729 ULONG size = sizeof(FIXED_INFO);
2730 void *buf = NULL;
2731 int status = 0, r, added_any;
2732 IP_ADDR_STRING *ns;
2733 GetNetworkParams_fn_t fn;
2735 if (!(handle = LoadLibrary("iphlpapi.dll"))) {
2736 log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
2737 //right now status = 0, doesn't that mean "good" - mikec
2738 status = -1;
2739 goto done;
2741 if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, "GetNetworkParams"))) {
2742 log(EVDNS_LOG_WARN, "Could not get address of function.");
2743 //same as above
2744 status = -1;
2745 goto done;
2748 buf = malloc(size);
2749 if (!buf) { status = 4; goto done; }
2750 fixed = buf;
2751 r = fn(fixed, &size);
2752 if (r != ERROR_SUCCESS && r != ERROR_BUFFER_OVERFLOW) {
2753 status = -1;
2754 goto done;
2756 if (r != ERROR_SUCCESS) {
2757 free(buf);
2758 buf = malloc(size);
2759 if (!buf) { status = 4; goto done; }
2760 fixed = buf;
2761 r = fn(fixed, &size);
2762 if (r != ERROR_SUCCESS) {
2763 log(EVDNS_LOG_DEBUG, "fn() failed.");
2764 status = -1;
2765 goto done;
2769 assert(fixed);
2770 added_any = 0;
2771 ns = &(fixed->DnsServerList);
2772 while (ns) {
2773 r = evdns_nameserver_ip_add_line(ns->IpAddress.String);
2774 if (r) {
2775 log(EVDNS_LOG_DEBUG,"Could not add nameserver %s to list,error: %d",
2776 (ns->IpAddress.String),(int)GetLastError());
2777 status = r;
2778 goto done;
2779 } else {
2780 log(EVDNS_LOG_DEBUG,"Succesfully added %s as nameserver",ns->IpAddress.String);
2783 added_any++;
2784 ns = ns->Next;
2787 if (!added_any) {
2788 log(EVDNS_LOG_DEBUG, "No nameservers added.");
2789 status = -1;
2792 done:
2793 if (buf)
2794 free(buf);
2795 if (handle)
2796 FreeLibrary(handle);
2797 return status;
2800 static int
2801 config_nameserver_from_reg_key(HKEY key, const char *subkey)
2803 char *buf;
2804 DWORD bufsz = 0, type = 0;
2805 int status = 0;
2807 if (RegQueryValueEx(key, subkey, 0, &type, NULL, &bufsz)
2808 != ERROR_MORE_DATA)
2809 return -1;
2810 if (!(buf = malloc(bufsz)))
2811 return -1;
2813 if (RegQueryValueEx(key, subkey, 0, &type, (LPBYTE)buf, &bufsz)
2814 == ERROR_SUCCESS && bufsz > 1) {
2815 status = evdns_nameserver_ip_add_line(buf);
2818 free(buf);
2819 return status;
2822 #define SERVICES_KEY "System\\CurrentControlSet\\Services\\"
2823 #define WIN_NS_9X_KEY SERVICES_KEY "VxD\\MSTCP"
2824 #define WIN_NS_NT_KEY SERVICES_KEY "Tcpip\\Parameters"
2826 static int
2827 load_nameservers_from_registry(void)
2829 int found = 0;
2830 int r;
2831 #define TRY(k, name) \
2832 if (!found && config_nameserver_from_reg_key(k,name) == 0) { \
2833 log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name); \
2834 found = 1; \
2835 } else if (!found) { \
2836 log(EVDNS_LOG_DEBUG,"Didn't find nameservers in %s/%s", \
2837 #k,#name); \
2840 if (((int)GetVersion()) > 0) { /* NT */
2841 HKEY nt_key = 0, interfaces_key = 0;
2843 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
2844 KEY_READ, &nt_key) != ERROR_SUCCESS) {
2845 log(EVDNS_LOG_DEBUG,"Couldn't open nt key, %d",(int)GetLastError());
2846 return -1;
2848 r = RegOpenKeyEx(nt_key, "Interfaces", 0,
2849 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
2850 &interfaces_key);
2851 if (r != ERROR_SUCCESS) {
2852 log(EVDNS_LOG_DEBUG,"Couldn't open interfaces key, %d",(int)GetLastError());
2853 return -1;
2855 TRY(nt_key, "NameServer");
2856 TRY(nt_key, "DhcpNameServer");
2857 TRY(interfaces_key, "NameServer");
2858 TRY(interfaces_key, "DhcpNameServer");
2859 RegCloseKey(interfaces_key);
2860 RegCloseKey(nt_key);
2861 } else {
2862 HKEY win_key = 0;
2863 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X_KEY, 0,
2864 KEY_READ, &win_key) != ERROR_SUCCESS) {
2865 log(EVDNS_LOG_DEBUG, "Couldn't open registry key, %d", (int)GetLastError());
2866 return -1;
2868 TRY(win_key, "NameServer");
2869 RegCloseKey(win_key);
2872 if (found == 0) {
2873 log(EVDNS_LOG_WARN,"Didn't find any nameservers.");
2876 return found ? 0 : -1;
2877 #undef TRY
2881 evdns_config_windows_nameservers(void)
2883 if (load_nameservers_with_getnetworkparams() == 0)
2884 return 0;
2885 return load_nameservers_from_registry();
2887 #endif
2890 evdns_init(void)
2892 int res = 0;
2893 #ifdef WIN32
2894 evdns_config_windows_nameservers();
2895 #else
2896 res = evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf");
2897 #endif
2899 return (res);
2902 const char *
2903 evdns_err_to_string(int err)
2905 switch (err) {
2906 case DNS_ERR_NONE: return "no error";
2907 case DNS_ERR_FORMAT: return "misformatted query";
2908 case DNS_ERR_SERVERFAILED: return "server failed";
2909 case DNS_ERR_NOTEXIST: return "name does not exist";
2910 case DNS_ERR_NOTIMPL: return "query not implemented";
2911 case DNS_ERR_REFUSED: return "refused";
2913 case DNS_ERR_TRUNCATED: return "reply truncated or ill-formed";
2914 case DNS_ERR_UNKNOWN: return "unknown";
2915 case DNS_ERR_TIMEOUT: return "request timed out";
2916 case DNS_ERR_SHUTDOWN: return "dns subsystem shut down";
2917 default: return "[Unknown error code]";
2921 void
2922 evdns_shutdown(int fail_requests)
2924 struct nameserver *server, *server_next;
2925 struct search_domain *dom, *dom_next;
2927 while (req_head) {
2928 if (fail_requests)
2929 reply_callback(req_head, 0, DNS_ERR_SHUTDOWN, NULL);
2930 request_finished(req_head, &req_head);
2932 while (req_waiting_head) {
2933 if (fail_requests)
2934 reply_callback(req_waiting_head, 0, DNS_ERR_SHUTDOWN, NULL);
2935 request_finished(req_waiting_head, &req_waiting_head);
2937 global_requests_inflight = global_requests_waiting = 0;
2939 for (server = server_head; server; server = server_next) {
2940 server_next = server->next;
2941 if (server->socket >= 0)
2942 CLOSE_SOCKET(server->socket);
2943 (void) event_del(&server->event);
2944 CLEAR(server);
2945 free(server);
2946 if (server_next == server_head)
2947 break;
2949 server_head = NULL;
2950 global_good_nameservers = 0;
2952 if (global_search_state) {
2953 for (dom = global_search_state->head; dom; dom = dom_next) {
2954 dom_next = dom->next;
2955 CLEAR(dom);
2956 free(dom);
2958 CLEAR(global_search_state);
2959 free(global_search_state);
2960 global_search_state = NULL;
2962 evdns_log_fn = NULL;
2965 #ifdef EVDNS_MAIN
2966 void
2967 main_callback(int result, char type, int count, int ttl,
2968 void *addrs, void *orig) {
2969 char *n = (char*)orig;
2970 int i;
2971 for (i = 0; i < count; ++i) {
2972 if (type == DNS_IPv4_A) {
2973 printf("%s: %s\n", n, debug_ntoa(((u32*)addrs)[i]));
2974 } else if (type == DNS_PTR) {
2975 printf("%s: %s\n", n, ((char**)addrs)[i]);
2978 if (!count) {
2979 printf("%s: No answer (%d)\n", n, result);
2981 fflush(stdout);
2983 void
2984 evdns_server_callback(struct evdns_server_request *req, void *data)
2986 int i, r;
2987 (void)data;
2988 /* dummy; give 192.168.11.11 as an answer for all A questions,
2989 * give foo.bar.example.com as an answer for all PTR questions. */
2990 for (i = 0; i < req->nquestions; ++i) {
2991 u32 ans = htonl(0xc0a80b0bUL);
2992 if (req->questions[i]->type == EVDNS_TYPE_A &&
2993 req->questions[i]->class == EVDNS_CLASS_INET) {
2994 printf(" -- replying for %s (A)\n", req->questions[i]->name);
2995 r = evdns_server_request_add_a_reply(req, req->questions[i]->name,
2996 1, &ans, 10);
2997 if (r<0)
2998 printf("eeep, didn't work.\n");
2999 } else if (req->questions[i]->type == EVDNS_TYPE_PTR &&
3000 req->questions[i]->class == EVDNS_CLASS_INET) {
3001 printf(" -- replying for %s (PTR)\n", req->questions[i]->name);
3002 r = evdns_server_request_add_ptr_reply(req, NULL, req->questions[i]->name,
3003 "foo.bar.example.com", 10);
3004 } else {
3005 printf(" -- skipping %s [%d %d]\n", req->questions[i]->name,
3006 req->questions[i]->type, req->questions[i]->class);
3010 r = evdns_request_respond(req, 0);
3011 if (r<0)
3012 printf("eeek, couldn't send reply.\n");
3015 void
3016 logfn(int is_warn, const char *msg) {
3017 (void) is_warn;
3018 fprintf(stderr, "%s\n", msg);
3021 main(int c, char **v) {
3022 int idx;
3023 int reverse = 0, verbose = 1, servertest = 0;
3024 if (c<2) {
3025 fprintf(stderr, "syntax: %s [-x] [-v] hostname\n", v[0]);
3026 fprintf(stderr, "syntax: %s [-servertest]\n", v[0]);
3027 return 1;
3029 idx = 1;
3030 while (idx < c && v[idx][0] == '-') {
3031 if (!strcmp(v[idx], "-x"))
3032 reverse = 1;
3033 else if (!strcmp(v[idx], "-v"))
3034 verbose = 1;
3035 else if (!strcmp(v[idx], "-servertest"))
3036 servertest = 1;
3037 else
3038 fprintf(stderr, "Unknown option %s\n", v[idx]);
3039 ++idx;
3041 event_init();
3042 if (verbose)
3043 evdns_set_log_fn(logfn);
3044 evdns_resolv_conf_parse(DNS_OPTION_NAMESERVERS, "/etc/resolv.conf");
3045 if (servertest) {
3046 int sock;
3047 struct sockaddr_in my_addr;
3048 sock = socket(PF_INET, SOCK_DGRAM, 0);
3049 fcntl(sock, F_SETFL, O_NONBLOCK);
3050 my_addr.sin_family = AF_INET;
3051 my_addr.sin_port = htons(10053);
3052 my_addr.sin_addr.s_addr = INADDR_ANY;
3053 if (bind(sock, (struct sockaddr*)&my_addr, sizeof(my_addr))<0) {
3054 perror("bind");
3055 exit(1);
3057 evdns_add_server_port(sock, 0, evdns_server_callback, NULL);
3059 for (; idx < c; ++idx) {
3060 if (reverse) {
3061 struct in_addr addr;
3062 if (!inet_aton(v[idx], &addr)) {
3063 fprintf(stderr, "Skipping non-IP %s\n", v[idx]);
3064 continue;
3066 fprintf(stderr, "resolving %s...\n",v[idx]);
3067 evdns_resolve_reverse(&addr, 0, main_callback, v[idx]);
3068 } else {
3069 fprintf(stderr, "resolving (fwd) %s...\n",v[idx]);
3070 evdns_resolve_ipv4(v[idx], 0, main_callback, v[idx]);
3073 fflush(stdout);
3074 event_dispatch();
3075 return 0;
3077 #endif
3079 // Local Variables:
3080 // tab-width: 4
3081 // c-basic-offset: 4
3082 // indent-tabs-mode: t
3083 // End: