Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libevent/evdns.c
39475 views
1
/* Copyright 2006-2007 Niels Provos
2
* Copyright 2007-2012 Nick Mathewson and Niels Provos
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
* 3. The name of the author may not be used to endorse or promote products
13
* derived from this software without specific prior written permission.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
*/
26
27
/* Based on software by Adam Langly. Adam's original message:
28
*
29
* Async DNS Library
30
* Adam Langley <[email protected]>
31
* http://www.imperialviolet.org/eventdns.html
32
* Public Domain code
33
*
34
* This software is Public Domain. To view a copy of the public domain dedication,
35
* visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
36
* Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
37
*
38
* I ask and expect, but do not require, that all derivative works contain an
39
* attribution similar to:
40
* Parts developed by Adam Langley <[email protected]>
41
*
42
* You may wish to replace the word "Parts" with something else depending on
43
* the amount of original code.
44
*
45
* (Derivative works does not include programs which link against, run or include
46
* the source verbatim in their source distributions)
47
*
48
* Version: 0.1b
49
*/
50
51
#include "event2/event-config.h"
52
#include "evconfig-private.h"
53
54
#include <sys/types.h>
55
56
#ifndef _FORTIFY_SOURCE
57
#define _FORTIFY_SOURCE 3
58
#endif
59
60
#include <string.h>
61
#include <fcntl.h>
62
#ifdef EVENT__HAVE_SYS_TIME_H
63
#include <sys/time.h>
64
#endif
65
#ifdef EVENT__HAVE_STDINT_H
66
#include <stdint.h>
67
#endif
68
#include <stdlib.h>
69
#include <string.h>
70
#include <errno.h>
71
#ifdef EVENT__HAVE_UNISTD_H
72
#include <unistd.h>
73
#endif
74
#include <limits.h>
75
#include <sys/stat.h>
76
#include <stdio.h>
77
#include <stdarg.h>
78
#ifdef _WIN32
79
#include <winsock2.h>
80
#include <winerror.h>
81
#include <ws2tcpip.h>
82
#ifndef _WIN32_IE
83
#define _WIN32_IE 0x400
84
#endif
85
#include <shlobj.h>
86
#endif
87
88
#include "event2/dns.h"
89
#include "event2/dns_struct.h"
90
#include "event2/dns_compat.h"
91
#include "event2/util.h"
92
#include "event2/event.h"
93
#include "event2/event_struct.h"
94
#include "event2/thread.h"
95
96
#include "defer-internal.h"
97
#include "log-internal.h"
98
#include "mm-internal.h"
99
#include "strlcpy-internal.h"
100
#include "ipv6-internal.h"
101
#include "util-internal.h"
102
#include "evthread-internal.h"
103
#ifdef _WIN32
104
#include <ctype.h>
105
#include <winsock2.h>
106
#include <windows.h>
107
#include <iphlpapi.h>
108
#include <io.h>
109
#else
110
#include <sys/socket.h>
111
#include <netinet/in.h>
112
#include <arpa/inet.h>
113
#endif
114
115
#ifdef EVENT__HAVE_NETINET_IN6_H
116
#include <netinet/in6.h>
117
#endif
118
119
#define EVDNS_LOG_DEBUG EVENT_LOG_DEBUG
120
#define EVDNS_LOG_WARN EVENT_LOG_WARN
121
#define EVDNS_LOG_MSG EVENT_LOG_MSG
122
123
#ifndef HOST_NAME_MAX
124
#define HOST_NAME_MAX 255
125
#endif
126
127
#include <stdio.h>
128
129
#undef MIN
130
#define MIN(a,b) ((a)<(b)?(a):(b))
131
132
#define ASSERT_VALID_REQUEST(req) \
133
EVUTIL_ASSERT((req)->handle && (req)->handle->current_req == (req))
134
135
#define u64 ev_uint64_t
136
#define u32 ev_uint32_t
137
#define u16 ev_uint16_t
138
#define u8 ev_uint8_t
139
140
/* maximum number of addresses from a single packet */
141
/* that we bother recording */
142
#define MAX_V4_ADDRS 32
143
#define MAX_V6_ADDRS 32
144
145
146
#define TYPE_A EVDNS_TYPE_A
147
#define TYPE_CNAME 5
148
#define TYPE_PTR EVDNS_TYPE_PTR
149
#define TYPE_SOA EVDNS_TYPE_SOA
150
#define TYPE_AAAA EVDNS_TYPE_AAAA
151
152
#define CLASS_INET EVDNS_CLASS_INET
153
154
/* Persistent handle. We keep this separate from 'struct request' since we
155
* need some object to last for as long as an evdns_request is outstanding so
156
* that it can be canceled, whereas a search request can lead to multiple
157
* 'struct request' instances being created over its lifetime. */
158
struct evdns_request {
159
struct request *current_req;
160
struct evdns_base *base;
161
162
int pending_cb; /* Waiting for its callback to be invoked; not
163
* owned by event base any more. */
164
165
/* elements used by the searching code */
166
int search_index;
167
struct search_state *search_state;
168
char *search_origname; /* needs to be free()ed */
169
int search_flags;
170
};
171
172
struct request {
173
u8 *request; /* the dns packet data */
174
u8 request_type; /* TYPE_PTR or TYPE_A or TYPE_AAAA */
175
unsigned int request_len;
176
int reissue_count;
177
int tx_count; /* the number of times that this packet has been sent */
178
void *user_pointer; /* the pointer given to us for this request */
179
evdns_callback_type user_callback;
180
struct nameserver *ns; /* the server which we last sent it */
181
182
/* these objects are kept in a circular list */
183
/* XXX We could turn this into a CIRCLEQ. */
184
struct request *next, *prev;
185
186
struct event timeout_event;
187
188
u16 trans_id; /* the transaction id */
189
unsigned request_appended :1; /* true if the request pointer is data which follows this struct */
190
unsigned transmit_me :1; /* needs to be transmitted */
191
192
/* XXXX This is a horrible hack. */
193
char **put_cname_in_ptr; /* store the cname here if we get one. */
194
195
struct evdns_base *base;
196
197
struct evdns_request *handle;
198
};
199
200
struct reply {
201
unsigned int type;
202
unsigned int have_answer : 1;
203
union {
204
struct {
205
u32 addrcount;
206
u32 addresses[MAX_V4_ADDRS];
207
} a;
208
struct {
209
u32 addrcount;
210
struct in6_addr addresses[MAX_V6_ADDRS];
211
} aaaa;
212
struct {
213
char name[HOST_NAME_MAX];
214
} ptr;
215
} data;
216
};
217
218
struct nameserver {
219
evutil_socket_t socket; /* a connected UDP socket */
220
struct sockaddr_storage address;
221
ev_socklen_t addrlen;
222
int failed_times; /* number of times which we have given this server a chance */
223
int timedout; /* number of times in a row a request has timed out */
224
struct event event;
225
/* these objects are kept in a circular list */
226
struct nameserver *next, *prev;
227
struct event timeout_event; /* used to keep the timeout for */
228
/* when we next probe this server. */
229
/* Valid if state == 0 */
230
/* Outstanding probe request for this nameserver, if any */
231
struct evdns_request *probe_request;
232
char state; /* zero if we think that this server is down */
233
char choked; /* true if we have an EAGAIN from this server's socket */
234
char write_waiting; /* true if we are waiting for EV_WRITE events */
235
struct evdns_base *base;
236
237
/* Number of currently inflight requests: used
238
* to track when we should add/del the event. */
239
int requests_inflight;
240
};
241
242
243
/* Represents a local port where we're listening for DNS requests. Right now, */
244
/* only UDP is supported. */
245
struct evdns_server_port {
246
evutil_socket_t socket; /* socket we use to read queries and write replies. */
247
int refcnt; /* reference count. */
248
char choked; /* Are we currently blocked from writing? */
249
char closing; /* Are we trying to close this port, pending writes? */
250
evdns_request_callback_fn_type user_callback; /* Fn to handle requests */
251
void *user_data; /* Opaque pointer passed to user_callback */
252
struct event event; /* Read/write event */
253
/* circular list of replies that we want to write. */
254
struct server_request *pending_replies;
255
struct event_base *event_base;
256
257
#ifndef EVENT__DISABLE_THREAD_SUPPORT
258
void *lock;
259
#endif
260
};
261
262
/* Represents part of a reply being built. (That is, a single RR.) */
263
struct server_reply_item {
264
struct server_reply_item *next; /* next item in sequence. */
265
char *name; /* name part of the RR */
266
u16 type; /* The RR type */
267
u16 class; /* The RR class (usually CLASS_INET) */
268
u32 ttl; /* The RR TTL */
269
char is_name; /* True iff data is a label */
270
u16 datalen; /* Length of data; -1 if data is a label */
271
void *data; /* The contents of the RR */
272
};
273
274
/* Represents a request that we've received as a DNS server, and holds */
275
/* the components of the reply as we're constructing it. */
276
struct server_request {
277
/* Pointers to the next and previous entries on the list of replies */
278
/* that we're waiting to write. Only set if we have tried to respond */
279
/* and gotten EAGAIN. */
280
struct server_request *next_pending;
281
struct server_request *prev_pending;
282
283
u16 trans_id; /* Transaction id. */
284
struct evdns_server_port *port; /* Which port received this request on? */
285
struct sockaddr_storage addr; /* Where to send the response */
286
ev_socklen_t addrlen; /* length of addr */
287
288
int n_answer; /* how many answer RRs have been set? */
289
int n_authority; /* how many authority RRs have been set? */
290
int n_additional; /* how many additional RRs have been set? */
291
292
struct server_reply_item *answer; /* linked list of answer RRs */
293
struct server_reply_item *authority; /* linked list of authority RRs */
294
struct server_reply_item *additional; /* linked list of additional RRs */
295
296
/* Constructed response. Only set once we're ready to send a reply. */
297
/* Once this is set, the RR fields are cleared, and no more should be set. */
298
char *response;
299
size_t response_len;
300
301
/* Caller-visible fields: flags, questions. */
302
struct evdns_server_request base;
303
};
304
305
struct evdns_base {
306
/* An array of n_req_heads circular lists for inflight requests.
307
* Each inflight request req is in req_heads[req->trans_id % n_req_heads].
308
*/
309
struct request **req_heads;
310
/* A circular list of requests that we're waiting to send, but haven't
311
* sent yet because there are too many requests inflight */
312
struct request *req_waiting_head;
313
/* A circular list of nameservers. */
314
struct nameserver *server_head;
315
int n_req_heads;
316
317
struct event_base *event_base;
318
319
/* The number of good nameservers that we have */
320
int global_good_nameservers;
321
322
/* inflight requests are contained in the req_head list */
323
/* and are actually going out across the network */
324
int global_requests_inflight;
325
/* requests which aren't inflight are in the waiting list */
326
/* and are counted here */
327
int global_requests_waiting;
328
329
int global_max_requests_inflight;
330
331
struct timeval global_timeout; /* 5 seconds by default */
332
int global_max_reissues; /* a reissue occurs when we get some errors from the server */
333
int global_max_retransmits; /* number of times we'll retransmit a request which timed out */
334
/* number of timeouts in a row before we consider this server to be down */
335
int global_max_nameserver_timeout;
336
/* true iff we will use the 0x20 hack to prevent poisoning attacks. */
337
int global_randomize_case;
338
339
/* The first time that a nameserver fails, how long do we wait before
340
* probing to see if it has returned? */
341
struct timeval global_nameserver_probe_initial_timeout;
342
343
/** Port to bind to for outgoing DNS packets. */
344
struct sockaddr_storage global_outgoing_address;
345
/** ev_socklen_t for global_outgoing_address. 0 if it isn't set. */
346
ev_socklen_t global_outgoing_addrlen;
347
348
struct timeval global_getaddrinfo_allow_skew;
349
350
int so_rcvbuf;
351
int so_sndbuf;
352
353
int getaddrinfo_ipv4_timeouts;
354
int getaddrinfo_ipv6_timeouts;
355
int getaddrinfo_ipv4_answered;
356
int getaddrinfo_ipv6_answered;
357
358
struct search_state *global_search_state;
359
360
TAILQ_HEAD(hosts_list, hosts_entry) hostsdb;
361
362
#ifndef EVENT__DISABLE_THREAD_SUPPORT
363
void *lock;
364
#endif
365
366
int disable_when_inactive;
367
};
368
369
struct hosts_entry {
370
TAILQ_ENTRY(hosts_entry) next;
371
union {
372
struct sockaddr sa;
373
struct sockaddr_in sin;
374
struct sockaddr_in6 sin6;
375
} addr;
376
int addrlen;
377
char hostname[1];
378
};
379
380
static struct evdns_base *current_base = NULL;
381
382
struct evdns_base *
383
evdns_get_global_base(void)
384
{
385
return current_base;
386
}
387
388
/* Given a pointer to an evdns_server_request, get the corresponding */
389
/* server_request. */
390
#define TO_SERVER_REQUEST(base_ptr) \
391
((struct server_request*) \
392
(((char*)(base_ptr) - evutil_offsetof(struct server_request, base))))
393
394
#define REQ_HEAD(base, id) ((base)->req_heads[id % (base)->n_req_heads])
395
396
static struct nameserver *nameserver_pick(struct evdns_base *base);
397
static void evdns_request_insert(struct request *req, struct request **head);
398
static void evdns_request_remove(struct request *req, struct request **head);
399
static void nameserver_ready_callback(evutil_socket_t fd, short events, void *arg);
400
static int evdns_transmit(struct evdns_base *base);
401
static int evdns_request_transmit(struct request *req);
402
static void nameserver_send_probe(struct nameserver *const ns);
403
static void search_request_finished(struct evdns_request *const);
404
static int search_try_next(struct evdns_request *const req);
405
static struct request *search_request_new(struct evdns_base *base, struct evdns_request *handle, int type, const char *const name, int flags, evdns_callback_type user_callback, void *user_arg);
406
static void evdns_requests_pump_waiting_queue(struct evdns_base *base);
407
static u16 transaction_id_pick(struct evdns_base *base);
408
static struct request *request_new(struct evdns_base *base, struct evdns_request *handle, int type, const char *name, int flags, evdns_callback_type callback, void *ptr);
409
static void request_submit(struct request *const req);
410
411
static int server_request_free(struct server_request *req);
412
static void server_request_free_answers(struct server_request *req);
413
static void server_port_free(struct evdns_server_port *port);
414
static void server_port_ready_callback(evutil_socket_t fd, short events, void *arg);
415
static int evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char *const filename);
416
static int evdns_base_set_option_impl(struct evdns_base *base,
417
const char *option, const char *val, int flags);
418
static void evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests);
419
static void evdns_request_timeout_callback(evutil_socket_t fd, short events, void *arg);
420
421
static int strtoint(const char *const str);
422
423
#ifdef EVENT__DISABLE_THREAD_SUPPORT
424
#define EVDNS_LOCK(base) EVUTIL_NIL_STMT_
425
#define EVDNS_UNLOCK(base) EVUTIL_NIL_STMT_
426
#define ASSERT_LOCKED(base) EVUTIL_NIL_STMT_
427
#else
428
#define EVDNS_LOCK(base) \
429
EVLOCK_LOCK((base)->lock, 0)
430
#define EVDNS_UNLOCK(base) \
431
EVLOCK_UNLOCK((base)->lock, 0)
432
#define ASSERT_LOCKED(base) \
433
EVLOCK_ASSERT_LOCKED((base)->lock)
434
#endif
435
436
static evdns_debug_log_fn_type evdns_log_fn = NULL;
437
438
void
439
evdns_set_log_fn(evdns_debug_log_fn_type fn)
440
{
441
evdns_log_fn = fn;
442
}
443
444
#ifdef __GNUC__
445
#define EVDNS_LOG_CHECK __attribute__ ((format(printf, 2, 3)))
446
#else
447
#define EVDNS_LOG_CHECK
448
#endif
449
450
static void evdns_log_(int severity, const char *fmt, ...) EVDNS_LOG_CHECK;
451
static void
452
evdns_log_(int severity, const char *fmt, ...)
453
{
454
va_list args;
455
va_start(args,fmt);
456
if (evdns_log_fn) {
457
char buf[512];
458
int is_warn = (severity == EVDNS_LOG_WARN);
459
evutil_vsnprintf(buf, sizeof(buf), fmt, args);
460
evdns_log_fn(is_warn, buf);
461
} else {
462
event_logv_(severity, NULL, fmt, args);
463
}
464
va_end(args);
465
}
466
467
#define log evdns_log_
468
469
/* This walks the list of inflight requests to find the */
470
/* one with a matching transaction id. Returns NULL on */
471
/* failure */
472
static struct request *
473
request_find_from_trans_id(struct evdns_base *base, u16 trans_id) {
474
struct request *req = REQ_HEAD(base, trans_id);
475
struct request *const started_at = req;
476
477
ASSERT_LOCKED(base);
478
479
if (req) {
480
do {
481
if (req->trans_id == trans_id) return req;
482
req = req->next;
483
} while (req != started_at);
484
}
485
486
return NULL;
487
}
488
489
/* a libevent callback function which is called when a nameserver */
490
/* has gone down and we want to test if it has came back to life yet */
491
static void
492
nameserver_prod_callback(evutil_socket_t fd, short events, void *arg) {
493
struct nameserver *const ns = (struct nameserver *) arg;
494
(void)fd;
495
(void)events;
496
497
EVDNS_LOCK(ns->base);
498
nameserver_send_probe(ns);
499
EVDNS_UNLOCK(ns->base);
500
}
501
502
/* a libevent callback which is called when a nameserver probe (to see if */
503
/* it has come back to life) times out. We increment the count of failed_times */
504
/* and wait longer to send the next probe packet. */
505
static void
506
nameserver_probe_failed(struct nameserver *const ns) {
507
struct timeval timeout;
508
int i;
509
510
ASSERT_LOCKED(ns->base);
511
(void) evtimer_del(&ns->timeout_event);
512
if (ns->state == 1) {
513
/* This can happen if the nameserver acts in a way which makes us mark */
514
/* it as bad and then starts sending good replies. */
515
return;
516
}
517
518
#define MAX_PROBE_TIMEOUT 3600
519
#define TIMEOUT_BACKOFF_FACTOR 3
520
521
memcpy(&timeout, &ns->base->global_nameserver_probe_initial_timeout,
522
sizeof(struct timeval));
523
for (i=ns->failed_times; i > 0 && timeout.tv_sec < MAX_PROBE_TIMEOUT; --i) {
524
timeout.tv_sec *= TIMEOUT_BACKOFF_FACTOR;
525
timeout.tv_usec *= TIMEOUT_BACKOFF_FACTOR;
526
if (timeout.tv_usec > 1000000) {
527
timeout.tv_sec += timeout.tv_usec / 1000000;
528
timeout.tv_usec %= 1000000;
529
}
530
}
531
if (timeout.tv_sec > MAX_PROBE_TIMEOUT) {
532
timeout.tv_sec = MAX_PROBE_TIMEOUT;
533
timeout.tv_usec = 0;
534
}
535
536
ns->failed_times++;
537
538
if (evtimer_add(&ns->timeout_event, &timeout) < 0) {
539
char addrbuf[128];
540
log(EVDNS_LOG_WARN,
541
"Error from libevent when adding timer event for %s",
542
evutil_format_sockaddr_port_(
543
(struct sockaddr *)&ns->address,
544
addrbuf, sizeof(addrbuf)));
545
}
546
}
547
548
static void
549
request_swap_ns(struct request *req, struct nameserver *ns) {
550
if (ns && req->ns != ns) {
551
EVUTIL_ASSERT(req->ns->requests_inflight > 0);
552
req->ns->requests_inflight--;
553
ns->requests_inflight++;
554
555
req->ns = ns;
556
}
557
}
558
559
/* called when a nameserver has been deemed to have failed. For example, too */
560
/* many packets have timed out etc */
561
static void
562
nameserver_failed(struct nameserver *const ns, const char *msg) {
563
struct request *req, *started_at;
564
struct evdns_base *base = ns->base;
565
int i;
566
char addrbuf[128];
567
568
ASSERT_LOCKED(base);
569
/* if this nameserver has already been marked as failed */
570
/* then don't do anything */
571
if (!ns->state) return;
572
573
log(EVDNS_LOG_MSG, "Nameserver %s has failed: %s",
574
evutil_format_sockaddr_port_(
575
(struct sockaddr *)&ns->address,
576
addrbuf, sizeof(addrbuf)),
577
msg);
578
579
base->global_good_nameservers--;
580
EVUTIL_ASSERT(base->global_good_nameservers >= 0);
581
if (base->global_good_nameservers == 0) {
582
log(EVDNS_LOG_MSG, "All nameservers have failed");
583
}
584
585
ns->state = 0;
586
ns->failed_times = 1;
587
588
if (evtimer_add(&ns->timeout_event,
589
&base->global_nameserver_probe_initial_timeout) < 0) {
590
log(EVDNS_LOG_WARN,
591
"Error from libevent when adding timer event for %s",
592
evutil_format_sockaddr_port_(
593
(struct sockaddr *)&ns->address,
594
addrbuf, sizeof(addrbuf)));
595
/* ???? Do more? */
596
}
597
598
/* walk the list of inflight requests to see if any can be reassigned to */
599
/* a different server. Requests in the waiting queue don't have a */
600
/* nameserver assigned yet */
601
602
/* if we don't have *any* good nameservers then there's no point */
603
/* trying to reassign requests to one */
604
if (!base->global_good_nameservers) return;
605
606
for (i = 0; i < base->n_req_heads; ++i) {
607
req = started_at = base->req_heads[i];
608
if (req) {
609
do {
610
if (req->tx_count == 0 && req->ns == ns) {
611
/* still waiting to go out, can be moved */
612
/* to another server */
613
request_swap_ns(req, nameserver_pick(base));
614
}
615
req = req->next;
616
} while (req != started_at);
617
}
618
}
619
}
620
621
static void
622
nameserver_up(struct nameserver *const ns)
623
{
624
char addrbuf[128];
625
ASSERT_LOCKED(ns->base);
626
if (ns->state) return;
627
log(EVDNS_LOG_MSG, "Nameserver %s is back up",
628
evutil_format_sockaddr_port_(
629
(struct sockaddr *)&ns->address,
630
addrbuf, sizeof(addrbuf)));
631
evtimer_del(&ns->timeout_event);
632
if (ns->probe_request) {
633
evdns_cancel_request(ns->base, ns->probe_request);
634
ns->probe_request = NULL;
635
}
636
ns->state = 1;
637
ns->failed_times = 0;
638
ns->timedout = 0;
639
ns->base->global_good_nameservers++;
640
}
641
642
static void
643
request_trans_id_set(struct request *const req, const u16 trans_id) {
644
req->trans_id = trans_id;
645
*((u16 *) req->request) = htons(trans_id);
646
}
647
648
/* Called to remove a request from a list and dealloc it. */
649
/* head is a pointer to the head of the list it should be */
650
/* removed from or NULL if the request isn't in a list. */
651
/* when free_handle is one, free the handle as well. */
652
static void
653
request_finished(struct request *const req, struct request **head, int free_handle) {
654
struct evdns_base *base = req->base;
655
int was_inflight = (head != &base->req_waiting_head);
656
EVDNS_LOCK(base);
657
ASSERT_VALID_REQUEST(req);
658
659
if (head)
660
evdns_request_remove(req, head);
661
662
log(EVDNS_LOG_DEBUG, "Removing timeout for request %p", req);
663
if (was_inflight) {
664
evtimer_del(&req->timeout_event);
665
base->global_requests_inflight--;
666
req->ns->requests_inflight--;
667
} else {
668
base->global_requests_waiting--;
669
}
670
/* it was initialized during request_new / evtimer_assign */
671
event_debug_unassign(&req->timeout_event);
672
673
if (req->ns &&
674
req->ns->requests_inflight == 0 &&
675
req->base->disable_when_inactive) {
676
event_del(&req->ns->event);
677
evtimer_del(&req->ns->timeout_event);
678
}
679
680
if (!req->request_appended) {
681
/* need to free the request data on it's own */
682
mm_free(req->request);
683
} else {
684
/* the request data is appended onto the header */
685
/* so everything gets free()ed when we: */
686
}
687
688
if (req->handle) {
689
EVUTIL_ASSERT(req->handle->current_req == req);
690
691
if (free_handle) {
692
search_request_finished(req->handle);
693
req->handle->current_req = NULL;
694
if (! req->handle->pending_cb) {
695
/* If we're planning to run the callback,
696
* don't free the handle until later. */
697
mm_free(req->handle);
698
}
699
req->handle = NULL; /* If we have a bug, let's crash
700
* early */
701
} else {
702
req->handle->current_req = NULL;
703
}
704
}
705
706
mm_free(req);
707
708
evdns_requests_pump_waiting_queue(base);
709
EVDNS_UNLOCK(base);
710
}
711
712
/* This is called when a server returns a funny error code. */
713
/* We try the request again with another server. */
714
/* */
715
/* return: */
716
/* 0 ok */
717
/* 1 failed/reissue is pointless */
718
static int
719
request_reissue(struct request *req) {
720
const struct nameserver *const last_ns = req->ns;
721
ASSERT_LOCKED(req->base);
722
ASSERT_VALID_REQUEST(req);
723
/* the last nameserver should have been marked as failing */
724
/* by the caller of this function, therefore pick will try */
725
/* not to return it */
726
request_swap_ns(req, nameserver_pick(req->base));
727
if (req->ns == last_ns) {
728
/* ... but pick did return it */
729
/* not a lot of point in trying again with the */
730
/* same server */
731
return 1;
732
}
733
734
req->reissue_count++;
735
req->tx_count = 0;
736
req->transmit_me = 1;
737
738
return 0;
739
}
740
741
/* this function looks for space on the inflight queue and promotes */
742
/* requests from the waiting queue if it can. */
743
/* */
744
/* TODO: */
745
/* add return code, see at nameserver_pick() and other functions. */
746
static void
747
evdns_requests_pump_waiting_queue(struct evdns_base *base) {
748
ASSERT_LOCKED(base);
749
while (base->global_requests_inflight < base->global_max_requests_inflight &&
750
base->global_requests_waiting) {
751
struct request *req;
752
753
EVUTIL_ASSERT(base->req_waiting_head);
754
req = base->req_waiting_head;
755
756
req->ns = nameserver_pick(base);
757
if (!req->ns)
758
return;
759
760
/* move a request from the waiting queue to the inflight queue */
761
req->ns->requests_inflight++;
762
763
evdns_request_remove(req, &base->req_waiting_head);
764
765
base->global_requests_waiting--;
766
base->global_requests_inflight++;
767
768
request_trans_id_set(req, transaction_id_pick(base));
769
770
evdns_request_insert(req, &REQ_HEAD(base, req->trans_id));
771
evdns_request_transmit(req);
772
evdns_transmit(base);
773
}
774
}
775
776
/* TODO(nickm) document */
777
struct deferred_reply_callback {
778
struct event_callback deferred;
779
struct evdns_request *handle;
780
u8 request_type;
781
u8 have_reply;
782
u32 ttl;
783
u32 err;
784
evdns_callback_type user_callback;
785
struct reply reply;
786
};
787
788
static void
789
reply_run_callback(struct event_callback *d, void *user_pointer)
790
{
791
struct deferred_reply_callback *cb =
792
EVUTIL_UPCAST(d, struct deferred_reply_callback, deferred);
793
794
switch (cb->request_type) {
795
case TYPE_A:
796
if (cb->have_reply)
797
cb->user_callback(DNS_ERR_NONE, DNS_IPv4_A,
798
cb->reply.data.a.addrcount, cb->ttl,
799
cb->reply.data.a.addresses,
800
user_pointer);
801
else
802
cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer);
803
break;
804
case TYPE_PTR:
805
if (cb->have_reply) {
806
char *name = cb->reply.data.ptr.name;
807
cb->user_callback(DNS_ERR_NONE, DNS_PTR, 1, cb->ttl,
808
&name, user_pointer);
809
} else {
810
cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer);
811
}
812
break;
813
case TYPE_AAAA:
814
if (cb->have_reply)
815
cb->user_callback(DNS_ERR_NONE, DNS_IPv6_AAAA,
816
cb->reply.data.aaaa.addrcount, cb->ttl,
817
cb->reply.data.aaaa.addresses,
818
user_pointer);
819
else
820
cb->user_callback(cb->err, 0, 0, cb->ttl, NULL, user_pointer);
821
break;
822
default:
823
EVUTIL_ASSERT(0);
824
}
825
826
if (cb->handle && cb->handle->pending_cb) {
827
mm_free(cb->handle);
828
}
829
830
mm_free(cb);
831
}
832
833
static void
834
reply_schedule_callback(struct request *const req, u32 ttl, u32 err, struct reply *reply)
835
{
836
struct deferred_reply_callback *d = mm_calloc(1, sizeof(*d));
837
838
if (!d) {
839
event_warn("%s: Couldn't allocate space for deferred callback.",
840
__func__);
841
return;
842
}
843
844
ASSERT_LOCKED(req->base);
845
846
d->request_type = req->request_type;
847
d->user_callback = req->user_callback;
848
d->ttl = ttl;
849
d->err = err;
850
if (reply) {
851
d->have_reply = 1;
852
memcpy(&d->reply, reply, sizeof(struct reply));
853
}
854
855
if (req->handle) {
856
req->handle->pending_cb = 1;
857
d->handle = req->handle;
858
}
859
860
event_deferred_cb_init_(
861
&d->deferred,
862
event_get_priority(&req->timeout_event),
863
reply_run_callback,
864
req->user_pointer);
865
event_deferred_cb_schedule_(
866
req->base->event_base,
867
&d->deferred);
868
}
869
870
871
#define _QR_MASK 0x8000U
872
#define _OP_MASK 0x7800U
873
#define _AA_MASK 0x0400U
874
#define _TC_MASK 0x0200U
875
#define _RD_MASK 0x0100U
876
#define _RA_MASK 0x0080U
877
#define _Z_MASK 0x0040U
878
#define _AD_MASK 0x0020U
879
#define _CD_MASK 0x0010U
880
#define _RCODE_MASK 0x000fU
881
#define _Z_MASK_DEPRECATED 0x0070U
882
883
/* this processes a parsed reply packet */
884
static void
885
reply_handle(struct request *const req, u16 flags, u32 ttl, struct reply *reply) {
886
int error;
887
char addrbuf[128];
888
static const int error_codes[] = {
889
DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST,
890
DNS_ERR_NOTIMPL, DNS_ERR_REFUSED
891
};
892
893
ASSERT_LOCKED(req->base);
894
ASSERT_VALID_REQUEST(req);
895
896
if (flags & (_RCODE_MASK | _TC_MASK) || !reply || !reply->have_answer) {
897
/* there was an error */
898
if (flags & _TC_MASK) {
899
error = DNS_ERR_TRUNCATED;
900
} else if (flags & _RCODE_MASK) {
901
u16 error_code = (flags & _RCODE_MASK) - 1;
902
if (error_code > 4) {
903
error = DNS_ERR_UNKNOWN;
904
} else {
905
error = error_codes[error_code];
906
}
907
} else if (reply && !reply->have_answer) {
908
error = DNS_ERR_NODATA;
909
} else {
910
error = DNS_ERR_UNKNOWN;
911
}
912
913
switch (error) {
914
case DNS_ERR_NOTIMPL:
915
case DNS_ERR_REFUSED:
916
/* we regard these errors as marking a bad nameserver */
917
if (req->reissue_count < req->base->global_max_reissues) {
918
char msg[64];
919
evutil_snprintf(msg, sizeof(msg), "Bad response %d (%s)",
920
error, evdns_err_to_string(error));
921
nameserver_failed(req->ns, msg);
922
if (!request_reissue(req)) return;
923
}
924
break;
925
case DNS_ERR_SERVERFAILED:
926
/* rcode 2 (servfailed) sometimes means "we
927
* are broken" and sometimes (with some binds)
928
* means "that request was very confusing."
929
* Treat this as a timeout, not a failure.
930
*/
931
log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver"
932
"at %s; will allow the request to time out.",
933
evutil_format_sockaddr_port_(
934
(struct sockaddr *)&req->ns->address,
935
addrbuf, sizeof(addrbuf)));
936
/* Call the timeout function */
937
evdns_request_timeout_callback(0, 0, req);
938
return;
939
default:
940
/* we got a good reply from the nameserver: it is up. */
941
if (req->handle == req->ns->probe_request) {
942
/* Avoid double-free */
943
req->ns->probe_request = NULL;
944
}
945
946
nameserver_up(req->ns);
947
}
948
949
if (req->handle->search_state &&
950
req->request_type != TYPE_PTR) {
951
/* if we have a list of domains to search in,
952
* try the next one */
953
if (!search_try_next(req->handle)) {
954
/* a new request was issued so this
955
* request is finished and */
956
/* the user callback will be made when
957
* that request (or a */
958
/* child of it) finishes. */
959
return;
960
}
961
}
962
963
/* all else failed. Pass the failure up */
964
reply_schedule_callback(req, ttl, error, NULL);
965
request_finished(req, &REQ_HEAD(req->base, req->trans_id), 1);
966
} else {
967
/* all ok, tell the user */
968
reply_schedule_callback(req, ttl, 0, reply);
969
if (req->handle == req->ns->probe_request)
970
req->ns->probe_request = NULL; /* Avoid double-free */
971
nameserver_up(req->ns);
972
request_finished(req, &REQ_HEAD(req->base, req->trans_id), 1);
973
}
974
}
975
976
static int
977
name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
978
int name_end = -1;
979
int j = *idx;
980
int ptr_count = 0;
981
#define GET32(x) do { if (j + 4 > length) goto err; memcpy(&t32_, packet + j, 4); j += 4; x = ntohl(t32_); } while (0)
982
#define GET16(x) do { if (j + 2 > length) goto err; memcpy(&t_, packet + j, 2); j += 2; x = ntohs(t_); } while (0)
983
#define GET8(x) do { if (j >= length) goto err; x = packet[j++]; } while (0)
984
985
char *cp = name_out;
986
const char *const end = name_out + name_out_len;
987
988
/* Normally, names are a series of length prefixed strings terminated */
989
/* with a length of 0 (the lengths are u8's < 63). */
990
/* However, the length can start with a pair of 1 bits and that */
991
/* means that the next 14 bits are a pointer within the current */
992
/* packet. */
993
994
for (;;) {
995
u8 label_len;
996
GET8(label_len);
997
if (!label_len) break;
998
if (label_len & 0xc0) {
999
u8 ptr_low;
1000
GET8(ptr_low);
1001
if (name_end < 0) name_end = j;
1002
j = (((int)label_len & 0x3f) << 8) + ptr_low;
1003
/* Make sure that the target offset is in-bounds. */
1004
if (j < 0 || j >= length) return -1;
1005
/* If we've jumped more times than there are characters in the
1006
* message, we must have a loop. */
1007
if (++ptr_count > length) return -1;
1008
continue;
1009
}
1010
if (label_len > 63) return -1;
1011
if (cp != name_out) {
1012
if (cp + 1 >= end) return -1;
1013
*cp++ = '.';
1014
}
1015
if (cp + label_len >= end) return -1;
1016
if (j + label_len > length) return -1;
1017
memcpy(cp, packet + j, label_len);
1018
cp += label_len;
1019
j += label_len;
1020
}
1021
if (cp >= end) return -1;
1022
*cp = '\0';
1023
if (name_end < 0)
1024
*idx = j;
1025
else
1026
*idx = name_end;
1027
return 0;
1028
err:
1029
return -1;
1030
}
1031
1032
/* parses a raw request from a nameserver */
1033
static int
1034
reply_parse(struct evdns_base *base, u8 *packet, int length) {
1035
int j = 0, k = 0; /* index into packet */
1036
u16 t_; /* used by the macros */
1037
u32 t32_; /* used by the macros */
1038
char tmp_name[256], cmp_name[256]; /* used by the macros */
1039
int name_matches = 0;
1040
1041
u16 trans_id, questions, answers, authority, additional, datalength;
1042
u16 flags = 0;
1043
u32 ttl, ttl_r = 0xffffffff;
1044
struct reply reply;
1045
struct request *req = NULL;
1046
unsigned int i;
1047
1048
ASSERT_LOCKED(base);
1049
1050
GET16(trans_id);
1051
GET16(flags);
1052
GET16(questions);
1053
GET16(answers);
1054
GET16(authority);
1055
GET16(additional);
1056
(void) authority; /* suppress "unused variable" warnings. */
1057
(void) additional; /* suppress "unused variable" warnings. */
1058
1059
req = request_find_from_trans_id(base, trans_id);
1060
if (!req) return -1;
1061
EVUTIL_ASSERT(req->base == base);
1062
1063
memset(&reply, 0, sizeof(reply));
1064
1065
/* If it's not an answer, it doesn't correspond to any request. */
1066
if (!(flags & _QR_MASK)) return -1; /* must be an answer */
1067
if ((flags & (_RCODE_MASK|_TC_MASK)) && (flags & (_RCODE_MASK|_TC_MASK)) != DNS_ERR_NOTEXIST) {
1068
/* there was an error and it's not NXDOMAIN */
1069
goto err;
1070
}
1071
/* if (!answers) return; */ /* must have an answer of some form */
1072
1073
/* This macro skips a name in the DNS reply. */
1074
#define SKIP_NAME \
1075
do { tmp_name[0] = '\0'; \
1076
if (name_parse(packet, length, &j, tmp_name, \
1077
sizeof(tmp_name))<0) \
1078
goto err; \
1079
} while (0)
1080
1081
reply.type = req->request_type;
1082
1083
/* skip over each question in the reply */
1084
for (i = 0; i < questions; ++i) {
1085
/* the question looks like
1086
* <label:name><u16:type><u16:class>
1087
*/
1088
tmp_name[0] = '\0';
1089
cmp_name[0] = '\0';
1090
k = j;
1091
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name)) < 0)
1092
goto err;
1093
if (name_parse(req->request, req->request_len, &k,
1094
cmp_name, sizeof(cmp_name))<0)
1095
goto err;
1096
if (!base->global_randomize_case) {
1097
if (strcmp(tmp_name, cmp_name) == 0)
1098
name_matches = 1;
1099
} else {
1100
if (evutil_ascii_strcasecmp(tmp_name, cmp_name) == 0)
1101
name_matches = 1;
1102
}
1103
1104
j += 4;
1105
if (j > length)
1106
goto err;
1107
}
1108
1109
if (!name_matches)
1110
goto err;
1111
1112
/* now we have the answer section which looks like
1113
* <label:name><u16:type><u16:class><u32:ttl><u16:len><data...>
1114
*/
1115
1116
for (i = 0; i < answers; ++i) {
1117
u16 type, class;
1118
1119
SKIP_NAME;
1120
GET16(type);
1121
GET16(class);
1122
GET32(ttl);
1123
GET16(datalength);
1124
1125
if (type == TYPE_A && class == CLASS_INET) {
1126
int addrcount, addrtocopy;
1127
if (req->request_type != TYPE_A) {
1128
j += datalength; continue;
1129
}
1130
if ((datalength & 3) != 0) /* not an even number of As. */
1131
goto err;
1132
addrcount = datalength >> 2;
1133
addrtocopy = MIN(MAX_V4_ADDRS - reply.data.a.addrcount, (unsigned)addrcount);
1134
1135
ttl_r = MIN(ttl_r, ttl);
1136
/* we only bother with the first four addresses. */
1137
if (j + 4*addrtocopy > length) goto err;
1138
memcpy(&reply.data.a.addresses[reply.data.a.addrcount],
1139
packet + j, 4*addrtocopy);
1140
j += 4*addrtocopy;
1141
reply.data.a.addrcount += addrtocopy;
1142
reply.have_answer = 1;
1143
if (reply.data.a.addrcount == MAX_V4_ADDRS) break;
1144
} else if (type == TYPE_PTR && class == CLASS_INET) {
1145
if (req->request_type != TYPE_PTR) {
1146
j += datalength; continue;
1147
}
1148
if (name_parse(packet, length, &j, reply.data.ptr.name,
1149
sizeof(reply.data.ptr.name))<0)
1150
goto err;
1151
ttl_r = MIN(ttl_r, ttl);
1152
reply.have_answer = 1;
1153
break;
1154
} else if (type == TYPE_CNAME) {
1155
char cname[HOST_NAME_MAX];
1156
if (!req->put_cname_in_ptr || *req->put_cname_in_ptr) {
1157
j += datalength; continue;
1158
}
1159
if (name_parse(packet, length, &j, cname,
1160
sizeof(cname))<0)
1161
goto err;
1162
*req->put_cname_in_ptr = mm_strdup(cname);
1163
} else if (type == TYPE_AAAA && class == CLASS_INET) {
1164
int addrcount, addrtocopy;
1165
if (req->request_type != TYPE_AAAA) {
1166
j += datalength; continue;
1167
}
1168
if ((datalength & 15) != 0) /* not an even number of AAAAs. */
1169
goto err;
1170
addrcount = datalength >> 4; /* each address is 16 bytes long */
1171
addrtocopy = MIN(MAX_V6_ADDRS - reply.data.aaaa.addrcount, (unsigned)addrcount);
1172
ttl_r = MIN(ttl_r, ttl);
1173
1174
/* we only bother with the first four addresses. */
1175
if (j + 16*addrtocopy > length) goto err;
1176
memcpy(&reply.data.aaaa.addresses[reply.data.aaaa.addrcount],
1177
packet + j, 16*addrtocopy);
1178
reply.data.aaaa.addrcount += addrtocopy;
1179
j += 16*addrtocopy;
1180
reply.have_answer = 1;
1181
if (reply.data.aaaa.addrcount == MAX_V6_ADDRS) break;
1182
} else {
1183
/* skip over any other type of resource */
1184
j += datalength;
1185
}
1186
}
1187
1188
if (!reply.have_answer) {
1189
for (i = 0; i < authority; ++i) {
1190
u16 type, class;
1191
SKIP_NAME;
1192
GET16(type);
1193
GET16(class);
1194
GET32(ttl);
1195
GET16(datalength);
1196
if (type == TYPE_SOA && class == CLASS_INET) {
1197
u32 serial, refresh, retry, expire, minimum;
1198
SKIP_NAME;
1199
SKIP_NAME;
1200
GET32(serial);
1201
GET32(refresh);
1202
GET32(retry);
1203
GET32(expire);
1204
GET32(minimum);
1205
(void)expire;
1206
(void)retry;
1207
(void)refresh;
1208
(void)serial;
1209
ttl_r = MIN(ttl_r, ttl);
1210
ttl_r = MIN(ttl_r, minimum);
1211
} else {
1212
/* skip over any other type of resource */
1213
j += datalength;
1214
}
1215
}
1216
}
1217
1218
if (ttl_r == 0xffffffff)
1219
ttl_r = 0;
1220
1221
reply_handle(req, flags, ttl_r, &reply);
1222
return 0;
1223
err:
1224
if (req)
1225
reply_handle(req, flags, 0, NULL);
1226
return -1;
1227
}
1228
1229
/* Parse a raw request (packet,length) sent to a nameserver port (port) from */
1230
/* a DNS client (addr,addrlen), and if it's well-formed, call the corresponding */
1231
/* callback. */
1232
static int
1233
request_parse(u8 *packet, int length, struct evdns_server_port *port, struct sockaddr *addr, ev_socklen_t addrlen)
1234
{
1235
int j = 0; /* index into packet */
1236
u16 t_; /* used by the macros */
1237
char tmp_name[256]; /* used by the macros */
1238
1239
int i;
1240
u16 trans_id, flags, questions, answers, authority, additional;
1241
struct server_request *server_req = NULL;
1242
1243
ASSERT_LOCKED(port);
1244
1245
/* Get the header fields */
1246
GET16(trans_id);
1247
GET16(flags);
1248
GET16(questions);
1249
GET16(answers);
1250
GET16(authority);
1251
GET16(additional);
1252
(void)answers;
1253
(void)additional;
1254
(void)authority;
1255
1256
if (flags & _QR_MASK) return -1; /* Must not be an answer. */
1257
flags &= (_RD_MASK|_CD_MASK); /* Only RD and CD get preserved. */
1258
1259
server_req = mm_malloc(sizeof(struct server_request));
1260
if (server_req == NULL) return -1;
1261
memset(server_req, 0, sizeof(struct server_request));
1262
1263
server_req->trans_id = trans_id;
1264
memcpy(&server_req->addr, addr, addrlen);
1265
server_req->addrlen = addrlen;
1266
1267
server_req->base.flags = flags;
1268
server_req->base.nquestions = 0;
1269
server_req->base.questions = mm_calloc(sizeof(struct evdns_server_question *), questions);
1270
if (server_req->base.questions == NULL)
1271
goto err;
1272
1273
for (i = 0; i < questions; ++i) {
1274
u16 type, class;
1275
struct evdns_server_question *q;
1276
int namelen;
1277
if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)
1278
goto err;
1279
GET16(type);
1280
GET16(class);
1281
namelen = (int)strlen(tmp_name);
1282
q = mm_malloc(sizeof(struct evdns_server_question) + namelen);
1283
if (!q)
1284
goto err;
1285
q->type = type;
1286
q->dns_question_class = class;
1287
memcpy(q->name, tmp_name, namelen+1);
1288
server_req->base.questions[server_req->base.nquestions++] = q;
1289
}
1290
1291
/* Ignore answers, authority, and additional. */
1292
1293
server_req->port = port;
1294
port->refcnt++;
1295
1296
/* Only standard queries are supported. */
1297
if (flags & _OP_MASK) {
1298
evdns_server_request_respond(&(server_req->base), DNS_ERR_NOTIMPL);
1299
return -1;
1300
}
1301
1302
port->user_callback(&(server_req->base), port->user_data);
1303
1304
return 0;
1305
err:
1306
if (server_req->base.questions) {
1307
for (i = 0; i < server_req->base.nquestions; ++i)
1308
mm_free(server_req->base.questions[i]);
1309
mm_free(server_req->base.questions);
1310
}
1311
mm_free(server_req);
1312
return -1;
1313
1314
#undef SKIP_NAME
1315
#undef GET32
1316
#undef GET16
1317
#undef GET8
1318
}
1319
1320
1321
void
1322
evdns_set_transaction_id_fn(ev_uint16_t (*fn)(void))
1323
{
1324
}
1325
1326
void
1327
evdns_set_random_bytes_fn(void (*fn)(char *, size_t))
1328
{
1329
}
1330
1331
/* Try to choose a strong transaction id which isn't already in flight */
1332
static u16
1333
transaction_id_pick(struct evdns_base *base) {
1334
ASSERT_LOCKED(base);
1335
for (;;) {
1336
u16 trans_id;
1337
evutil_secure_rng_get_bytes(&trans_id, sizeof(trans_id));
1338
1339
if (trans_id == 0xffff) continue;
1340
/* now check to see if that id is already inflight */
1341
if (request_find_from_trans_id(base, trans_id) == NULL)
1342
return trans_id;
1343
}
1344
}
1345
1346
/* choose a namesever to use. This function will try to ignore */
1347
/* nameservers which we think are down and load balance across the rest */
1348
/* by updating the server_head global each time. */
1349
static struct nameserver *
1350
nameserver_pick(struct evdns_base *base) {
1351
struct nameserver *started_at = base->server_head, *picked;
1352
ASSERT_LOCKED(base);
1353
if (!base->server_head) return NULL;
1354
1355
/* if we don't have any good nameservers then there's no */
1356
/* point in trying to find one. */
1357
if (!base->global_good_nameservers) {
1358
base->server_head = base->server_head->next;
1359
return base->server_head;
1360
}
1361
1362
/* remember that nameservers are in a circular list */
1363
for (;;) {
1364
if (base->server_head->state) {
1365
/* we think this server is currently good */
1366
picked = base->server_head;
1367
base->server_head = base->server_head->next;
1368
return picked;
1369
}
1370
1371
base->server_head = base->server_head->next;
1372
if (base->server_head == started_at) {
1373
/* all the nameservers seem to be down */
1374
/* so we just return this one and hope for the */
1375
/* best */
1376
EVUTIL_ASSERT(base->global_good_nameservers == 0);
1377
picked = base->server_head;
1378
base->server_head = base->server_head->next;
1379
return picked;
1380
}
1381
}
1382
}
1383
1384
/* this is called when a namesever socket is ready for reading */
1385
static void
1386
nameserver_read(struct nameserver *ns) {
1387
struct sockaddr_storage ss;
1388
ev_socklen_t addrlen = sizeof(ss);
1389
u8 packet[1500];
1390
char addrbuf[128];
1391
ASSERT_LOCKED(ns->base);
1392
1393
for (;;) {
1394
const int r = recvfrom(ns->socket, (void*)packet,
1395
sizeof(packet), 0,
1396
(struct sockaddr*)&ss, &addrlen);
1397
if (r < 0) {
1398
int err = evutil_socket_geterror(ns->socket);
1399
if (EVUTIL_ERR_RW_RETRIABLE(err))
1400
return;
1401
nameserver_failed(ns,
1402
evutil_socket_error_to_string(err));
1403
return;
1404
}
1405
if (evutil_sockaddr_cmp((struct sockaddr*)&ss,
1406
(struct sockaddr*)&ns->address, 0)) {
1407
log(EVDNS_LOG_WARN, "Address mismatch on received "
1408
"DNS packet. Apparent source was %s",
1409
evutil_format_sockaddr_port_(
1410
(struct sockaddr *)&ss,
1411
addrbuf, sizeof(addrbuf)));
1412
return;
1413
}
1414
1415
ns->timedout = 0;
1416
reply_parse(ns->base, packet, r);
1417
}
1418
}
1419
1420
/* Read a packet from a DNS client on a server port s, parse it, and */
1421
/* act accordingly. */
1422
static void
1423
server_port_read(struct evdns_server_port *s) {
1424
u8 packet[1500];
1425
struct sockaddr_storage addr;
1426
ev_socklen_t addrlen;
1427
int r;
1428
ASSERT_LOCKED(s);
1429
1430
for (;;) {
1431
addrlen = sizeof(struct sockaddr_storage);
1432
r = recvfrom(s->socket, (void*)packet, sizeof(packet), 0,
1433
(struct sockaddr*) &addr, &addrlen);
1434
if (r < 0) {
1435
int err = evutil_socket_geterror(s->socket);
1436
if (EVUTIL_ERR_RW_RETRIABLE(err))
1437
return;
1438
log(EVDNS_LOG_WARN,
1439
"Error %s (%d) while reading request.",
1440
evutil_socket_error_to_string(err), err);
1441
return;
1442
}
1443
request_parse(packet, r, s, (struct sockaddr*) &addr, addrlen);
1444
}
1445
}
1446
1447
/* Try to write all pending replies on a given DNS server port. */
1448
static void
1449
server_port_flush(struct evdns_server_port *port)
1450
{
1451
struct server_request *req = port->pending_replies;
1452
ASSERT_LOCKED(port);
1453
while (req) {
1454
int r = sendto(port->socket, req->response, (int)req->response_len, 0,
1455
(struct sockaddr*) &req->addr, (ev_socklen_t)req->addrlen);
1456
if (r < 0) {
1457
int err = evutil_socket_geterror(port->socket);
1458
if (EVUTIL_ERR_RW_RETRIABLE(err))
1459
return;
1460
log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", evutil_socket_error_to_string(err), err);
1461
}
1462
if (server_request_free(req)) {
1463
/* we released the last reference to req->port. */
1464
return;
1465
} else {
1466
EVUTIL_ASSERT(req != port->pending_replies);
1467
req = port->pending_replies;
1468
}
1469
}
1470
1471
/* We have no more pending requests; stop listening for 'writeable' events. */
1472
(void) event_del(&port->event);
1473
event_assign(&port->event, port->event_base,
1474
port->socket, EV_READ | EV_PERSIST,
1475
server_port_ready_callback, port);
1476
1477
if (event_add(&port->event, NULL) < 0) {
1478
log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server.");
1479
/* ???? Do more? */
1480
}
1481
}
1482
1483
/* set if we are waiting for the ability to write to this server. */
1484
/* if waiting is true then we ask libevent for EV_WRITE events, otherwise */
1485
/* we stop these events. */
1486
static void
1487
nameserver_write_waiting(struct nameserver *ns, char waiting) {
1488
ASSERT_LOCKED(ns->base);
1489
if (ns->write_waiting == waiting) return;
1490
1491
ns->write_waiting = waiting;
1492
(void) event_del(&ns->event);
1493
event_assign(&ns->event, ns->base->event_base,
1494
ns->socket, EV_READ | (waiting ? EV_WRITE : 0) | EV_PERSIST,
1495
nameserver_ready_callback, ns);
1496
if (event_add(&ns->event, NULL) < 0) {
1497
char addrbuf[128];
1498
log(EVDNS_LOG_WARN, "Error from libevent when adding event for %s",
1499
evutil_format_sockaddr_port_(
1500
(struct sockaddr *)&ns->address,
1501
addrbuf, sizeof(addrbuf)));
1502
/* ???? Do more? */
1503
}
1504
}
1505
1506
/* a callback function. Called by libevent when the kernel says that */
1507
/* a nameserver socket is ready for writing or reading */
1508
static void
1509
nameserver_ready_callback(evutil_socket_t fd, short events, void *arg) {
1510
struct nameserver *ns = (struct nameserver *) arg;
1511
(void)fd;
1512
1513
EVDNS_LOCK(ns->base);
1514
if (events & EV_WRITE) {
1515
ns->choked = 0;
1516
if (!evdns_transmit(ns->base)) {
1517
nameserver_write_waiting(ns, 0);
1518
}
1519
}
1520
if (events & EV_READ) {
1521
nameserver_read(ns);
1522
}
1523
EVDNS_UNLOCK(ns->base);
1524
}
1525
1526
/* a callback function. Called by libevent when the kernel says that */
1527
/* a server socket is ready for writing or reading. */
1528
static void
1529
server_port_ready_callback(evutil_socket_t fd, short events, void *arg) {
1530
struct evdns_server_port *port = (struct evdns_server_port *) arg;
1531
(void) fd;
1532
1533
EVDNS_LOCK(port);
1534
if (events & EV_WRITE) {
1535
port->choked = 0;
1536
server_port_flush(port);
1537
}
1538
if (events & EV_READ) {
1539
server_port_read(port);
1540
}
1541
EVDNS_UNLOCK(port);
1542
}
1543
1544
/* This is an inefficient representation; only use it via the dnslabel_table_*
1545
* functions, so that is can be safely replaced with something smarter later. */
1546
#define MAX_LABELS 128
1547
/* Structures used to implement name compression */
1548
struct dnslabel_entry { char *v; off_t pos; };
1549
struct dnslabel_table {
1550
int n_labels; /* number of current entries */
1551
/* map from name to position in message */
1552
struct dnslabel_entry labels[MAX_LABELS];
1553
};
1554
1555
/* Initialize dnslabel_table. */
1556
static void
1557
dnslabel_table_init(struct dnslabel_table *table)
1558
{
1559
table->n_labels = 0;
1560
}
1561
1562
/* Free all storage held by table, but not the table itself. */
1563
static void
1564
dnslabel_clear(struct dnslabel_table *table)
1565
{
1566
int i;
1567
for (i = 0; i < table->n_labels; ++i)
1568
mm_free(table->labels[i].v);
1569
table->n_labels = 0;
1570
}
1571
1572
/* return the position of the label in the current message, or -1 if the label */
1573
/* hasn't been used yet. */
1574
static int
1575
dnslabel_table_get_pos(const struct dnslabel_table *table, const char *label)
1576
{
1577
int i;
1578
for (i = 0; i < table->n_labels; ++i) {
1579
if (!strcmp(label, table->labels[i].v))
1580
return table->labels[i].pos;
1581
}
1582
return -1;
1583
}
1584
1585
/* remember that we've used the label at position pos */
1586
static int
1587
dnslabel_table_add(struct dnslabel_table *table, const char *label, off_t pos)
1588
{
1589
char *v;
1590
int p;
1591
if (table->n_labels == MAX_LABELS)
1592
return (-1);
1593
v = mm_strdup(label);
1594
if (v == NULL)
1595
return (-1);
1596
p = table->n_labels++;
1597
table->labels[p].v = v;
1598
table->labels[p].pos = pos;
1599
1600
return (0);
1601
}
1602
1603
/* Converts a string to a length-prefixed set of DNS labels, starting */
1604
/* at buf[j]. name and buf must not overlap. name_len should be the length */
1605
/* of name. table is optional, and is used for compression. */
1606
/* */
1607
/* Input: abc.def */
1608
/* Output: <3>abc<3>def<0> */
1609
/* */
1610
/* Returns the first index after the encoded name, or negative on error. */
1611
/* -1 label was > 63 bytes */
1612
/* -2 name too long to fit in buffer. */
1613
/* */
1614
static off_t
1615
dnsname_to_labels(u8 *const buf, size_t buf_len, off_t j,
1616
const char *name, const size_t name_len,
1617
struct dnslabel_table *table) {
1618
const char *end = name + name_len;
1619
int ref = 0;
1620
u16 t_;
1621
1622
#define APPEND16(x) do { \
1623
if (j + 2 > (off_t)buf_len) \
1624
goto overflow; \
1625
t_ = htons(x); \
1626
memcpy(buf + j, &t_, 2); \
1627
j += 2; \
1628
} while (0)
1629
#define APPEND32(x) do { \
1630
if (j + 4 > (off_t)buf_len) \
1631
goto overflow; \
1632
t32_ = htonl(x); \
1633
memcpy(buf + j, &t32_, 4); \
1634
j += 4; \
1635
} while (0)
1636
1637
if (name_len > 255) return -2;
1638
1639
for (;;) {
1640
const char *const start = name;
1641
if (table && (ref = dnslabel_table_get_pos(table, name)) >= 0) {
1642
APPEND16(ref | 0xc000);
1643
return j;
1644
}
1645
name = strchr(name, '.');
1646
if (!name) {
1647
const size_t label_len = end - start;
1648
if (label_len > 63) return -1;
1649
if ((size_t)(j+label_len+1) > buf_len) return -2;
1650
if (table) dnslabel_table_add(table, start, j);
1651
buf[j++] = (ev_uint8_t)label_len;
1652
1653
memcpy(buf + j, start, label_len);
1654
j += (int) label_len;
1655
break;
1656
} else {
1657
/* append length of the label. */
1658
const size_t label_len = name - start;
1659
if (label_len > 63) return -1;
1660
if ((size_t)(j+label_len+1) > buf_len) return -2;
1661
if (table) dnslabel_table_add(table, start, j);
1662
buf[j++] = (ev_uint8_t)label_len;
1663
1664
memcpy(buf + j, start, label_len);
1665
j += (int) label_len;
1666
/* hop over the '.' */
1667
name++;
1668
}
1669
}
1670
1671
/* the labels must be terminated by a 0. */
1672
/* It's possible that the name ended in a . */
1673
/* in which case the zero is already there */
1674
if (!j || buf[j-1]) buf[j++] = 0;
1675
return j;
1676
overflow:
1677
return (-2);
1678
}
1679
1680
/* Finds the length of a dns request for a DNS name of the given */
1681
/* length. The actual request may be smaller than the value returned */
1682
/* here */
1683
static size_t
1684
evdns_request_len(const size_t name_len) {
1685
return 96 + /* length of the DNS standard header */
1686
name_len + 2 +
1687
4; /* space for the resource type */
1688
}
1689
1690
/* build a dns request packet into buf. buf should be at least as long */
1691
/* as evdns_request_len told you it should be. */
1692
/* */
1693
/* Returns the amount of space used. Negative on error. */
1694
static int
1695
evdns_request_data_build(const char *const name, const size_t name_len,
1696
const u16 trans_id, const u16 type, const u16 class,
1697
u8 *const buf, size_t buf_len) {
1698
off_t j = 0; /* current offset into buf */
1699
u16 t_; /* used by the macros */
1700
1701
APPEND16(trans_id);
1702
APPEND16(0x0100); /* standard query, recusion needed */
1703
APPEND16(1); /* one question */
1704
APPEND16(0); /* no answers */
1705
APPEND16(0); /* no authority */
1706
APPEND16(0); /* no additional */
1707
1708
j = dnsname_to_labels(buf, buf_len, j, name, name_len, NULL);
1709
if (j < 0) {
1710
return (int)j;
1711
}
1712
1713
APPEND16(type);
1714
APPEND16(class);
1715
1716
return (int)j;
1717
overflow:
1718
return (-1);
1719
}
1720
1721
/* exported function */
1722
struct evdns_server_port *
1723
evdns_add_server_port_with_base(struct event_base *base, evutil_socket_t socket, int flags, evdns_request_callback_fn_type cb, void *user_data)
1724
{
1725
struct evdns_server_port *port;
1726
if (flags)
1727
return NULL; /* flags not yet implemented */
1728
if (!(port = mm_malloc(sizeof(struct evdns_server_port))))
1729
return NULL;
1730
memset(port, 0, sizeof(struct evdns_server_port));
1731
1732
1733
port->socket = socket;
1734
port->refcnt = 1;
1735
port->choked = 0;
1736
port->closing = 0;
1737
port->user_callback = cb;
1738
port->user_data = user_data;
1739
port->pending_replies = NULL;
1740
port->event_base = base;
1741
1742
event_assign(&port->event, port->event_base,
1743
port->socket, EV_READ | EV_PERSIST,
1744
server_port_ready_callback, port);
1745
if (event_add(&port->event, NULL) < 0) {
1746
mm_free(port);
1747
return NULL;
1748
}
1749
EVTHREAD_ALLOC_LOCK(port->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
1750
return port;
1751
}
1752
1753
struct evdns_server_port *
1754
evdns_add_server_port(evutil_socket_t socket, int flags, evdns_request_callback_fn_type cb, void *user_data)
1755
{
1756
return evdns_add_server_port_with_base(NULL, socket, flags, cb, user_data);
1757
}
1758
1759
/* exported function */
1760
void
1761
evdns_close_server_port(struct evdns_server_port *port)
1762
{
1763
EVDNS_LOCK(port);
1764
if (--port->refcnt == 0) {
1765
EVDNS_UNLOCK(port);
1766
server_port_free(port);
1767
} else {
1768
port->closing = 1;
1769
EVDNS_UNLOCK(port);
1770
}
1771
}
1772
1773
/* exported function */
1774
int
1775
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)
1776
{
1777
struct server_request *req = TO_SERVER_REQUEST(req_);
1778
struct server_reply_item **itemp, *item;
1779
int *countp;
1780
int result = -1;
1781
1782
EVDNS_LOCK(req->port);
1783
if (req->response) /* have we already answered? */
1784
goto done;
1785
1786
switch (section) {
1787
case EVDNS_ANSWER_SECTION:
1788
itemp = &req->answer;
1789
countp = &req->n_answer;
1790
break;
1791
case EVDNS_AUTHORITY_SECTION:
1792
itemp = &req->authority;
1793
countp = &req->n_authority;
1794
break;
1795
case EVDNS_ADDITIONAL_SECTION:
1796
itemp = &req->additional;
1797
countp = &req->n_additional;
1798
break;
1799
default:
1800
goto done;
1801
}
1802
while (*itemp) {
1803
itemp = &((*itemp)->next);
1804
}
1805
item = mm_malloc(sizeof(struct server_reply_item));
1806
if (!item)
1807
goto done;
1808
item->next = NULL;
1809
if (!(item->name = mm_strdup(name))) {
1810
mm_free(item);
1811
goto done;
1812
}
1813
item->type = type;
1814
item->dns_question_class = class;
1815
item->ttl = ttl;
1816
item->is_name = is_name != 0;
1817
item->datalen = 0;
1818
item->data = NULL;
1819
if (data) {
1820
if (item->is_name) {
1821
if (!(item->data = mm_strdup(data))) {
1822
mm_free(item->name);
1823
mm_free(item);
1824
goto done;
1825
}
1826
item->datalen = (u16)-1;
1827
} else {
1828
if (!(item->data = mm_malloc(datalen))) {
1829
mm_free(item->name);
1830
mm_free(item);
1831
goto done;
1832
}
1833
item->datalen = datalen;
1834
memcpy(item->data, data, datalen);
1835
}
1836
}
1837
1838
*itemp = item;
1839
++(*countp);
1840
result = 0;
1841
done:
1842
EVDNS_UNLOCK(req->port);
1843
return result;
1844
}
1845
1846
/* exported function */
1847
int
1848
evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, const void *addrs, int ttl)
1849
{
1850
return evdns_server_request_add_reply(
1851
req, EVDNS_ANSWER_SECTION, name, TYPE_A, CLASS_INET,
1852
ttl, n*4, 0, addrs);
1853
}
1854
1855
/* exported function */
1856
int
1857
evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, const void *addrs, int ttl)
1858
{
1859
return evdns_server_request_add_reply(
1860
req, EVDNS_ANSWER_SECTION, name, TYPE_AAAA, CLASS_INET,
1861
ttl, n*16, 0, addrs);
1862
}
1863
1864
/* exported function */
1865
int
1866
evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl)
1867
{
1868
u32 a;
1869
char buf[32];
1870
if (in && inaddr_name)
1871
return -1;
1872
else if (!in && !inaddr_name)
1873
return -1;
1874
if (in) {
1875
a = ntohl(in->s_addr);
1876
evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
1877
(int)(u8)((a )&0xff),
1878
(int)(u8)((a>>8 )&0xff),
1879
(int)(u8)((a>>16)&0xff),
1880
(int)(u8)((a>>24)&0xff));
1881
inaddr_name = buf;
1882
}
1883
return evdns_server_request_add_reply(
1884
req, EVDNS_ANSWER_SECTION, inaddr_name, TYPE_PTR, CLASS_INET,
1885
ttl, -1, 1, hostname);
1886
}
1887
1888
/* exported function */
1889
int
1890
evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl)
1891
{
1892
return evdns_server_request_add_reply(
1893
req, EVDNS_ANSWER_SECTION, name, TYPE_CNAME, CLASS_INET,
1894
ttl, -1, 1, cname);
1895
}
1896
1897
/* exported function */
1898
void
1899
evdns_server_request_set_flags(struct evdns_server_request *exreq, int flags)
1900
{
1901
struct server_request *req = TO_SERVER_REQUEST(exreq);
1902
req->base.flags &= ~(EVDNS_FLAGS_AA|EVDNS_FLAGS_RD);
1903
req->base.flags |= flags;
1904
}
1905
1906
static int
1907
evdns_server_request_format_response(struct server_request *req, int err)
1908
{
1909
unsigned char buf[1500];
1910
size_t buf_len = sizeof(buf);
1911
off_t j = 0, r;
1912
u16 t_;
1913
u32 t32_;
1914
int i;
1915
u16 flags;
1916
struct dnslabel_table table;
1917
1918
if (err < 0 || err > 15) return -1;
1919
1920
/* Set response bit and error code; copy OPCODE and RD fields from
1921
* question; copy RA and AA if set by caller. */
1922
flags = req->base.flags;
1923
flags |= (_QR_MASK | err);
1924
1925
dnslabel_table_init(&table);
1926
APPEND16(req->trans_id);
1927
APPEND16(flags);
1928
APPEND16(req->base.nquestions);
1929
APPEND16(req->n_answer);
1930
APPEND16(req->n_authority);
1931
APPEND16(req->n_additional);
1932
1933
/* Add questions. */
1934
for (i=0; i < req->base.nquestions; ++i) {
1935
const char *s = req->base.questions[i]->name;
1936
j = dnsname_to_labels(buf, buf_len, j, s, strlen(s), &table);
1937
if (j < 0) {
1938
dnslabel_clear(&table);
1939
return (int) j;
1940
}
1941
APPEND16(req->base.questions[i]->type);
1942
APPEND16(req->base.questions[i]->dns_question_class);
1943
}
1944
1945
/* Add answer, authority, and additional sections. */
1946
for (i=0; i<3; ++i) {
1947
struct server_reply_item *item;
1948
if (i==0)
1949
item = req->answer;
1950
else if (i==1)
1951
item = req->authority;
1952
else
1953
item = req->additional;
1954
while (item) {
1955
r = dnsname_to_labels(buf, buf_len, j, item->name, strlen(item->name), &table);
1956
if (r < 0)
1957
goto overflow;
1958
j = r;
1959
1960
APPEND16(item->type);
1961
APPEND16(item->dns_question_class);
1962
APPEND32(item->ttl);
1963
if (item->is_name) {
1964
off_t len_idx = j, name_start;
1965
j += 2;
1966
name_start = j;
1967
r = dnsname_to_labels(buf, buf_len, j, item->data, strlen(item->data), &table);
1968
if (r < 0)
1969
goto overflow;
1970
j = r;
1971
t_ = htons( (short) (j-name_start) );
1972
memcpy(buf+len_idx, &t_, 2);
1973
} else {
1974
APPEND16(item->datalen);
1975
if (j+item->datalen > (off_t)buf_len)
1976
goto overflow;
1977
memcpy(buf+j, item->data, item->datalen);
1978
j += item->datalen;
1979
}
1980
item = item->next;
1981
}
1982
}
1983
1984
if (j > 512) {
1985
overflow:
1986
j = 512;
1987
buf[2] |= 0x02; /* set the truncated bit. */
1988
}
1989
1990
req->response_len = j;
1991
1992
if (!(req->response = mm_malloc(req->response_len))) {
1993
server_request_free_answers(req);
1994
dnslabel_clear(&table);
1995
return (-1);
1996
}
1997
memcpy(req->response, buf, req->response_len);
1998
server_request_free_answers(req);
1999
dnslabel_clear(&table);
2000
return (0);
2001
}
2002
2003
/* exported function */
2004
int
2005
evdns_server_request_respond(struct evdns_server_request *req_, int err)
2006
{
2007
struct server_request *req = TO_SERVER_REQUEST(req_);
2008
struct evdns_server_port *port = req->port;
2009
int r = -1;
2010
2011
EVDNS_LOCK(port);
2012
if (!req->response) {
2013
if ((r = evdns_server_request_format_response(req, err))<0)
2014
goto done;
2015
}
2016
2017
r = sendto(port->socket, req->response, (int)req->response_len, 0,
2018
(struct sockaddr*) &req->addr, (ev_socklen_t)req->addrlen);
2019
if (r<0) {
2020
int sock_err = evutil_socket_geterror(port->socket);
2021
if (EVUTIL_ERR_RW_RETRIABLE(sock_err))
2022
goto done;
2023
2024
if (port->pending_replies) {
2025
req->prev_pending = port->pending_replies->prev_pending;
2026
req->next_pending = port->pending_replies;
2027
req->prev_pending->next_pending =
2028
req->next_pending->prev_pending = req;
2029
} else {
2030
req->prev_pending = req->next_pending = req;
2031
port->pending_replies = req;
2032
port->choked = 1;
2033
2034
(void) event_del(&port->event);
2035
event_assign(&port->event, port->event_base, port->socket, (port->closing?0:EV_READ) | EV_WRITE | EV_PERSIST, server_port_ready_callback, port);
2036
2037
if (event_add(&port->event, NULL) < 0) {
2038
log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server");
2039
}
2040
2041
}
2042
2043
r = 1;
2044
goto done;
2045
}
2046
if (server_request_free(req)) {
2047
r = 0;
2048
goto done;
2049
}
2050
2051
if (port->pending_replies)
2052
server_port_flush(port);
2053
2054
r = 0;
2055
done:
2056
EVDNS_UNLOCK(port);
2057
return r;
2058
}
2059
2060
/* Free all storage held by RRs in req. */
2061
static void
2062
server_request_free_answers(struct server_request *req)
2063
{
2064
struct server_reply_item *victim, *next, **list;
2065
int i;
2066
for (i = 0; i < 3; ++i) {
2067
if (i==0)
2068
list = &req->answer;
2069
else if (i==1)
2070
list = &req->authority;
2071
else
2072
list = &req->additional;
2073
2074
victim = *list;
2075
while (victim) {
2076
next = victim->next;
2077
mm_free(victim->name);
2078
if (victim->data)
2079
mm_free(victim->data);
2080
mm_free(victim);
2081
victim = next;
2082
}
2083
*list = NULL;
2084
}
2085
}
2086
2087
/* Free all storage held by req, and remove links to it. */
2088
/* return true iff we just wound up freeing the server_port. */
2089
static int
2090
server_request_free(struct server_request *req)
2091
{
2092
int i, rc=1, lock=0;
2093
if (req->base.questions) {
2094
for (i = 0; i < req->base.nquestions; ++i)
2095
mm_free(req->base.questions[i]);
2096
mm_free(req->base.questions);
2097
}
2098
2099
if (req->port) {
2100
EVDNS_LOCK(req->port);
2101
lock=1;
2102
if (req->port->pending_replies == req) {
2103
if (req->next_pending && req->next_pending != req)
2104
req->port->pending_replies = req->next_pending;
2105
else
2106
req->port->pending_replies = NULL;
2107
}
2108
rc = --req->port->refcnt;
2109
}
2110
2111
if (req->response) {
2112
mm_free(req->response);
2113
}
2114
2115
server_request_free_answers(req);
2116
2117
if (req->next_pending && req->next_pending != req) {
2118
req->next_pending->prev_pending = req->prev_pending;
2119
req->prev_pending->next_pending = req->next_pending;
2120
}
2121
2122
if (rc == 0) {
2123
EVDNS_UNLOCK(req->port); /* ????? nickm */
2124
server_port_free(req->port);
2125
mm_free(req);
2126
return (1);
2127
}
2128
if (lock)
2129
EVDNS_UNLOCK(req->port);
2130
mm_free(req);
2131
return (0);
2132
}
2133
2134
/* Free all storage held by an evdns_server_port. Only called when */
2135
static void
2136
server_port_free(struct evdns_server_port *port)
2137
{
2138
EVUTIL_ASSERT(port);
2139
EVUTIL_ASSERT(!port->refcnt);
2140
EVUTIL_ASSERT(!port->pending_replies);
2141
if (port->socket > 0) {
2142
evutil_closesocket(port->socket);
2143
port->socket = -1;
2144
}
2145
(void) event_del(&port->event);
2146
event_debug_unassign(&port->event);
2147
EVTHREAD_FREE_LOCK(port->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
2148
mm_free(port);
2149
}
2150
2151
/* exported function */
2152
int
2153
evdns_server_request_drop(struct evdns_server_request *req_)
2154
{
2155
struct server_request *req = TO_SERVER_REQUEST(req_);
2156
server_request_free(req);
2157
return 0;
2158
}
2159
2160
/* exported function */
2161
int
2162
evdns_server_request_get_requesting_addr(struct evdns_server_request *req_, struct sockaddr *sa, int addr_len)
2163
{
2164
struct server_request *req = TO_SERVER_REQUEST(req_);
2165
if (addr_len < (int)req->addrlen)
2166
return -1;
2167
memcpy(sa, &(req->addr), req->addrlen);
2168
return req->addrlen;
2169
}
2170
2171
#undef APPEND16
2172
#undef APPEND32
2173
2174
/* this is a libevent callback function which is called when a request */
2175
/* has timed out. */
2176
static void
2177
evdns_request_timeout_callback(evutil_socket_t fd, short events, void *arg) {
2178
struct request *const req = (struct request *) arg;
2179
struct evdns_base *base = req->base;
2180
2181
(void) fd;
2182
(void) events;
2183
2184
log(EVDNS_LOG_DEBUG, "Request %p timed out", arg);
2185
EVDNS_LOCK(base);
2186
2187
if (req->tx_count >= req->base->global_max_retransmits) {
2188
struct nameserver *ns = req->ns;
2189
/* this request has failed */
2190
log(EVDNS_LOG_DEBUG, "Giving up on request %p; tx_count==%d",
2191
arg, req->tx_count);
2192
reply_schedule_callback(req, 0, DNS_ERR_TIMEOUT, NULL);
2193
2194
request_finished(req, &REQ_HEAD(req->base, req->trans_id), 1);
2195
nameserver_failed(ns, "request timed out.");
2196
} else {
2197
/* retransmit it */
2198
log(EVDNS_LOG_DEBUG, "Retransmitting request %p; tx_count==%d",
2199
arg, req->tx_count);
2200
(void) evtimer_del(&req->timeout_event);
2201
request_swap_ns(req, nameserver_pick(base));
2202
evdns_request_transmit(req);
2203
2204
req->ns->timedout++;
2205
if (req->ns->timedout > req->base->global_max_nameserver_timeout) {
2206
req->ns->timedout = 0;
2207
nameserver_failed(req->ns, "request timed out.");
2208
}
2209
}
2210
2211
EVDNS_UNLOCK(base);
2212
}
2213
2214
/* try to send a request to a given server. */
2215
/* */
2216
/* return: */
2217
/* 0 ok */
2218
/* 1 temporary failure */
2219
/* 2 other failure */
2220
static int
2221
evdns_request_transmit_to(struct request *req, struct nameserver *server) {
2222
int r;
2223
ASSERT_LOCKED(req->base);
2224
ASSERT_VALID_REQUEST(req);
2225
2226
if (server->requests_inflight == 1 &&
2227
req->base->disable_when_inactive &&
2228
event_add(&server->event, NULL) < 0) {
2229
return 1;
2230
}
2231
2232
r = sendto(server->socket, (void*)req->request, req->request_len, 0,
2233
(struct sockaddr *)&server->address, server->addrlen);
2234
if (r < 0) {
2235
int err = evutil_socket_geterror(server->socket);
2236
if (EVUTIL_ERR_RW_RETRIABLE(err))
2237
return 1;
2238
nameserver_failed(req->ns, evutil_socket_error_to_string(err));
2239
return 2;
2240
} else if (r != (int)req->request_len) {
2241
return 1; /* short write */
2242
} else {
2243
return 0;
2244
}
2245
}
2246
2247
/* try to send a request, updating the fields of the request */
2248
/* as needed */
2249
/* */
2250
/* return: */
2251
/* 0 ok */
2252
/* 1 failed */
2253
static int
2254
evdns_request_transmit(struct request *req) {
2255
int retcode = 0, r;
2256
2257
ASSERT_LOCKED(req->base);
2258
ASSERT_VALID_REQUEST(req);
2259
/* if we fail to send this packet then this flag marks it */
2260
/* for evdns_transmit */
2261
req->transmit_me = 1;
2262
EVUTIL_ASSERT(req->trans_id != 0xffff);
2263
2264
if (!req->ns)
2265
{
2266
/* unable to transmit request if no nameservers */
2267
return 1;
2268
}
2269
2270
if (req->ns->choked) {
2271
/* don't bother trying to write to a socket */
2272
/* which we have had EAGAIN from */
2273
return 1;
2274
}
2275
2276
r = evdns_request_transmit_to(req, req->ns);
2277
switch (r) {
2278
case 1:
2279
/* temp failure */
2280
req->ns->choked = 1;
2281
nameserver_write_waiting(req->ns, 1);
2282
return 1;
2283
case 2:
2284
/* failed to transmit the request entirely. we can fallthrough since
2285
* we'll set a timeout, which will time out, and make us retransmit the
2286
* request anyway. */
2287
retcode = 1;
2288
EVUTIL_FALLTHROUGH;
2289
default:
2290
/* all ok */
2291
log(EVDNS_LOG_DEBUG,
2292
"Setting timeout for request %p, sent to nameserver %p", req, req->ns);
2293
if (evtimer_add(&req->timeout_event, &req->base->global_timeout) < 0) {
2294
log(EVDNS_LOG_WARN,
2295
"Error from libevent when adding timer for request %p",
2296
req);
2297
/* ???? Do more? */
2298
}
2299
req->tx_count++;
2300
req->transmit_me = 0;
2301
return retcode;
2302
}
2303
}
2304
2305
static void
2306
nameserver_probe_callback(int result, char type, int count, int ttl, void *addresses, void *arg) {
2307
struct nameserver *const ns = (struct nameserver *) arg;
2308
(void) type;
2309
(void) count;
2310
(void) ttl;
2311
(void) addresses;
2312
2313
if (result == DNS_ERR_CANCEL) {
2314
/* We canceled this request because the nameserver came up
2315
* for some other reason. Do not change our opinion about
2316
* the nameserver. */
2317
return;
2318
}
2319
2320
EVDNS_LOCK(ns->base);
2321
ns->probe_request = NULL;
2322
if (result == DNS_ERR_NONE || result == DNS_ERR_NOTEXIST) {
2323
/* this is a good reply */
2324
nameserver_up(ns);
2325
} else {
2326
nameserver_probe_failed(ns);
2327
}
2328
EVDNS_UNLOCK(ns->base);
2329
}
2330
2331
static void
2332
nameserver_send_probe(struct nameserver *const ns) {
2333
struct evdns_request *handle;
2334
struct request *req;
2335
char addrbuf[128];
2336
/* here we need to send a probe to a given nameserver */
2337
/* in the hope that it is up now. */
2338
2339
ASSERT_LOCKED(ns->base);
2340
log(EVDNS_LOG_DEBUG, "Sending probe to %s",
2341
evutil_format_sockaddr_port_(
2342
(struct sockaddr *)&ns->address,
2343
addrbuf, sizeof(addrbuf)));
2344
handle = mm_calloc(1, sizeof(*handle));
2345
if (!handle) return;
2346
req = request_new(ns->base, handle, TYPE_A, "google.com", DNS_QUERY_NO_SEARCH, nameserver_probe_callback, ns);
2347
if (!req) {
2348
mm_free(handle);
2349
return;
2350
}
2351
ns->probe_request = handle;
2352
/* we force this into the inflight queue no matter what */
2353
request_trans_id_set(req, transaction_id_pick(ns->base));
2354
req->ns = ns;
2355
request_submit(req);
2356
}
2357
2358
/* returns: */
2359
/* 0 didn't try to transmit anything */
2360
/* 1 tried to transmit something */
2361
static int
2362
evdns_transmit(struct evdns_base *base) {
2363
char did_try_to_transmit = 0;
2364
int i;
2365
2366
ASSERT_LOCKED(base);
2367
for (i = 0; i < base->n_req_heads; ++i) {
2368
if (base->req_heads[i]) {
2369
struct request *const started_at = base->req_heads[i], *req = started_at;
2370
/* first transmit all the requests which are currently waiting */
2371
do {
2372
if (req->transmit_me) {
2373
did_try_to_transmit = 1;
2374
evdns_request_transmit(req);
2375
}
2376
2377
req = req->next;
2378
} while (req != started_at);
2379
}
2380
}
2381
2382
return did_try_to_transmit;
2383
}
2384
2385
/* exported function */
2386
int
2387
evdns_base_count_nameservers(struct evdns_base *base)
2388
{
2389
const struct nameserver *server;
2390
int n = 0;
2391
2392
EVDNS_LOCK(base);
2393
server = base->server_head;
2394
if (!server)
2395
goto done;
2396
do {
2397
++n;
2398
server = server->next;
2399
} while (server != base->server_head);
2400
done:
2401
EVDNS_UNLOCK(base);
2402
return n;
2403
}
2404
2405
int
2406
evdns_count_nameservers(void)
2407
{
2408
return evdns_base_count_nameservers(current_base);
2409
}
2410
2411
/* exported function */
2412
int
2413
evdns_base_clear_nameservers_and_suspend(struct evdns_base *base)
2414
{
2415
struct nameserver *server, *started_at;
2416
int i;
2417
2418
EVDNS_LOCK(base);
2419
server = base->server_head;
2420
started_at = base->server_head;
2421
if (!server) {
2422
EVDNS_UNLOCK(base);
2423
return 0;
2424
}
2425
while (1) {
2426
struct nameserver *next = server->next;
2427
(void) event_del(&server->event);
2428
if (evtimer_initialized(&server->timeout_event))
2429
(void) evtimer_del(&server->timeout_event);
2430
if (server->probe_request) {
2431
evdns_cancel_request(server->base, server->probe_request);
2432
server->probe_request = NULL;
2433
}
2434
if (server->socket >= 0)
2435
evutil_closesocket(server->socket);
2436
mm_free(server);
2437
if (next == started_at)
2438
break;
2439
server = next;
2440
}
2441
base->server_head = NULL;
2442
base->global_good_nameservers = 0;
2443
2444
for (i = 0; i < base->n_req_heads; ++i) {
2445
struct request *req, *req_started_at;
2446
req = req_started_at = base->req_heads[i];
2447
while (req) {
2448
struct request *next = req->next;
2449
req->tx_count = req->reissue_count = 0;
2450
req->ns = NULL;
2451
/* ???? What to do about searches? */
2452
(void) evtimer_del(&req->timeout_event);
2453
req->trans_id = 0;
2454
req->transmit_me = 0;
2455
2456
base->global_requests_waiting++;
2457
evdns_request_insert(req, &base->req_waiting_head);
2458
/* We want to insert these suspended elements at the front of
2459
* the waiting queue, since they were pending before any of
2460
* the waiting entries were added. This is a circular list,
2461
* so we can just shift the start back by one.*/
2462
base->req_waiting_head = base->req_waiting_head->prev;
2463
2464
if (next == req_started_at)
2465
break;
2466
req = next;
2467
}
2468
base->req_heads[i] = NULL;
2469
}
2470
2471
base->global_requests_inflight = 0;
2472
2473
EVDNS_UNLOCK(base);
2474
return 0;
2475
}
2476
2477
int
2478
evdns_clear_nameservers_and_suspend(void)
2479
{
2480
return evdns_base_clear_nameservers_and_suspend(current_base);
2481
}
2482
2483
2484
/* exported function */
2485
int
2486
evdns_base_resume(struct evdns_base *base)
2487
{
2488
EVDNS_LOCK(base);
2489
evdns_requests_pump_waiting_queue(base);
2490
EVDNS_UNLOCK(base);
2491
2492
return 0;
2493
}
2494
2495
int
2496
evdns_resume(void)
2497
{
2498
return evdns_base_resume(current_base);
2499
}
2500
2501
static int
2502
evdns_nameserver_add_impl_(struct evdns_base *base, const struct sockaddr *address, int addrlen) {
2503
/* first check to see if we already have this nameserver */
2504
2505
const struct nameserver *server = base->server_head, *const started_at = base->server_head;
2506
struct nameserver *ns;
2507
int err = 0;
2508
char addrbuf[128];
2509
2510
ASSERT_LOCKED(base);
2511
if (server) {
2512
do {
2513
if (!evutil_sockaddr_cmp((struct sockaddr*)&server->address, address, 1)) return 3;
2514
server = server->next;
2515
} while (server != started_at);
2516
}
2517
if (addrlen > (int)sizeof(ns->address)) {
2518
log(EVDNS_LOG_DEBUG, "Addrlen %d too long.", (int)addrlen);
2519
return 2;
2520
}
2521
2522
ns = (struct nameserver *) mm_malloc(sizeof(struct nameserver));
2523
if (!ns) return -1;
2524
2525
memset(ns, 0, sizeof(struct nameserver));
2526
ns->base = base;
2527
2528
evtimer_assign(&ns->timeout_event, ns->base->event_base, nameserver_prod_callback, ns);
2529
2530
ns->socket = evutil_socket_(address->sa_family,
2531
SOCK_DGRAM|EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC, 0);
2532
if (ns->socket < 0) { err = 1; goto out1; }
2533
2534
if (base->global_outgoing_addrlen &&
2535
!evutil_sockaddr_is_loopback_(address)) {
2536
if (bind(ns->socket,
2537
(struct sockaddr*)&base->global_outgoing_address,
2538
base->global_outgoing_addrlen) < 0) {
2539
log(EVDNS_LOG_WARN,"Couldn't bind to outgoing address");
2540
err = 2;
2541
goto out2;
2542
}
2543
}
2544
2545
if (base->so_rcvbuf) {
2546
if (setsockopt(ns->socket, SOL_SOCKET, SO_RCVBUF,
2547
(void *)&base->so_rcvbuf, sizeof(base->so_rcvbuf))) {
2548
log(EVDNS_LOG_WARN, "Couldn't set SO_RCVBUF to %i", base->so_rcvbuf);
2549
err = -SO_RCVBUF;
2550
goto out2;
2551
}
2552
}
2553
if (base->so_sndbuf) {
2554
if (setsockopt(ns->socket, SOL_SOCKET, SO_SNDBUF,
2555
(void *)&base->so_sndbuf, sizeof(base->so_sndbuf))) {
2556
log(EVDNS_LOG_WARN, "Couldn't set SO_SNDBUF to %i", base->so_sndbuf);
2557
err = -SO_SNDBUF;
2558
goto out2;
2559
}
2560
}
2561
2562
memcpy(&ns->address, address, addrlen);
2563
ns->addrlen = addrlen;
2564
ns->state = 1;
2565
event_assign(&ns->event, ns->base->event_base, ns->socket,
2566
EV_READ | EV_PERSIST, nameserver_ready_callback, ns);
2567
if (!base->disable_when_inactive && event_add(&ns->event, NULL) < 0) {
2568
err = 2;
2569
goto out2;
2570
}
2571
2572
log(EVDNS_LOG_DEBUG, "Added nameserver %s as %p",
2573
evutil_format_sockaddr_port_(address, addrbuf, sizeof(addrbuf)), ns);
2574
2575
/* insert this nameserver into the list of them */
2576
if (!base->server_head) {
2577
ns->next = ns->prev = ns;
2578
base->server_head = ns;
2579
} else {
2580
ns->next = base->server_head->next;
2581
ns->prev = base->server_head;
2582
base->server_head->next = ns;
2583
ns->next->prev = ns;
2584
}
2585
2586
base->global_good_nameservers++;
2587
2588
return 0;
2589
2590
out2:
2591
evutil_closesocket(ns->socket);
2592
out1:
2593
event_debug_unassign(&ns->event);
2594
mm_free(ns);
2595
log(EVDNS_LOG_WARN, "Unable to add nameserver %s: error %d",
2596
evutil_format_sockaddr_port_(address, addrbuf, sizeof(addrbuf)), err);
2597
return err;
2598
}
2599
2600
/* exported function */
2601
int
2602
evdns_base_nameserver_add(struct evdns_base *base, unsigned long int address)
2603
{
2604
struct sockaddr_in sin;
2605
int res;
2606
memset(&sin, 0, sizeof(sin));
2607
sin.sin_addr.s_addr = address;
2608
sin.sin_port = htons(53);
2609
sin.sin_family = AF_INET;
2610
EVDNS_LOCK(base);
2611
res = evdns_nameserver_add_impl_(base, (struct sockaddr*)&sin, sizeof(sin));
2612
EVDNS_UNLOCK(base);
2613
return res;
2614
}
2615
2616
int
2617
evdns_nameserver_add(unsigned long int address) {
2618
if (!current_base)
2619
current_base = evdns_base_new(NULL, 0);
2620
return evdns_base_nameserver_add(current_base, address);
2621
}
2622
2623
static void
2624
sockaddr_setport(struct sockaddr *sa, ev_uint16_t port)
2625
{
2626
if (sa->sa_family == AF_INET) {
2627
((struct sockaddr_in *)sa)->sin_port = htons(port);
2628
} else if (sa->sa_family == AF_INET6) {
2629
((struct sockaddr_in6 *)sa)->sin6_port = htons(port);
2630
}
2631
}
2632
2633
static ev_uint16_t
2634
sockaddr_getport(struct sockaddr *sa)
2635
{
2636
if (sa->sa_family == AF_INET) {
2637
return ntohs(((struct sockaddr_in *)sa)->sin_port);
2638
} else if (sa->sa_family == AF_INET6) {
2639
return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
2640
} else {
2641
return 0;
2642
}
2643
}
2644
2645
/* exported function */
2646
int
2647
evdns_base_nameserver_ip_add(struct evdns_base *base, const char *ip_as_string) {
2648
struct sockaddr_storage ss;
2649
struct sockaddr *sa;
2650
int len = sizeof(ss);
2651
int res;
2652
if (evutil_parse_sockaddr_port(ip_as_string, (struct sockaddr *)&ss,
2653
&len)) {
2654
log(EVDNS_LOG_WARN, "Unable to parse nameserver address %s",
2655
ip_as_string);
2656
return 4;
2657
}
2658
sa = (struct sockaddr *) &ss;
2659
if (sockaddr_getport(sa) == 0)
2660
sockaddr_setport(sa, 53);
2661
2662
EVDNS_LOCK(base);
2663
res = evdns_nameserver_add_impl_(base, sa, len);
2664
EVDNS_UNLOCK(base);
2665
return res;
2666
}
2667
2668
int
2669
evdns_nameserver_ip_add(const char *ip_as_string) {
2670
if (!current_base)
2671
current_base = evdns_base_new(NULL, 0);
2672
return evdns_base_nameserver_ip_add(current_base, ip_as_string);
2673
}
2674
2675
int
2676
evdns_base_nameserver_sockaddr_add(struct evdns_base *base,
2677
const struct sockaddr *sa, ev_socklen_t len, unsigned flags)
2678
{
2679
int res;
2680
EVUTIL_ASSERT(base);
2681
EVDNS_LOCK(base);
2682
res = evdns_nameserver_add_impl_(base, sa, len);
2683
EVDNS_UNLOCK(base);
2684
return res;
2685
}
2686
2687
int
2688
evdns_base_get_nameserver_addr(struct evdns_base *base, int idx,
2689
struct sockaddr *sa, ev_socklen_t len)
2690
{
2691
int result = -1;
2692
int i;
2693
struct nameserver *server;
2694
EVDNS_LOCK(base);
2695
server = base->server_head;
2696
for (i = 0; i < idx && server; ++i, server = server->next) {
2697
if (server->next == base->server_head)
2698
goto done;
2699
}
2700
if (! server)
2701
goto done;
2702
2703
if (server->addrlen > len) {
2704
result = (int) server->addrlen;
2705
goto done;
2706
}
2707
2708
memcpy(sa, &server->address, server->addrlen);
2709
result = (int) server->addrlen;
2710
done:
2711
EVDNS_UNLOCK(base);
2712
return result;
2713
}
2714
2715
/* remove from the queue */
2716
static void
2717
evdns_request_remove(struct request *req, struct request **head)
2718
{
2719
ASSERT_LOCKED(req->base);
2720
ASSERT_VALID_REQUEST(req);
2721
2722
#if 0
2723
{
2724
struct request *ptr;
2725
int found = 0;
2726
EVUTIL_ASSERT(*head != NULL);
2727
2728
ptr = *head;
2729
do {
2730
if (ptr == req) {
2731
found = 1;
2732
break;
2733
}
2734
ptr = ptr->next;
2735
} while (ptr != *head);
2736
EVUTIL_ASSERT(found);
2737
2738
EVUTIL_ASSERT(req->next);
2739
}
2740
#endif
2741
2742
if (req->next == req) {
2743
/* only item in the list */
2744
*head = NULL;
2745
} else {
2746
req->next->prev = req->prev;
2747
req->prev->next = req->next;
2748
if (*head == req) *head = req->next;
2749
}
2750
req->next = req->prev = NULL;
2751
}
2752
2753
/* insert into the tail of the queue */
2754
static void
2755
evdns_request_insert(struct request *req, struct request **head) {
2756
ASSERT_LOCKED(req->base);
2757
ASSERT_VALID_REQUEST(req);
2758
if (!*head) {
2759
*head = req;
2760
req->next = req->prev = req;
2761
return;
2762
}
2763
2764
req->prev = (*head)->prev;
2765
req->prev->next = req;
2766
req->next = *head;
2767
(*head)->prev = req;
2768
}
2769
2770
static int
2771
string_num_dots(const char *s) {
2772
int count = 0;
2773
while ((s = strchr(s, '.'))) {
2774
s++;
2775
count++;
2776
}
2777
return count;
2778
}
2779
2780
static struct request *
2781
request_new(struct evdns_base *base, struct evdns_request *handle, int type,
2782
const char *name, int flags, evdns_callback_type callback,
2783
void *user_ptr) {
2784
2785
const char issuing_now =
2786
(base->global_requests_inflight < base->global_max_requests_inflight) ? 1 : 0;
2787
2788
const size_t name_len = strlen(name);
2789
const size_t request_max_len = evdns_request_len(name_len);
2790
const u16 trans_id = issuing_now ? transaction_id_pick(base) : 0xffff;
2791
/* the request data is alloced in a single block with the header */
2792
struct request *const req =
2793
mm_malloc(sizeof(struct request) + request_max_len);
2794
int rlen;
2795
char namebuf[256];
2796
(void) flags;
2797
2798
ASSERT_LOCKED(base);
2799
2800
if (!req) return NULL;
2801
2802
if (name_len >= sizeof(namebuf)) {
2803
mm_free(req);
2804
return NULL;
2805
}
2806
2807
memset(req, 0, sizeof(struct request));
2808
req->base = base;
2809
2810
evtimer_assign(&req->timeout_event, req->base->event_base, evdns_request_timeout_callback, req);
2811
2812
if (base->global_randomize_case) {
2813
unsigned i;
2814
char randbits[(sizeof(namebuf)+7)/8];
2815
strlcpy(namebuf, name, sizeof(namebuf));
2816
evutil_secure_rng_get_bytes(randbits, (name_len+7)/8);
2817
for (i = 0; i < name_len; ++i) {
2818
if (EVUTIL_ISALPHA_(namebuf[i])) {
2819
if ((randbits[i >> 3] & (1<<(i & 7))))
2820
namebuf[i] |= 0x20;
2821
else
2822
namebuf[i] &= ~0x20;
2823
}
2824
}
2825
name = namebuf;
2826
}
2827
2828
/* request data lives just after the header */
2829
req->request = ((u8 *) req) + sizeof(struct request);
2830
/* denotes that the request data shouldn't be free()ed */
2831
req->request_appended = 1;
2832
rlen = evdns_request_data_build(name, name_len, trans_id,
2833
type, CLASS_INET, req->request, request_max_len);
2834
if (rlen < 0)
2835
goto err1;
2836
2837
req->request_len = rlen;
2838
req->trans_id = trans_id;
2839
req->tx_count = 0;
2840
req->request_type = type;
2841
req->user_pointer = user_ptr;
2842
req->user_callback = callback;
2843
req->ns = issuing_now ? nameserver_pick(base) : NULL;
2844
req->next = req->prev = NULL;
2845
req->handle = handle;
2846
if (handle) {
2847
handle->current_req = req;
2848
handle->base = base;
2849
}
2850
2851
return req;
2852
err1:
2853
mm_free(req);
2854
return NULL;
2855
}
2856
2857
static void
2858
request_submit(struct request *const req) {
2859
struct evdns_base *base = req->base;
2860
ASSERT_LOCKED(base);
2861
ASSERT_VALID_REQUEST(req);
2862
if (req->ns) {
2863
/* if it has a nameserver assigned then this is going */
2864
/* straight into the inflight queue */
2865
evdns_request_insert(req, &REQ_HEAD(base, req->trans_id));
2866
2867
base->global_requests_inflight++;
2868
req->ns->requests_inflight++;
2869
2870
evdns_request_transmit(req);
2871
} else {
2872
evdns_request_insert(req, &base->req_waiting_head);
2873
base->global_requests_waiting++;
2874
}
2875
}
2876
2877
/* exported function */
2878
void
2879
evdns_cancel_request(struct evdns_base *base, struct evdns_request *handle)
2880
{
2881
struct request *req;
2882
2883
if (!handle->current_req)
2884
return;
2885
2886
if (!base) {
2887
/* This redundancy is silly; can we fix it? (Not for 2.0) XXXX */
2888
base = handle->base;
2889
if (!base)
2890
base = handle->current_req->base;
2891
}
2892
2893
EVDNS_LOCK(base);
2894
if (handle->pending_cb) {
2895
EVDNS_UNLOCK(base);
2896
return;
2897
}
2898
2899
req = handle->current_req;
2900
ASSERT_VALID_REQUEST(req);
2901
2902
reply_schedule_callback(req, 0, DNS_ERR_CANCEL, NULL);
2903
if (req->ns) {
2904
/* remove from inflight queue */
2905
request_finished(req, &REQ_HEAD(base, req->trans_id), 1);
2906
} else {
2907
/* remove from global_waiting head */
2908
request_finished(req, &base->req_waiting_head, 1);
2909
}
2910
EVDNS_UNLOCK(base);
2911
}
2912
2913
/* exported function */
2914
struct evdns_request *
2915
evdns_base_resolve_ipv4(struct evdns_base *base, const char *name, int flags,
2916
evdns_callback_type callback, void *ptr) {
2917
struct evdns_request *handle;
2918
struct request *req;
2919
log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
2920
handle = mm_calloc(1, sizeof(*handle));
2921
if (handle == NULL)
2922
return NULL;
2923
EVDNS_LOCK(base);
2924
if (flags & DNS_QUERY_NO_SEARCH) {
2925
req =
2926
request_new(base, handle, TYPE_A, name, flags,
2927
callback, ptr);
2928
if (req)
2929
request_submit(req);
2930
} else {
2931
search_request_new(base, handle, TYPE_A, name, flags,
2932
callback, ptr);
2933
}
2934
if (handle->current_req == NULL) {
2935
mm_free(handle);
2936
handle = NULL;
2937
}
2938
EVDNS_UNLOCK(base);
2939
return handle;
2940
}
2941
2942
int evdns_resolve_ipv4(const char *name, int flags,
2943
evdns_callback_type callback, void *ptr)
2944
{
2945
return evdns_base_resolve_ipv4(current_base, name, flags, callback, ptr)
2946
? 0 : -1;
2947
}
2948
2949
2950
/* exported function */
2951
struct evdns_request *
2952
evdns_base_resolve_ipv6(struct evdns_base *base,
2953
const char *name, int flags,
2954
evdns_callback_type callback, void *ptr)
2955
{
2956
struct evdns_request *handle;
2957
struct request *req;
2958
log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
2959
handle = mm_calloc(1, sizeof(*handle));
2960
if (handle == NULL)
2961
return NULL;
2962
EVDNS_LOCK(base);
2963
if (flags & DNS_QUERY_NO_SEARCH) {
2964
req = request_new(base, handle, TYPE_AAAA, name, flags,
2965
callback, ptr);
2966
if (req)
2967
request_submit(req);
2968
} else {
2969
search_request_new(base, handle, TYPE_AAAA, name, flags,
2970
callback, ptr);
2971
}
2972
if (handle->current_req == NULL) {
2973
mm_free(handle);
2974
handle = NULL;
2975
}
2976
EVDNS_UNLOCK(base);
2977
return handle;
2978
}
2979
2980
int evdns_resolve_ipv6(const char *name, int flags,
2981
evdns_callback_type callback, void *ptr) {
2982
return evdns_base_resolve_ipv6(current_base, name, flags, callback, ptr)
2983
? 0 : -1;
2984
}
2985
2986
struct evdns_request *
2987
evdns_base_resolve_reverse(struct evdns_base *base, const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
2988
char buf[32];
2989
struct evdns_request *handle;
2990
struct request *req;
2991
u32 a;
2992
EVUTIL_ASSERT(in);
2993
a = ntohl(in->s_addr);
2994
evutil_snprintf(buf, sizeof(buf), "%d.%d.%d.%d.in-addr.arpa",
2995
(int)(u8)((a )&0xff),
2996
(int)(u8)((a>>8 )&0xff),
2997
(int)(u8)((a>>16)&0xff),
2998
(int)(u8)((a>>24)&0xff));
2999
handle = mm_calloc(1, sizeof(*handle));
3000
if (handle == NULL)
3001
return NULL;
3002
log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
3003
EVDNS_LOCK(base);
3004
req = request_new(base, handle, TYPE_PTR, buf, flags, callback, ptr);
3005
if (req)
3006
request_submit(req);
3007
if (handle->current_req == NULL) {
3008
mm_free(handle);
3009
handle = NULL;
3010
}
3011
EVDNS_UNLOCK(base);
3012
return (handle);
3013
}
3014
3015
int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr) {
3016
return evdns_base_resolve_reverse(current_base, in, flags, callback, ptr)
3017
? 0 : -1;
3018
}
3019
3020
struct evdns_request *
3021
evdns_base_resolve_reverse_ipv6(struct evdns_base *base, const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
3022
/* 32 nybbles, 32 periods, "ip6.arpa", NUL. */
3023
char buf[73];
3024
char *cp;
3025
struct evdns_request *handle;
3026
struct request *req;
3027
int i;
3028
EVUTIL_ASSERT(in);
3029
cp = buf;
3030
for (i=15; i >= 0; --i) {
3031
u8 byte = in->s6_addr[i];
3032
*cp++ = "0123456789abcdef"[byte & 0x0f];
3033
*cp++ = '.';
3034
*cp++ = "0123456789abcdef"[byte >> 4];
3035
*cp++ = '.';
3036
}
3037
EVUTIL_ASSERT(cp + strlen("ip6.arpa") < buf+sizeof(buf));
3038
memcpy(cp, "ip6.arpa", strlen("ip6.arpa")+1);
3039
handle = mm_calloc(1, sizeof(*handle));
3040
if (handle == NULL)
3041
return NULL;
3042
log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
3043
EVDNS_LOCK(base);
3044
req = request_new(base, handle, TYPE_PTR, buf, flags, callback, ptr);
3045
if (req)
3046
request_submit(req);
3047
if (handle->current_req == NULL) {
3048
mm_free(handle);
3049
handle = NULL;
3050
}
3051
EVDNS_UNLOCK(base);
3052
return (handle);
3053
}
3054
3055
int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr) {
3056
return evdns_base_resolve_reverse_ipv6(current_base, in, flags, callback, ptr)
3057
? 0 : -1;
3058
}
3059
3060
/* ================================================================= */
3061
/* Search support */
3062
/* */
3063
/* the libc resolver has support for searching a number of domains */
3064
/* to find a name. If nothing else then it takes the single domain */
3065
/* from the gethostname() call. */
3066
/* */
3067
/* It can also be configured via the domain and search options in a */
3068
/* resolv.conf. */
3069
/* */
3070
/* The ndots option controls how many dots it takes for the resolver */
3071
/* to decide that a name is non-local and so try a raw lookup first. */
3072
3073
struct search_domain {
3074
int len;
3075
struct search_domain *next;
3076
/* the text string is appended to this structure */
3077
};
3078
3079
struct search_state {
3080
int refcount;
3081
int ndots;
3082
int num_domains;
3083
struct search_domain *head;
3084
};
3085
3086
static void
3087
search_state_decref(struct search_state *const state) {
3088
if (!state) return;
3089
state->refcount--;
3090
if (!state->refcount) {
3091
struct search_domain *next, *dom;
3092
for (dom = state->head; dom; dom = next) {
3093
next = dom->next;
3094
mm_free(dom);
3095
}
3096
mm_free(state);
3097
}
3098
}
3099
3100
static struct search_state *
3101
search_state_new(void) {
3102
struct search_state *state = (struct search_state *) mm_malloc(sizeof(struct search_state));
3103
if (!state) return NULL;
3104
memset(state, 0, sizeof(struct search_state));
3105
state->refcount = 1;
3106
state->ndots = 1;
3107
3108
return state;
3109
}
3110
3111
static void
3112
search_postfix_clear(struct evdns_base *base) {
3113
search_state_decref(base->global_search_state);
3114
3115
base->global_search_state = search_state_new();
3116
}
3117
3118
/* exported function */
3119
void
3120
evdns_base_search_clear(struct evdns_base *base)
3121
{
3122
EVDNS_LOCK(base);
3123
search_postfix_clear(base);
3124
EVDNS_UNLOCK(base);
3125
}
3126
3127
void
3128
evdns_search_clear(void) {
3129
evdns_base_search_clear(current_base);
3130
}
3131
3132
static void
3133
search_postfix_add(struct evdns_base *base, const char *domain) {
3134
size_t domain_len;
3135
struct search_domain *sdomain;
3136
while (domain[0] == '.') domain++;
3137
domain_len = strlen(domain);
3138
3139
ASSERT_LOCKED(base);
3140
if (!base->global_search_state) base->global_search_state = search_state_new();
3141
if (!base->global_search_state) return;
3142
base->global_search_state->num_domains++;
3143
3144
sdomain = (struct search_domain *) mm_malloc(sizeof(struct search_domain) + domain_len);
3145
if (!sdomain) return;
3146
memcpy( ((u8 *) sdomain) + sizeof(struct search_domain), domain, domain_len);
3147
sdomain->next = base->global_search_state->head;
3148
sdomain->len = (int) domain_len;
3149
3150
base->global_search_state->head = sdomain;
3151
}
3152
3153
/* reverse the order of members in the postfix list. This is needed because, */
3154
/* when parsing resolv.conf we push elements in the wrong order */
3155
static void
3156
search_reverse(struct evdns_base *base) {
3157
struct search_domain *cur, *prev = NULL, *next;
3158
ASSERT_LOCKED(base);
3159
cur = base->global_search_state->head;
3160
while (cur) {
3161
next = cur->next;
3162
cur->next = prev;
3163
prev = cur;
3164
cur = next;
3165
}
3166
3167
base->global_search_state->head = prev;
3168
}
3169
3170
/* exported function */
3171
void
3172
evdns_base_search_add(struct evdns_base *base, const char *domain) {
3173
EVDNS_LOCK(base);
3174
search_postfix_add(base, domain);
3175
EVDNS_UNLOCK(base);
3176
}
3177
void
3178
evdns_search_add(const char *domain) {
3179
evdns_base_search_add(current_base, domain);
3180
}
3181
3182
/* exported function */
3183
void
3184
evdns_base_search_ndots_set(struct evdns_base *base, const int ndots) {
3185
EVDNS_LOCK(base);
3186
if (!base->global_search_state) base->global_search_state = search_state_new();
3187
if (base->global_search_state)
3188
base->global_search_state->ndots = ndots;
3189
EVDNS_UNLOCK(base);
3190
}
3191
void
3192
evdns_search_ndots_set(const int ndots) {
3193
evdns_base_search_ndots_set(current_base, ndots);
3194
}
3195
3196
static void
3197
search_set_from_hostname(struct evdns_base *base) {
3198
char hostname[HOST_NAME_MAX + 1], *domainname;
3199
3200
ASSERT_LOCKED(base);
3201
search_postfix_clear(base);
3202
if (gethostname(hostname, sizeof(hostname))) return;
3203
domainname = strchr(hostname, '.');
3204
if (!domainname) return;
3205
search_postfix_add(base, domainname);
3206
}
3207
3208
/* warning: returns malloced string */
3209
static char *
3210
search_make_new(const struct search_state *const state, int n, const char *const base_name) {
3211
const size_t base_len = strlen(base_name);
3212
char need_to_append_dot;
3213
struct search_domain *dom;
3214
3215
if (!base_len) return NULL;
3216
need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
3217
3218
for (dom = state->head; dom; dom = dom->next) {
3219
if (!n--) {
3220
/* this is the postfix we want */
3221
/* the actual postfix string is kept at the end of the structure */
3222
const u8 *const postfix = ((u8 *) dom) + sizeof(struct search_domain);
3223
const int postfix_len = dom->len;
3224
char *const newname = (char *) mm_malloc(base_len + need_to_append_dot + postfix_len + 1);
3225
if (!newname) return NULL;
3226
memcpy(newname, base_name, base_len);
3227
if (need_to_append_dot) newname[base_len] = '.';
3228
memcpy(newname + base_len + need_to_append_dot, postfix, postfix_len);
3229
newname[base_len + need_to_append_dot + postfix_len] = 0;
3230
return newname;
3231
}
3232
}
3233
3234
/* we ran off the end of the list and still didn't find the requested string */
3235
EVUTIL_ASSERT(0);
3236
return NULL; /* unreachable; stops warnings in some compilers. */
3237
}
3238
3239
static struct request *
3240
search_request_new(struct evdns_base *base, struct evdns_request *handle,
3241
int type, const char *const name, int flags,
3242
evdns_callback_type user_callback, void *user_arg) {
3243
ASSERT_LOCKED(base);
3244
EVUTIL_ASSERT(type == TYPE_A || type == TYPE_AAAA);
3245
EVUTIL_ASSERT(handle->current_req == NULL);
3246
if ( ((flags & DNS_QUERY_NO_SEARCH) == 0) &&
3247
base->global_search_state &&
3248
base->global_search_state->num_domains) {
3249
/* we have some domains to search */
3250
struct request *req;
3251
if (string_num_dots(name) >= base->global_search_state->ndots) {
3252
req = request_new(base, handle, type, name, flags, user_callback, user_arg);
3253
if (!req) return NULL;
3254
handle->search_index = -1;
3255
} else {
3256
char *const new_name = search_make_new(base->global_search_state, 0, name);
3257
if (!new_name) return NULL;
3258
req = request_new(base, handle, type, new_name, flags, user_callback, user_arg);
3259
mm_free(new_name);
3260
if (!req) return NULL;
3261
handle->search_index = 0;
3262
}
3263
EVUTIL_ASSERT(handle->search_origname == NULL);
3264
handle->search_origname = mm_strdup(name);
3265
if (handle->search_origname == NULL) {
3266
/* XXX Should we dealloc req? If yes, how? */
3267
if (req)
3268
mm_free(req);
3269
return NULL;
3270
}
3271
handle->search_state = base->global_search_state;
3272
handle->search_flags = flags;
3273
base->global_search_state->refcount++;
3274
request_submit(req);
3275
return req;
3276
} else {
3277
struct request *const req = request_new(base, handle, type, name, flags, user_callback, user_arg);
3278
if (!req) return NULL;
3279
request_submit(req);
3280
return req;
3281
}
3282
}
3283
3284
/* this is called when a request has failed to find a name. We need to check */
3285
/* if it is part of a search and, if so, try the next name in the list */
3286
/* returns: */
3287
/* 0 another request has been submitted */
3288
/* 1 no more requests needed */
3289
static int
3290
search_try_next(struct evdns_request *const handle) {
3291
struct request *req = handle->current_req;
3292
struct evdns_base *base = req->base;
3293
struct request *newreq;
3294
ASSERT_LOCKED(base);
3295
if (handle->search_state) {
3296
/* it is part of a search */
3297
char *new_name;
3298
handle->search_index++;
3299
if (handle->search_index >= handle->search_state->num_domains) {
3300
/* no more postfixes to try, however we may need to try */
3301
/* this name without a postfix */
3302
if (string_num_dots(handle->search_origname) < handle->search_state->ndots) {
3303
/* yep, we need to try it raw */
3304
newreq = request_new(base, NULL, req->request_type, handle->search_origname, handle->search_flags, req->user_callback, req->user_pointer);
3305
log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", handle->search_origname);
3306
if (newreq) {
3307
search_request_finished(handle);
3308
goto submit_next;
3309
}
3310
}
3311
return 1;
3312
}
3313
3314
new_name = search_make_new(handle->search_state, handle->search_index, handle->search_origname);
3315
if (!new_name) return 1;
3316
log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, handle->search_index);
3317
newreq = request_new(base, NULL, req->request_type, new_name, handle->search_flags, req->user_callback, req->user_pointer);
3318
mm_free(new_name);
3319
if (!newreq) return 1;
3320
goto submit_next;
3321
}
3322
return 1;
3323
3324
submit_next:
3325
request_finished(req, &REQ_HEAD(req->base, req->trans_id), 0);
3326
handle->current_req = newreq;
3327
newreq->handle = handle;
3328
request_submit(newreq);
3329
return 0;
3330
}
3331
3332
static void
3333
search_request_finished(struct evdns_request *const handle) {
3334
ASSERT_LOCKED(handle->current_req->base);
3335
if (handle->search_state) {
3336
search_state_decref(handle->search_state);
3337
handle->search_state = NULL;
3338
}
3339
if (handle->search_origname) {
3340
mm_free(handle->search_origname);
3341
handle->search_origname = NULL;
3342
}
3343
}
3344
3345
/* ================================================================= */
3346
/* Parsing resolv.conf files */
3347
3348
static void
3349
evdns_resolv_set_defaults(struct evdns_base *base, int flags) {
3350
int add_default = flags & DNS_OPTION_NAMESERVERS;
3351
if (flags & DNS_OPTION_NAMESERVERS_NO_DEFAULT)
3352
add_default = 0;
3353
3354
/* if the file isn't found then we assume a local resolver */
3355
ASSERT_LOCKED(base);
3356
if (flags & DNS_OPTION_SEARCH)
3357
search_set_from_hostname(base);
3358
if (add_default)
3359
evdns_base_nameserver_ip_add(base, "127.0.0.1");
3360
}
3361
3362
#ifndef EVENT__HAVE_STRTOK_R
3363
static char *
3364
strtok_r(char *s, const char *delim, char **state) {
3365
char *cp, *start;
3366
start = cp = s ? s : *state;
3367
if (!cp)
3368
return NULL;
3369
while (*cp && !strchr(delim, *cp))
3370
++cp;
3371
if (!*cp) {
3372
if (cp == start)
3373
return NULL;
3374
*state = NULL;
3375
return start;
3376
} else {
3377
*cp++ = '\0';
3378
*state = cp;
3379
return start;
3380
}
3381
}
3382
#endif
3383
3384
/* helper version of atoi which returns -1 on error */
3385
static int
3386
strtoint(const char *const str)
3387
{
3388
char *endptr;
3389
const int r = strtol(str, &endptr, 10);
3390
if (*endptr) return -1;
3391
return r;
3392
}
3393
3394
/* Parse a number of seconds into a timeval; return -1 on error. */
3395
static int
3396
evdns_strtotimeval(const char *const str, struct timeval *out)
3397
{
3398
double d;
3399
char *endptr;
3400
d = strtod(str, &endptr);
3401
if (*endptr) return -1;
3402
if (d < 0) return -1;
3403
out->tv_sec = (int) d;
3404
out->tv_usec = (int) ((d - (int) d)*1000000);
3405
if (out->tv_sec == 0 && out->tv_usec < 1000) /* less than 1 msec */
3406
return -1;
3407
return 0;
3408
}
3409
3410
/* helper version of atoi that returns -1 on error and clips to bounds. */
3411
static int
3412
strtoint_clipped(const char *const str, int min, int max)
3413
{
3414
int r = strtoint(str);
3415
if (r == -1)
3416
return r;
3417
else if (r<min)
3418
return min;
3419
else if (r>max)
3420
return max;
3421
else
3422
return r;
3423
}
3424
3425
static int
3426
evdns_base_set_max_requests_inflight(struct evdns_base *base, int maxinflight)
3427
{
3428
int old_n_heads = base->n_req_heads, n_heads;
3429
struct request **old_heads = base->req_heads, **new_heads, *req;
3430
int i;
3431
3432
ASSERT_LOCKED(base);
3433
if (maxinflight < 1)
3434
maxinflight = 1;
3435
n_heads = (maxinflight+4) / 5;
3436
EVUTIL_ASSERT(n_heads > 0);
3437
new_heads = mm_calloc(n_heads, sizeof(struct request*));
3438
if (!new_heads)
3439
return (-1);
3440
if (old_heads) {
3441
for (i = 0; i < old_n_heads; ++i) {
3442
while (old_heads[i]) {
3443
req = old_heads[i];
3444
evdns_request_remove(req, &old_heads[i]);
3445
evdns_request_insert(req, &new_heads[req->trans_id % n_heads]);
3446
}
3447
}
3448
mm_free(old_heads);
3449
}
3450
base->req_heads = new_heads;
3451
base->n_req_heads = n_heads;
3452
base->global_max_requests_inflight = maxinflight;
3453
return (0);
3454
}
3455
3456
/* exported function */
3457
int
3458
evdns_base_set_option(struct evdns_base *base,
3459
const char *option, const char *val)
3460
{
3461
int res;
3462
EVDNS_LOCK(base);
3463
res = evdns_base_set_option_impl(base, option, val, DNS_OPTIONS_ALL);
3464
EVDNS_UNLOCK(base);
3465
return res;
3466
}
3467
3468
static inline int
3469
str_matches_option(const char *s1, const char *optionname)
3470
{
3471
/* Option names are given as "option:" We accept either 'option' in
3472
* s1, or 'option:randomjunk'. The latter form is to implement the
3473
* resolv.conf parser. */
3474
size_t optlen = strlen(optionname);
3475
size_t slen = strlen(s1);
3476
if (slen == optlen || slen == optlen - 1)
3477
return !strncmp(s1, optionname, slen);
3478
else if (slen > optlen)
3479
return !strncmp(s1, optionname, optlen);
3480
else
3481
return 0;
3482
}
3483
3484
static int
3485
evdns_base_set_option_impl(struct evdns_base *base,
3486
const char *option, const char *val, int flags)
3487
{
3488
ASSERT_LOCKED(base);
3489
if (str_matches_option(option, "ndots:")) {
3490
const int ndots = strtoint(val);
3491
if (ndots == -1) return -1;
3492
if (!(flags & DNS_OPTION_SEARCH)) return 0;
3493
log(EVDNS_LOG_DEBUG, "Setting ndots to %d", ndots);
3494
if (!base->global_search_state) base->global_search_state = search_state_new();
3495
if (!base->global_search_state) return -1;
3496
base->global_search_state->ndots = ndots;
3497
} else if (str_matches_option(option, "timeout:")) {
3498
struct timeval tv;
3499
if (evdns_strtotimeval(val, &tv) == -1) return -1;
3500
if (!(flags & DNS_OPTION_MISC)) return 0;
3501
log(EVDNS_LOG_DEBUG, "Setting timeout to %s", val);
3502
memcpy(&base->global_timeout, &tv, sizeof(struct timeval));
3503
} else if (str_matches_option(option, "getaddrinfo-allow-skew:")) {
3504
struct timeval tv;
3505
if (evdns_strtotimeval(val, &tv) == -1) return -1;
3506
if (!(flags & DNS_OPTION_MISC)) return 0;
3507
log(EVDNS_LOG_DEBUG, "Setting getaddrinfo-allow-skew to %s",
3508
val);
3509
memcpy(&base->global_getaddrinfo_allow_skew, &tv,
3510
sizeof(struct timeval));
3511
} else if (str_matches_option(option, "max-timeouts:")) {
3512
const int maxtimeout = strtoint_clipped(val, 1, 255);
3513
if (maxtimeout == -1) return -1;
3514
if (!(flags & DNS_OPTION_MISC)) return 0;
3515
log(EVDNS_LOG_DEBUG, "Setting maximum allowed timeouts to %d",
3516
maxtimeout);
3517
base->global_max_nameserver_timeout = maxtimeout;
3518
} else if (str_matches_option(option, "max-inflight:")) {
3519
const int maxinflight = strtoint_clipped(val, 1, 65000);
3520
if (maxinflight == -1) return -1;
3521
if (!(flags & DNS_OPTION_MISC)) return 0;
3522
log(EVDNS_LOG_DEBUG, "Setting maximum inflight requests to %d",
3523
maxinflight);
3524
evdns_base_set_max_requests_inflight(base, maxinflight);
3525
} else if (str_matches_option(option, "attempts:")) {
3526
int retries = strtoint(val);
3527
if (retries == -1) return -1;
3528
if (retries > 255) retries = 255;
3529
if (!(flags & DNS_OPTION_MISC)) return 0;
3530
log(EVDNS_LOG_DEBUG, "Setting retries to %d", retries);
3531
base->global_max_retransmits = retries;
3532
} else if (str_matches_option(option, "randomize-case:")) {
3533
int randcase = strtoint(val);
3534
if (randcase == -1) return -1;
3535
if (!(flags & DNS_OPTION_MISC)) return 0;
3536
base->global_randomize_case = randcase;
3537
} else if (str_matches_option(option, "bind-to:")) {
3538
/* XXX This only applies to successive nameservers, not
3539
* to already-configured ones. We might want to fix that. */
3540
int len = sizeof(base->global_outgoing_address);
3541
if (!(flags & DNS_OPTION_NAMESERVERS)) return 0;
3542
if (evutil_parse_sockaddr_port(val,
3543
(struct sockaddr*)&base->global_outgoing_address, &len))
3544
return -1;
3545
base->global_outgoing_addrlen = len;
3546
} else if (str_matches_option(option, "initial-probe-timeout:")) {
3547
struct timeval tv;
3548
if (evdns_strtotimeval(val, &tv) == -1) return -1;
3549
if (tv.tv_sec > 3600)
3550
tv.tv_sec = 3600;
3551
if (!(flags & DNS_OPTION_MISC)) return 0;
3552
log(EVDNS_LOG_DEBUG, "Setting initial probe timeout to %s",
3553
val);
3554
memcpy(&base->global_nameserver_probe_initial_timeout, &tv,
3555
sizeof(tv));
3556
} else if (str_matches_option(option, "so-rcvbuf:")) {
3557
int buf = strtoint(val);
3558
if (buf == -1) return -1;
3559
if (!(flags & DNS_OPTION_MISC)) return 0;
3560
log(EVDNS_LOG_DEBUG, "Setting SO_RCVBUF to %s", val);
3561
base->so_rcvbuf = buf;
3562
} else if (str_matches_option(option, "so-sndbuf:")) {
3563
int buf = strtoint(val);
3564
if (buf == -1) return -1;
3565
if (!(flags & DNS_OPTION_MISC)) return 0;
3566
log(EVDNS_LOG_DEBUG, "Setting SO_SNDBUF to %s", val);
3567
base->so_sndbuf = buf;
3568
}
3569
return 0;
3570
}
3571
3572
int
3573
evdns_set_option(const char *option, const char *val, int flags)
3574
{
3575
if (!current_base)
3576
current_base = evdns_base_new(NULL, 0);
3577
return evdns_base_set_option(current_base, option, val);
3578
}
3579
3580
static void
3581
resolv_conf_parse_line(struct evdns_base *base, char *const start, int flags) {
3582
char *strtok_state;
3583
static const char *const delims = " \t";
3584
#define NEXT_TOKEN strtok_r(NULL, delims, &strtok_state)
3585
3586
3587
char *const first_token = strtok_r(start, delims, &strtok_state);
3588
ASSERT_LOCKED(base);
3589
if (!first_token) return;
3590
3591
if (!strcmp(first_token, "nameserver") && (flags & DNS_OPTION_NAMESERVERS)) {
3592
const char *const nameserver = NEXT_TOKEN;
3593
3594
if (nameserver)
3595
evdns_base_nameserver_ip_add(base, nameserver);
3596
} else if (!strcmp(first_token, "domain") && (flags & DNS_OPTION_SEARCH)) {
3597
const char *const domain = NEXT_TOKEN;
3598
if (domain) {
3599
search_postfix_clear(base);
3600
search_postfix_add(base, domain);
3601
}
3602
} else if (!strcmp(first_token, "search") && (flags & DNS_OPTION_SEARCH)) {
3603
const char *domain;
3604
search_postfix_clear(base);
3605
3606
while ((domain = NEXT_TOKEN)) {
3607
search_postfix_add(base, domain);
3608
}
3609
search_reverse(base);
3610
} else if (!strcmp(first_token, "options")) {
3611
const char *option;
3612
while ((option = NEXT_TOKEN)) {
3613
const char *val = strchr(option, ':');
3614
evdns_base_set_option_impl(base, option, val ? val+1 : "", flags);
3615
}
3616
}
3617
#undef NEXT_TOKEN
3618
}
3619
3620
/* exported function */
3621
/* returns: */
3622
/* 0 no errors */
3623
/* 1 failed to open file */
3624
/* 2 failed to stat file */
3625
/* 3 file too large */
3626
/* 4 out of memory */
3627
/* 5 short read from file */
3628
int
3629
evdns_base_resolv_conf_parse(struct evdns_base *base, int flags, const char *const filename) {
3630
int res;
3631
EVDNS_LOCK(base);
3632
res = evdns_base_resolv_conf_parse_impl(base, flags, filename);
3633
EVDNS_UNLOCK(base);
3634
return res;
3635
}
3636
3637
static char *
3638
evdns_get_default_hosts_filename(void)
3639
{
3640
#ifdef _WIN32
3641
/* Windows is a little coy about where it puts its configuration
3642
* files. Sure, they're _usually_ in C:\windows\system32, but
3643
* there's no reason in principle they couldn't be in
3644
* W:\hoboken chicken emergency\
3645
*/
3646
char path[MAX_PATH+1];
3647
static const char hostfile[] = "\\drivers\\etc\\hosts";
3648
char *path_out;
3649
size_t len_out;
3650
3651
if (! SHGetSpecialFolderPathA(NULL, path, CSIDL_SYSTEM, 0))
3652
return NULL;
3653
len_out = strlen(path)+strlen(hostfile)+1;
3654
path_out = mm_malloc(len_out);
3655
evutil_snprintf(path_out, len_out, "%s%s", path, hostfile);
3656
return path_out;
3657
#else
3658
return mm_strdup("/etc/hosts");
3659
#endif
3660
}
3661
3662
static int
3663
evdns_base_resolv_conf_parse_impl(struct evdns_base *base, int flags, const char *const filename) {
3664
size_t n;
3665
char *resolv;
3666
char *start;
3667
int err = 0;
3668
int add_default;
3669
3670
log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
3671
3672
add_default = flags & DNS_OPTION_NAMESERVERS;
3673
if (flags & DNS_OPTION_NAMESERVERS_NO_DEFAULT)
3674
add_default = 0;
3675
3676
if (flags & DNS_OPTION_HOSTSFILE) {
3677
char *fname = evdns_get_default_hosts_filename();
3678
evdns_base_load_hosts(base, fname);
3679
if (fname)
3680
mm_free(fname);
3681
}
3682
3683
if (!filename) {
3684
evdns_resolv_set_defaults(base, flags);
3685
return 1;
3686
}
3687
3688
if ((err = evutil_read_file_(filename, &resolv, &n, 0)) < 0) {
3689
if (err == -1) {
3690
/* No file. */
3691
evdns_resolv_set_defaults(base, flags);
3692
return 1;
3693
} else {
3694
return 2;
3695
}
3696
}
3697
3698
start = resolv;
3699
for (;;) {
3700
char *const newline = strchr(start, '\n');
3701
if (!newline) {
3702
resolv_conf_parse_line(base, start, flags);
3703
break;
3704
} else {
3705
*newline = 0;
3706
resolv_conf_parse_line(base, start, flags);
3707
start = newline + 1;
3708
}
3709
}
3710
3711
if (!base->server_head && add_default) {
3712
/* no nameservers were configured. */
3713
evdns_base_nameserver_ip_add(base, "127.0.0.1");
3714
err = 6;
3715
}
3716
if (flags & DNS_OPTION_SEARCH && (!base->global_search_state || base->global_search_state->num_domains == 0)) {
3717
search_set_from_hostname(base);
3718
}
3719
3720
mm_free(resolv);
3721
return err;
3722
}
3723
3724
int
3725
evdns_resolv_conf_parse(int flags, const char *const filename) {
3726
if (!current_base)
3727
current_base = evdns_base_new(NULL, 0);
3728
return evdns_base_resolv_conf_parse(current_base, flags, filename);
3729
}
3730
3731
3732
#ifdef _WIN32
3733
/* Add multiple nameservers from a space-or-comma-separated list. */
3734
static int
3735
evdns_nameserver_ip_add_line(struct evdns_base *base, const char *ips) {
3736
const char *addr;
3737
char *buf;
3738
int r;
3739
ASSERT_LOCKED(base);
3740
while (*ips) {
3741
while (isspace(*ips) || *ips == ',' || *ips == '\t')
3742
++ips;
3743
addr = ips;
3744
while (isdigit(*ips) || *ips == '.' || *ips == ':' ||
3745
*ips=='[' || *ips==']')
3746
++ips;
3747
buf = mm_malloc(ips-addr+1);
3748
if (!buf) return 4;
3749
memcpy(buf, addr, ips-addr);
3750
buf[ips-addr] = '\0';
3751
r = evdns_base_nameserver_ip_add(base, buf);
3752
mm_free(buf);
3753
if (r) return r;
3754
}
3755
return 0;
3756
}
3757
3758
typedef DWORD(WINAPI *GetNetworkParams_fn_t)(FIXED_INFO *, DWORD*);
3759
3760
/* Use the windows GetNetworkParams interface in iphlpapi.dll to */
3761
/* figure out what our nameservers are. */
3762
static int
3763
load_nameservers_with_getnetworkparams(struct evdns_base *base)
3764
{
3765
/* Based on MSDN examples and inspection of c-ares code. */
3766
FIXED_INFO *fixed;
3767
HMODULE handle = 0;
3768
ULONG size = sizeof(FIXED_INFO);
3769
void *buf = NULL;
3770
int status = 0, r, added_any;
3771
IP_ADDR_STRING *ns;
3772
GetNetworkParams_fn_t fn;
3773
3774
ASSERT_LOCKED(base);
3775
if (!(handle = evutil_load_windows_system_library_(
3776
TEXT("iphlpapi.dll")))) {
3777
log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
3778
status = -1;
3779
goto done;
3780
}
3781
if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, "GetNetworkParams"))) {
3782
log(EVDNS_LOG_WARN, "Could not get address of function.");
3783
status = -1;
3784
goto done;
3785
}
3786
3787
buf = mm_malloc(size);
3788
if (!buf) { status = 4; goto done; }
3789
fixed = buf;
3790
r = fn(fixed, &size);
3791
if (r != ERROR_SUCCESS && r != ERROR_BUFFER_OVERFLOW) {
3792
status = -1;
3793
goto done;
3794
}
3795
if (r != ERROR_SUCCESS) {
3796
mm_free(buf);
3797
buf = mm_malloc(size);
3798
if (!buf) { status = 4; goto done; }
3799
fixed = buf;
3800
r = fn(fixed, &size);
3801
if (r != ERROR_SUCCESS) {
3802
log(EVDNS_LOG_DEBUG, "fn() failed.");
3803
status = -1;
3804
goto done;
3805
}
3806
}
3807
3808
EVUTIL_ASSERT(fixed);
3809
added_any = 0;
3810
ns = &(fixed->DnsServerList);
3811
while (ns) {
3812
r = evdns_nameserver_ip_add_line(base, ns->IpAddress.String);
3813
if (r) {
3814
log(EVDNS_LOG_DEBUG,"Could not add nameserver %s to list,error: %d",
3815
(ns->IpAddress.String),(int)GetLastError());
3816
status = r;
3817
} else {
3818
++added_any;
3819
log(EVDNS_LOG_DEBUG,"Successfully added %s as nameserver",ns->IpAddress.String);
3820
}
3821
3822
ns = ns->Next;
3823
}
3824
3825
if (!added_any) {
3826
log(EVDNS_LOG_DEBUG, "No nameservers added.");
3827
if (status == 0)
3828
status = -1;
3829
} else {
3830
status = 0;
3831
}
3832
3833
done:
3834
if (buf)
3835
mm_free(buf);
3836
if (handle)
3837
FreeLibrary(handle);
3838
return status;
3839
}
3840
3841
static int
3842
config_nameserver_from_reg_key(struct evdns_base *base, HKEY key, const TCHAR *subkey)
3843
{
3844
char *buf;
3845
DWORD bufsz = 0, type = 0;
3846
int status = 0;
3847
3848
ASSERT_LOCKED(base);
3849
if (RegQueryValueEx(key, subkey, 0, &type, NULL, &bufsz)
3850
!= ERROR_MORE_DATA)
3851
return -1;
3852
if (!(buf = mm_malloc(bufsz)))
3853
return -1;
3854
3855
if (RegQueryValueEx(key, subkey, 0, &type, (LPBYTE)buf, &bufsz)
3856
== ERROR_SUCCESS && bufsz > 1) {
3857
status = evdns_nameserver_ip_add_line(base,buf);
3858
}
3859
3860
mm_free(buf);
3861
return status;
3862
}
3863
3864
#define SERVICES_KEY TEXT("System\\CurrentControlSet\\Services\\")
3865
#define WIN_NS_9X_KEY SERVICES_KEY TEXT("VxD\\MSTCP")
3866
#define WIN_NS_NT_KEY SERVICES_KEY TEXT("Tcpip\\Parameters")
3867
3868
static int
3869
load_nameservers_from_registry(struct evdns_base *base)
3870
{
3871
int found = 0;
3872
int r;
3873
#define TRY(k, name) \
3874
if (!found && config_nameserver_from_reg_key(base,k,TEXT(name)) == 0) { \
3875
log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name); \
3876
found = 1; \
3877
} else if (!found) { \
3878
log(EVDNS_LOG_DEBUG,"Didn't find nameservers in %s/%s", \
3879
#k,#name); \
3880
}
3881
3882
ASSERT_LOCKED(base);
3883
3884
if (((int)GetVersion()) > 0) { /* NT */
3885
HKEY nt_key = 0, interfaces_key = 0;
3886
3887
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
3888
KEY_READ, &nt_key) != ERROR_SUCCESS) {
3889
log(EVDNS_LOG_DEBUG,"Couldn't open nt key, %d",(int)GetLastError());
3890
return -1;
3891
}
3892
r = RegOpenKeyEx(nt_key, TEXT("Interfaces"), 0,
3893
KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
3894
&interfaces_key);
3895
if (r != ERROR_SUCCESS) {
3896
log(EVDNS_LOG_DEBUG,"Couldn't open interfaces key, %d",(int)GetLastError());
3897
return -1;
3898
}
3899
TRY(nt_key, "NameServer");
3900
TRY(nt_key, "DhcpNameServer");
3901
TRY(interfaces_key, "NameServer");
3902
TRY(interfaces_key, "DhcpNameServer");
3903
RegCloseKey(interfaces_key);
3904
RegCloseKey(nt_key);
3905
} else {
3906
HKEY win_key = 0;
3907
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X_KEY, 0,
3908
KEY_READ, &win_key) != ERROR_SUCCESS) {
3909
log(EVDNS_LOG_DEBUG, "Couldn't open registry key, %d", (int)GetLastError());
3910
return -1;
3911
}
3912
TRY(win_key, "NameServer");
3913
RegCloseKey(win_key);
3914
}
3915
3916
if (found == 0) {
3917
log(EVDNS_LOG_WARN,"Didn't find any nameservers.");
3918
}
3919
3920
return found ? 0 : -1;
3921
#undef TRY
3922
}
3923
3924
int
3925
evdns_base_config_windows_nameservers(struct evdns_base *base)
3926
{
3927
int r;
3928
char *fname;
3929
if (base == NULL)
3930
base = current_base;
3931
if (base == NULL)
3932
return -1;
3933
EVDNS_LOCK(base);
3934
fname = evdns_get_default_hosts_filename();
3935
log(EVDNS_LOG_DEBUG, "Loading hosts entries from %s", fname);
3936
evdns_base_load_hosts(base, fname);
3937
if (fname)
3938
mm_free(fname);
3939
3940
if (load_nameservers_with_getnetworkparams(base) == 0) {
3941
EVDNS_UNLOCK(base);
3942
return 0;
3943
}
3944
r = load_nameservers_from_registry(base);
3945
3946
EVDNS_UNLOCK(base);
3947
return r;
3948
}
3949
3950
int
3951
evdns_config_windows_nameservers(void)
3952
{
3953
if (!current_base) {
3954
current_base = evdns_base_new(NULL, 1);
3955
return current_base == NULL ? -1 : 0;
3956
} else {
3957
return evdns_base_config_windows_nameservers(current_base);
3958
}
3959
}
3960
#endif
3961
3962
struct evdns_base *
3963
evdns_base_new(struct event_base *event_base, int flags)
3964
{
3965
struct evdns_base *base;
3966
3967
if (evutil_secure_rng_init() < 0) {
3968
log(EVDNS_LOG_WARN, "Unable to seed random number generator; "
3969
"DNS can't run.");
3970
return NULL;
3971
}
3972
3973
/* Give the evutil library a hook into its evdns-enabled
3974
* functionality. We can't just call evdns_getaddrinfo directly or
3975
* else libevent-core will depend on libevent-extras. */
3976
evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo);
3977
evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel);
3978
3979
base = mm_malloc(sizeof(struct evdns_base));
3980
if (base == NULL)
3981
return (NULL);
3982
memset(base, 0, sizeof(struct evdns_base));
3983
base->req_waiting_head = NULL;
3984
3985
EVTHREAD_ALLOC_LOCK(base->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
3986
EVDNS_LOCK(base);
3987
3988
/* Set max requests inflight and allocate req_heads. */
3989
base->req_heads = NULL;
3990
3991
evdns_base_set_max_requests_inflight(base, 64);
3992
3993
base->server_head = NULL;
3994
base->event_base = event_base;
3995
base->global_good_nameservers = base->global_requests_inflight =
3996
base->global_requests_waiting = 0;
3997
3998
base->global_timeout.tv_sec = 5;
3999
base->global_timeout.tv_usec = 0;
4000
base->global_max_reissues = 1;
4001
base->global_max_retransmits = 3;
4002
base->global_max_nameserver_timeout = 3;
4003
base->global_search_state = NULL;
4004
base->global_randomize_case = 1;
4005
base->global_getaddrinfo_allow_skew.tv_sec = 3;
4006
base->global_getaddrinfo_allow_skew.tv_usec = 0;
4007
base->global_nameserver_probe_initial_timeout.tv_sec = 10;
4008
base->global_nameserver_probe_initial_timeout.tv_usec = 0;
4009
4010
TAILQ_INIT(&base->hostsdb);
4011
4012
#define EVDNS_BASE_ALL_FLAGS ( \
4013
EVDNS_BASE_INITIALIZE_NAMESERVERS | \
4014
EVDNS_BASE_DISABLE_WHEN_INACTIVE | \
4015
EVDNS_BASE_NAMESERVERS_NO_DEFAULT | \
4016
0)
4017
4018
if (flags & ~EVDNS_BASE_ALL_FLAGS) {
4019
flags = EVDNS_BASE_INITIALIZE_NAMESERVERS;
4020
log(EVDNS_LOG_WARN,
4021
"Unrecognized flag passed to evdns_base_new(). Assuming "
4022
"you meant EVDNS_BASE_INITIALIZE_NAMESERVERS.");
4023
}
4024
#undef EVDNS_BASE_ALL_FLAGS
4025
4026
if (flags & EVDNS_BASE_INITIALIZE_NAMESERVERS) {
4027
int r;
4028
int opts = DNS_OPTIONS_ALL;
4029
if (flags & EVDNS_BASE_NAMESERVERS_NO_DEFAULT) {
4030
opts |= DNS_OPTION_NAMESERVERS_NO_DEFAULT;
4031
}
4032
4033
#ifdef _WIN32
4034
r = evdns_base_config_windows_nameservers(base);
4035
#else
4036
r = evdns_base_resolv_conf_parse(base, opts, "/etc/resolv.conf");
4037
#endif
4038
if (r) {
4039
evdns_base_free_and_unlock(base, 0);
4040
return NULL;
4041
}
4042
}
4043
if (flags & EVDNS_BASE_DISABLE_WHEN_INACTIVE) {
4044
base->disable_when_inactive = 1;
4045
}
4046
4047
EVDNS_UNLOCK(base);
4048
return base;
4049
}
4050
4051
int
4052
evdns_init(void)
4053
{
4054
struct evdns_base *base = evdns_base_new(NULL, 1);
4055
if (base) {
4056
current_base = base;
4057
return 0;
4058
} else {
4059
return -1;
4060
}
4061
}
4062
4063
const char *
4064
evdns_err_to_string(int err)
4065
{
4066
switch (err) {
4067
case DNS_ERR_NONE: return "no error";
4068
case DNS_ERR_FORMAT: return "misformatted query";
4069
case DNS_ERR_SERVERFAILED: return "server failed";
4070
case DNS_ERR_NOTEXIST: return "name does not exist";
4071
case DNS_ERR_NOTIMPL: return "query not implemented";
4072
case DNS_ERR_REFUSED: return "refused";
4073
4074
case DNS_ERR_TRUNCATED: return "reply truncated or ill-formed";
4075
case DNS_ERR_UNKNOWN: return "unknown";
4076
case DNS_ERR_TIMEOUT: return "request timed out";
4077
case DNS_ERR_SHUTDOWN: return "dns subsystem shut down";
4078
case DNS_ERR_CANCEL: return "dns request canceled";
4079
case DNS_ERR_NODATA: return "no records in the reply";
4080
default: return "[Unknown error code]";
4081
}
4082
}
4083
4084
static void
4085
evdns_nameserver_free(struct nameserver *server)
4086
{
4087
if (server->socket >= 0)
4088
evutil_closesocket(server->socket);
4089
(void) event_del(&server->event);
4090
event_debug_unassign(&server->event);
4091
if (server->state == 0)
4092
(void) event_del(&server->timeout_event);
4093
if (server->probe_request) {
4094
evdns_cancel_request(server->base, server->probe_request);
4095
server->probe_request = NULL;
4096
}
4097
event_debug_unassign(&server->timeout_event);
4098
mm_free(server);
4099
}
4100
4101
static void
4102
evdns_base_free_and_unlock(struct evdns_base *base, int fail_requests)
4103
{
4104
struct nameserver *server, *server_next;
4105
struct search_domain *dom, *dom_next;
4106
int i;
4107
4108
/* Requires that we hold the lock. */
4109
4110
/* TODO(nickm) we might need to refcount here. */
4111
4112
while (base->req_waiting_head) {
4113
if (fail_requests)
4114
reply_schedule_callback(base->req_waiting_head, 0, DNS_ERR_SHUTDOWN, NULL);
4115
request_finished(base->req_waiting_head, &base->req_waiting_head, 1);
4116
}
4117
for (i = 0; i < base->n_req_heads; ++i) {
4118
while (base->req_heads[i]) {
4119
if (fail_requests)
4120
reply_schedule_callback(base->req_heads[i], 0, DNS_ERR_SHUTDOWN, NULL);
4121
request_finished(base->req_heads[i], &REQ_HEAD(base, base->req_heads[i]->trans_id), 1);
4122
}
4123
}
4124
base->global_requests_inflight = base->global_requests_waiting = 0;
4125
4126
for (server = base->server_head; server; server = server_next) {
4127
server_next = server->next;
4128
/** already done something before */
4129
server->probe_request = NULL;
4130
evdns_nameserver_free(server);
4131
if (server_next == base->server_head)
4132
break;
4133
}
4134
base->server_head = NULL;
4135
base->global_good_nameservers = 0;
4136
4137
if (base->global_search_state) {
4138
for (dom = base->global_search_state->head; dom; dom = dom_next) {
4139
dom_next = dom->next;
4140
mm_free(dom);
4141
}
4142
mm_free(base->global_search_state);
4143
base->global_search_state = NULL;
4144
}
4145
4146
{
4147
struct hosts_entry *victim;
4148
while ((victim = TAILQ_FIRST(&base->hostsdb))) {
4149
TAILQ_REMOVE(&base->hostsdb, victim, next);
4150
mm_free(victim);
4151
}
4152
}
4153
4154
mm_free(base->req_heads);
4155
4156
EVDNS_UNLOCK(base);
4157
EVTHREAD_FREE_LOCK(base->lock, EVTHREAD_LOCKTYPE_RECURSIVE);
4158
4159
mm_free(base);
4160
}
4161
4162
void
4163
evdns_base_free(struct evdns_base *base, int fail_requests)
4164
{
4165
EVDNS_LOCK(base);
4166
evdns_base_free_and_unlock(base, fail_requests);
4167
}
4168
4169
void
4170
evdns_base_clear_host_addresses(struct evdns_base *base)
4171
{
4172
struct hosts_entry *victim;
4173
EVDNS_LOCK(base);
4174
while ((victim = TAILQ_FIRST(&base->hostsdb))) {
4175
TAILQ_REMOVE(&base->hostsdb, victim, next);
4176
mm_free(victim);
4177
}
4178
EVDNS_UNLOCK(base);
4179
}
4180
4181
void
4182
evdns_shutdown(int fail_requests)
4183
{
4184
if (current_base) {
4185
struct evdns_base *b = current_base;
4186
current_base = NULL;
4187
evdns_base_free(b, fail_requests);
4188
}
4189
evdns_log_fn = NULL;
4190
}
4191
4192
static int
4193
evdns_base_parse_hosts_line(struct evdns_base *base, char *line)
4194
{
4195
char *strtok_state;
4196
static const char *const delims = " \t";
4197
char *const addr = strtok_r(line, delims, &strtok_state);
4198
char *hostname, *hash;
4199
struct sockaddr_storage ss;
4200
int socklen = sizeof(ss);
4201
ASSERT_LOCKED(base);
4202
4203
#define NEXT_TOKEN strtok_r(NULL, delims, &strtok_state)
4204
4205
if (!addr || *addr == '#')
4206
return 0;
4207
4208
memset(&ss, 0, sizeof(ss));
4209
if (evutil_parse_sockaddr_port(addr, (struct sockaddr*)&ss, &socklen)<0)
4210
return -1;
4211
if (socklen > (int)sizeof(struct sockaddr_in6))
4212
return -1;
4213
4214
if (sockaddr_getport((struct sockaddr*)&ss))
4215
return -1;
4216
4217
while ((hostname = NEXT_TOKEN)) {
4218
struct hosts_entry *he;
4219
size_t namelen;
4220
if ((hash = strchr(hostname, '#'))) {
4221
if (hash == hostname)
4222
return 0;
4223
*hash = '\0';
4224
}
4225
4226
namelen = strlen(hostname);
4227
4228
he = mm_calloc(1, sizeof(struct hosts_entry)+namelen);
4229
if (!he)
4230
return -1;
4231
EVUTIL_ASSERT(socklen <= (int)sizeof(he->addr));
4232
memcpy(&he->addr, &ss, socklen);
4233
memcpy(he->hostname, hostname, namelen+1);
4234
he->addrlen = socklen;
4235
4236
TAILQ_INSERT_TAIL(&base->hostsdb, he, next);
4237
4238
if (hash)
4239
return 0;
4240
}
4241
4242
return 0;
4243
#undef NEXT_TOKEN
4244
}
4245
4246
static int
4247
evdns_base_load_hosts_impl(struct evdns_base *base, const char *hosts_fname)
4248
{
4249
char *str=NULL, *cp, *eol;
4250
size_t len;
4251
int err=0;
4252
4253
ASSERT_LOCKED(base);
4254
4255
if (hosts_fname == NULL ||
4256
(err = evutil_read_file_(hosts_fname, &str, &len, 0)) < 0) {
4257
char tmp[64];
4258
strlcpy(tmp, "127.0.0.1 localhost", sizeof(tmp));
4259
evdns_base_parse_hosts_line(base, tmp);
4260
strlcpy(tmp, "::1 localhost", sizeof(tmp));
4261
evdns_base_parse_hosts_line(base, tmp);
4262
return err ? -1 : 0;
4263
}
4264
4265
/* This will break early if there is a NUL in the hosts file.
4266
* Probably not a problem.*/
4267
cp = str;
4268
for (;;) {
4269
eol = strchr(cp, '\n');
4270
4271
if (eol) {
4272
*eol = '\0';
4273
evdns_base_parse_hosts_line(base, cp);
4274
cp = eol+1;
4275
} else {
4276
evdns_base_parse_hosts_line(base, cp);
4277
break;
4278
}
4279
}
4280
4281
mm_free(str);
4282
return 0;
4283
}
4284
4285
int
4286
evdns_base_load_hosts(struct evdns_base *base, const char *hosts_fname)
4287
{
4288
int res;
4289
if (!base)
4290
base = current_base;
4291
EVDNS_LOCK(base);
4292
res = evdns_base_load_hosts_impl(base, hosts_fname);
4293
EVDNS_UNLOCK(base);
4294
return res;
4295
}
4296
4297
/* A single request for a getaddrinfo, either v4 or v6. */
4298
struct getaddrinfo_subrequest {
4299
struct evdns_request *r;
4300
ev_uint32_t type;
4301
};
4302
4303
/* State data used to implement an in-progress getaddrinfo. */
4304
struct evdns_getaddrinfo_request {
4305
struct evdns_base *evdns_base;
4306
/* Copy of the modified 'hints' data that we'll use to build
4307
* answers. */
4308
struct evutil_addrinfo hints;
4309
/* The callback to invoke when we're done */
4310
evdns_getaddrinfo_cb user_cb;
4311
/* User-supplied data to give to the callback. */
4312
void *user_data;
4313
/* The port to use when building sockaddrs. */
4314
ev_uint16_t port;
4315
/* The sub_request for an A record (if any) */
4316
struct getaddrinfo_subrequest ipv4_request;
4317
/* The sub_request for an AAAA record (if any) */
4318
struct getaddrinfo_subrequest ipv6_request;
4319
4320
/* The cname result that we were told (if any) */
4321
char *cname_result;
4322
4323
/* If we have one request answered and one request still inflight,
4324
* then this field holds the answer from the first request... */
4325
struct evutil_addrinfo *pending_result;
4326
/* And this event is a timeout that will tell us to cancel the second
4327
* request if it's taking a long time. */
4328
struct event timeout;
4329
4330
/* And this field holds the error code from the first request... */
4331
int pending_error;
4332
/* If this is set, the user canceled this request. */
4333
unsigned user_canceled : 1;
4334
/* If this is set, the user can no longer cancel this request; we're
4335
* just waiting for the free. */
4336
unsigned request_done : 1;
4337
};
4338
4339
/* Convert an evdns errors to the equivalent getaddrinfo error. */
4340
static int
4341
evdns_err_to_getaddrinfo_err(int e1)
4342
{
4343
/* XXX Do this better! */
4344
if (e1 == DNS_ERR_NONE)
4345
return 0;
4346
else if (e1 == DNS_ERR_NOTEXIST)
4347
return EVUTIL_EAI_NONAME;
4348
else
4349
return EVUTIL_EAI_FAIL;
4350
}
4351
4352
/* Return the more informative of two getaddrinfo errors. */
4353
static int
4354
getaddrinfo_merge_err(int e1, int e2)
4355
{
4356
/* XXXX be cleverer here. */
4357
if (e1 == 0)
4358
return e2;
4359
else
4360
return e1;
4361
}
4362
4363
static void
4364
free_getaddrinfo_request(struct evdns_getaddrinfo_request *data)
4365
{
4366
/* DO NOT CALL this if either of the requests is pending. Only once
4367
* both callbacks have been invoked is it safe to free the request */
4368
if (data->pending_result)
4369
evutil_freeaddrinfo(data->pending_result);
4370
if (data->cname_result)
4371
mm_free(data->cname_result);
4372
event_del(&data->timeout);
4373
mm_free(data);
4374
return;
4375
}
4376
4377
static void
4378
add_cname_to_reply(struct evdns_getaddrinfo_request *data,
4379
struct evutil_addrinfo *ai)
4380
{
4381
if (data->cname_result && ai) {
4382
ai->ai_canonname = data->cname_result;
4383
data->cname_result = NULL;
4384
}
4385
}
4386
4387
/* Callback: invoked when one request in a mixed-format A/AAAA getaddrinfo
4388
* request has finished, but the other one took too long to answer. Pass
4389
* along the answer we got, and cancel the other request.
4390
*/
4391
static void
4392
evdns_getaddrinfo_timeout_cb(evutil_socket_t fd, short what, void *ptr)
4393
{
4394
int v4_timedout = 0, v6_timedout = 0;
4395
struct evdns_getaddrinfo_request *data = ptr;
4396
4397
/* Cancel any pending requests, and note which one */
4398
if (data->ipv4_request.r) {
4399
/* XXXX This does nothing if the request's callback is already
4400
* running (pending_cb is set). */
4401
evdns_cancel_request(NULL, data->ipv4_request.r);
4402
v4_timedout = 1;
4403
EVDNS_LOCK(data->evdns_base);
4404
++data->evdns_base->getaddrinfo_ipv4_timeouts;
4405
EVDNS_UNLOCK(data->evdns_base);
4406
}
4407
if (data->ipv6_request.r) {
4408
/* XXXX This does nothing if the request's callback is already
4409
* running (pending_cb is set). */
4410
evdns_cancel_request(NULL, data->ipv6_request.r);
4411
v6_timedout = 1;
4412
EVDNS_LOCK(data->evdns_base);
4413
++data->evdns_base->getaddrinfo_ipv6_timeouts;
4414
EVDNS_UNLOCK(data->evdns_base);
4415
}
4416
4417
/* We only use this timeout callback when we have an answer for
4418
* one address. */
4419
EVUTIL_ASSERT(!v4_timedout || !v6_timedout);
4420
4421
/* Report the outcome of the other request that didn't time out. */
4422
if (data->pending_result) {
4423
add_cname_to_reply(data, data->pending_result);
4424
data->user_cb(0, data->pending_result, data->user_data);
4425
data->pending_result = NULL;
4426
} else {
4427
int e = data->pending_error;
4428
if (!e)
4429
e = EVUTIL_EAI_AGAIN;
4430
data->user_cb(e, NULL, data->user_data);
4431
}
4432
4433
data->user_cb = NULL; /* prevent double-call if evdns callbacks are
4434
* in-progress. XXXX It would be better if this
4435
* weren't necessary. */
4436
4437
if (!v4_timedout && !v6_timedout) {
4438
/* should be impossible? XXXX */
4439
free_getaddrinfo_request(data);
4440
}
4441
}
4442
4443
static int
4444
evdns_getaddrinfo_set_timeout(struct evdns_base *evdns_base,
4445
struct evdns_getaddrinfo_request *data)
4446
{
4447
return event_add(&data->timeout, &evdns_base->global_getaddrinfo_allow_skew);
4448
}
4449
4450
static inline int
4451
evdns_result_is_answer(int result)
4452
{
4453
return (result != DNS_ERR_NOTIMPL && result != DNS_ERR_REFUSED &&
4454
result != DNS_ERR_SERVERFAILED && result != DNS_ERR_CANCEL);
4455
}
4456
4457
static void
4458
evdns_getaddrinfo_gotresolve(int result, char type, int count,
4459
int ttl, void *addresses, void *arg)
4460
{
4461
int i;
4462
struct getaddrinfo_subrequest *req = arg;
4463
struct getaddrinfo_subrequest *other_req;
4464
struct evdns_getaddrinfo_request *data;
4465
4466
struct evutil_addrinfo *res;
4467
4468
struct sockaddr_in sin;
4469
struct sockaddr_in6 sin6;
4470
struct sockaddr *sa;
4471
int socklen, addrlen;
4472
void *addrp;
4473
int err;
4474
int user_canceled;
4475
4476
EVUTIL_ASSERT(req->type == DNS_IPv4_A || req->type == DNS_IPv6_AAAA);
4477
if (req->type == DNS_IPv4_A) {
4478
data = EVUTIL_UPCAST(req, struct evdns_getaddrinfo_request, ipv4_request);
4479
other_req = &data->ipv6_request;
4480
} else {
4481
data = EVUTIL_UPCAST(req, struct evdns_getaddrinfo_request, ipv6_request);
4482
other_req = &data->ipv4_request;
4483
}
4484
4485
/** Called from evdns_base_free() with @fail_requests == 1 */
4486
if (result != DNS_ERR_SHUTDOWN) {
4487
EVDNS_LOCK(data->evdns_base);
4488
if (evdns_result_is_answer(result)) {
4489
if (req->type == DNS_IPv4_A)
4490
++data->evdns_base->getaddrinfo_ipv4_answered;
4491
else
4492
++data->evdns_base->getaddrinfo_ipv6_answered;
4493
}
4494
user_canceled = data->user_canceled;
4495
if (other_req->r == NULL)
4496
data->request_done = 1;
4497
EVDNS_UNLOCK(data->evdns_base);
4498
} else {
4499
data->evdns_base = NULL;
4500
user_canceled = data->user_canceled;
4501
}
4502
4503
req->r = NULL;
4504
4505
if (result == DNS_ERR_CANCEL && ! user_canceled) {
4506
/* Internal cancel request from timeout or internal error.
4507
* we already answered the user. */
4508
if (other_req->r == NULL)
4509
free_getaddrinfo_request(data);
4510
return;
4511
}
4512
4513
if (data->user_cb == NULL) {
4514
/* We already answered. XXXX This shouldn't be needed; see
4515
* comments in evdns_getaddrinfo_timeout_cb */
4516
free_getaddrinfo_request(data);
4517
return;
4518
}
4519
4520
if (result == DNS_ERR_NONE) {
4521
if (count == 0)
4522
err = EVUTIL_EAI_NODATA;
4523
else
4524
err = 0;
4525
} else {
4526
err = evdns_err_to_getaddrinfo_err(result);
4527
}
4528
4529
if (err) {
4530
/* Looks like we got an error. */
4531
if (other_req->r) {
4532
/* The other request is still working; maybe it will
4533
* succeed. */
4534
/* XXXX handle failure from set_timeout */
4535
if (result != DNS_ERR_SHUTDOWN) {
4536
evdns_getaddrinfo_set_timeout(data->evdns_base, data);
4537
}
4538
data->pending_error = err;
4539
return;
4540
}
4541
4542
if (user_canceled) {
4543
data->user_cb(EVUTIL_EAI_CANCEL, NULL, data->user_data);
4544
} else if (data->pending_result) {
4545
/* If we have an answer waiting, and we weren't
4546
* canceled, ignore this error. */
4547
add_cname_to_reply(data, data->pending_result);
4548
data->user_cb(0, data->pending_result, data->user_data);
4549
data->pending_result = NULL;
4550
} else {
4551
if (data->pending_error)
4552
err = getaddrinfo_merge_err(err,
4553
data->pending_error);
4554
data->user_cb(err, NULL, data->user_data);
4555
}
4556
free_getaddrinfo_request(data);
4557
return;
4558
} else if (user_canceled) {
4559
if (other_req->r) {
4560
/* The other request is still working; let it hit this
4561
* callback with EVUTIL_EAI_CANCEL callback and report
4562
* the failure. */
4563
return;
4564
}
4565
data->user_cb(EVUTIL_EAI_CANCEL, NULL, data->user_data);
4566
free_getaddrinfo_request(data);
4567
return;
4568
}
4569
4570
/* Looks like we got some answers. We should turn them into addrinfos
4571
* and then either queue those or return them all. */
4572
EVUTIL_ASSERT(type == DNS_IPv4_A || type == DNS_IPv6_AAAA);
4573
4574
if (type == DNS_IPv4_A) {
4575
memset(&sin, 0, sizeof(sin));
4576
sin.sin_family = AF_INET;
4577
sin.sin_port = htons(data->port);
4578
4579
sa = (struct sockaddr *)&sin;
4580
socklen = sizeof(sin);
4581
addrlen = 4;
4582
addrp = &sin.sin_addr.s_addr;
4583
} else {
4584
memset(&sin6, 0, sizeof(sin6));
4585
sin6.sin6_family = AF_INET6;
4586
sin6.sin6_port = htons(data->port);
4587
4588
sa = (struct sockaddr *)&sin6;
4589
socklen = sizeof(sin6);
4590
addrlen = 16;
4591
addrp = &sin6.sin6_addr.s6_addr;
4592
}
4593
4594
res = NULL;
4595
for (i=0; i < count; ++i) {
4596
struct evutil_addrinfo *ai;
4597
memcpy(addrp, ((char*)addresses)+i*addrlen, addrlen);
4598
ai = evutil_new_addrinfo_(sa, socklen, &data->hints);
4599
if (!ai) {
4600
if (other_req->r) {
4601
evdns_cancel_request(NULL, other_req->r);
4602
}
4603
data->user_cb(EVUTIL_EAI_MEMORY, NULL, data->user_data);
4604
if (res)
4605
evutil_freeaddrinfo(res);
4606
4607
if (other_req->r == NULL)
4608
free_getaddrinfo_request(data);
4609
return;
4610
}
4611
res = evutil_addrinfo_append_(res, ai);
4612
}
4613
4614
if (other_req->r) {
4615
/* The other request is still in progress; wait for it */
4616
/* XXXX handle failure from set_timeout */
4617
evdns_getaddrinfo_set_timeout(data->evdns_base, data);
4618
data->pending_result = res;
4619
return;
4620
} else {
4621
/* The other request is done or never started; append its
4622
* results (if any) and return them. */
4623
if (data->pending_result) {
4624
if (req->type == DNS_IPv4_A)
4625
res = evutil_addrinfo_append_(res,
4626
data->pending_result);
4627
else
4628
res = evutil_addrinfo_append_(
4629
data->pending_result, res);
4630
data->pending_result = NULL;
4631
}
4632
4633
/* Call the user callback. */
4634
add_cname_to_reply(data, res);
4635
data->user_cb(0, res, data->user_data);
4636
4637
/* Free data. */
4638
free_getaddrinfo_request(data);
4639
}
4640
}
4641
4642
static struct hosts_entry *
4643
find_hosts_entry(struct evdns_base *base, const char *hostname,
4644
struct hosts_entry *find_after)
4645
{
4646
struct hosts_entry *e;
4647
4648
if (find_after)
4649
e = TAILQ_NEXT(find_after, next);
4650
else
4651
e = TAILQ_FIRST(&base->hostsdb);
4652
4653
for (; e; e = TAILQ_NEXT(e, next)) {
4654
if (!evutil_ascii_strcasecmp(e->hostname, hostname))
4655
return e;
4656
}
4657
return NULL;
4658
}
4659
4660
static int
4661
evdns_getaddrinfo_fromhosts(struct evdns_base *base,
4662
const char *nodename, struct evutil_addrinfo *hints, ev_uint16_t port,
4663
struct evutil_addrinfo **res)
4664
{
4665
int n_found = 0;
4666
struct hosts_entry *e;
4667
struct evutil_addrinfo *ai=NULL;
4668
int f = hints->ai_family;
4669
4670
EVDNS_LOCK(base);
4671
for (e = find_hosts_entry(base, nodename, NULL); e;
4672
e = find_hosts_entry(base, nodename, e)) {
4673
struct evutil_addrinfo *ai_new;
4674
++n_found;
4675
if ((e->addr.sa.sa_family == AF_INET && f == PF_INET6) ||
4676
(e->addr.sa.sa_family == AF_INET6 && f == PF_INET))
4677
continue;
4678
ai_new = evutil_new_addrinfo_(&e->addr.sa, e->addrlen, hints);
4679
if (!ai_new) {
4680
n_found = 0;
4681
goto out;
4682
}
4683
sockaddr_setport(ai_new->ai_addr, port);
4684
ai = evutil_addrinfo_append_(ai, ai_new);
4685
}
4686
EVDNS_UNLOCK(base);
4687
out:
4688
if (n_found) {
4689
/* Note that we return an empty answer if we found entries for
4690
* this hostname but none were of the right address type. */
4691
*res = ai;
4692
return 0;
4693
} else {
4694
if (ai)
4695
evutil_freeaddrinfo(ai);
4696
return -1;
4697
}
4698
}
4699
4700
struct evdns_getaddrinfo_request *
4701
evdns_getaddrinfo(struct evdns_base *dns_base,
4702
const char *nodename, const char *servname,
4703
const struct evutil_addrinfo *hints_in,
4704
evdns_getaddrinfo_cb cb, void *arg)
4705
{
4706
struct evdns_getaddrinfo_request *data;
4707
struct evutil_addrinfo hints;
4708
struct evutil_addrinfo *res = NULL;
4709
int err;
4710
int port = 0;
4711
int want_cname = 0;
4712
int started = 0;
4713
4714
if (!dns_base) {
4715
dns_base = current_base;
4716
if (!dns_base) {
4717
log(EVDNS_LOG_WARN,
4718
"Call to getaddrinfo_async with no "
4719
"evdns_base configured.");
4720
cb(EVUTIL_EAI_FAIL, NULL, arg); /* ??? better error? */
4721
return NULL;
4722
}
4723
}
4724
4725
/* If we _must_ answer this immediately, do so. */
4726
if ((hints_in && (hints_in->ai_flags & EVUTIL_AI_NUMERICHOST))) {
4727
res = NULL;
4728
err = evutil_getaddrinfo(nodename, servname, hints_in, &res);
4729
cb(err, res, arg);
4730
return NULL;
4731
}
4732
4733
if (hints_in) {
4734
memcpy(&hints, hints_in, sizeof(hints));
4735
} else {
4736
memset(&hints, 0, sizeof(hints));
4737
hints.ai_family = PF_UNSPEC;
4738
}
4739
4740
evutil_adjust_hints_for_addrconfig_(&hints);
4741
4742
/* Now try to see if we _can_ answer immediately. */
4743
/* (It would be nice to do this by calling getaddrinfo directly, with
4744
* AI_NUMERICHOST, on plaforms that have it, but we can't: there isn't
4745
* a reliable way to distinguish the "that wasn't a numeric host!" case
4746
* from any other EAI_NONAME cases.) */
4747
err = evutil_getaddrinfo_common_(nodename, servname, &hints, &res, &port);
4748
if (err != EVUTIL_EAI_NEED_RESOLVE) {
4749
cb(err, res, arg);
4750
return NULL;
4751
}
4752
4753
/* If there is an entry in the hosts file, we should give it now. */
4754
if (!evdns_getaddrinfo_fromhosts(dns_base, nodename, &hints, port, &res)) {
4755
cb(0, res, arg);
4756
return NULL;
4757
}
4758
4759
/* Okay, things are serious now. We're going to need to actually
4760
* launch a request.
4761
*/
4762
data = mm_calloc(1,sizeof(struct evdns_getaddrinfo_request));
4763
if (!data) {
4764
cb(EVUTIL_EAI_MEMORY, NULL, arg);
4765
return NULL;
4766
}
4767
4768
memcpy(&data->hints, &hints, sizeof(data->hints));
4769
data->port = (ev_uint16_t)port;
4770
data->ipv4_request.type = DNS_IPv4_A;
4771
data->ipv6_request.type = DNS_IPv6_AAAA;
4772
data->user_cb = cb;
4773
data->user_data = arg;
4774
data->evdns_base = dns_base;
4775
4776
want_cname = (hints.ai_flags & EVUTIL_AI_CANONNAME);
4777
4778
/* If we are asked for a PF_UNSPEC address, we launch two requests in
4779
* parallel: one for an A address and one for an AAAA address. We
4780
* can't send just one request, since many servers only answer one
4781
* question per DNS request.
4782
*
4783
* Once we have the answer to one request, we allow for a short
4784
* timeout before we report it, to see if the other one arrives. If
4785
* they both show up in time, then we report both the answers.
4786
*
4787
* If too many addresses of one type time out or fail, we should stop
4788
* launching those requests. (XXX we don't do that yet.)
4789
*/
4790
4791
EVDNS_LOCK(dns_base);
4792
4793
if (hints.ai_family != PF_INET6) {
4794
log(EVDNS_LOG_DEBUG, "Sending request for %s on ipv4 as %p",
4795
nodename, &data->ipv4_request);
4796
4797
data->ipv4_request.r = evdns_base_resolve_ipv4(dns_base,
4798
nodename, 0, evdns_getaddrinfo_gotresolve,
4799
&data->ipv4_request);
4800
if (want_cname && data->ipv4_request.r)
4801
data->ipv4_request.r->current_req->put_cname_in_ptr =
4802
&data->cname_result;
4803
}
4804
if (hints.ai_family != PF_INET) {
4805
log(EVDNS_LOG_DEBUG, "Sending request for %s on ipv6 as %p",
4806
nodename, &data->ipv6_request);
4807
4808
data->ipv6_request.r = evdns_base_resolve_ipv6(dns_base,
4809
nodename, 0, evdns_getaddrinfo_gotresolve,
4810
&data->ipv6_request);
4811
if (want_cname && data->ipv6_request.r)
4812
data->ipv6_request.r->current_req->put_cname_in_ptr =
4813
&data->cname_result;
4814
}
4815
4816
evtimer_assign(&data->timeout, dns_base->event_base,
4817
evdns_getaddrinfo_timeout_cb, data);
4818
4819
started = (data->ipv4_request.r || data->ipv6_request.r);
4820
4821
EVDNS_UNLOCK(dns_base);
4822
4823
if (started) {
4824
return data;
4825
} else {
4826
mm_free(data);
4827
cb(EVUTIL_EAI_FAIL, NULL, arg);
4828
return NULL;
4829
}
4830
}
4831
4832
void
4833
evdns_getaddrinfo_cancel(struct evdns_getaddrinfo_request *data)
4834
{
4835
EVDNS_LOCK(data->evdns_base);
4836
if (data->request_done) {
4837
EVDNS_UNLOCK(data->evdns_base);
4838
return;
4839
}
4840
event_del(&data->timeout);
4841
data->user_canceled = 1;
4842
if (data->ipv4_request.r)
4843
evdns_cancel_request(data->evdns_base, data->ipv4_request.r);
4844
if (data->ipv6_request.r)
4845
evdns_cancel_request(data->evdns_base, data->ipv6_request.r);
4846
EVDNS_UNLOCK(data->evdns_base);
4847
}
4848
4849