dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / dnscrypt / src / libevent-modified / evutil.c
blobe681b0654e40e34f2917e0f8e8926965e7b474d3
1 /*
2 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
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.
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.
27 #include "event2/event-config.h"
29 #ifndef _GNU_SOURCE
30 # define _GNU_SOURCE
31 #endif
33 #ifdef WIN32
34 #include <winsock2.h>
35 #include <ws2tcpip.h>
36 #define WIN32_LEAN_AND_MEAN
37 #include <windows.h>
38 #undef WIN32_LEAN_AND_MEAN
39 #include <io.h>
40 #include <tchar.h>
41 #endif
43 #include <sys/types.h>
44 #ifdef _EVENT_HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
46 #endif
47 #ifdef _EVENT_HAVE_SYS_IOCTL_H
48 #include <sys/ioctl.h>
49 #endif
50 #ifdef _EVENT_HAVE_UNISTD_H
51 #include <unistd.h>
52 #endif
53 #ifdef _EVENT_HAVE_FCNTL_H
54 #include <fcntl.h>
55 #endif
56 #ifdef _EVENT_HAVE_STDLIB_H
57 #include <stdlib.h>
58 #endif
59 #include <errno.h>
60 #include <limits.h>
61 #include <stdio.h>
62 #include <string.h>
63 #ifdef _EVENT_HAVE_NETINET_IN_H
64 #include <netinet/in.h>
65 #endif
66 #ifdef _EVENT_HAVE_NETINET_IN6_H
67 #include <netinet/in6.h>
68 #endif
69 #ifdef _EVENT_HAVE_ARPA_INET_H
70 #include <arpa/inet.h>
71 #endif
73 #ifndef _EVENT_HAVE_GETTIMEOFDAY
74 #include <sys/timeb.h>
75 #include <time.h>
76 #endif
77 #include <sys/stat.h>
79 #include "event2/util.h"
80 #include "util-internal.h"
81 #include "log-internal.h"
82 #include "mm-internal.h"
84 #include "strlcpy-internal.h"
85 #include "ipv6-internal.h"
87 #ifdef WIN32
88 #define open _open
89 #define read _read
90 #define close _close
91 #define fstat _fstati64
92 #define stat _stati64
93 #define mode_t int
94 #endif
96 int
97 evutil_open_closeonexec(const char *pathname, int flags, unsigned mode)
99 int fd;
101 #ifdef O_CLOEXEC
102 flags |= O_CLOEXEC;
103 #endif
105 if (flags & O_CREAT)
106 fd = open(pathname, flags, (mode_t)mode);
107 else
108 fd = open(pathname, flags);
109 if (fd < 0)
110 return -1;
112 #if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
113 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
114 return -1;
115 #endif
117 return fd;
121 Read the contents of 'filename' into a newly allocated NUL-terminated
122 string. Set *content_out to hold this string, and *len_out to hold its
123 length (not including the appended NUL). If 'is_binary', open the file in
124 binary mode.
126 Returns 0 on success, -1 if the open fails, and -2 for all other failures.
128 Used internally only; may go away in a future version.
131 evutil_read_file(const char *filename, char **content_out, size_t *len_out,
132 int is_binary)
134 int fd, r;
135 struct stat st;
136 char *mem;
137 size_t read_so_far=0;
138 int mode = O_RDONLY;
140 EVUTIL_ASSERT(content_out);
141 EVUTIL_ASSERT(len_out);
142 *content_out = NULL;
143 *len_out = 0;
145 #ifdef O_BINARY
146 if (is_binary)
147 mode |= O_BINARY;
148 #endif
150 fd = evutil_open_closeonexec(filename, mode, 0);
151 if (fd < 0)
152 return -1;
153 if (fstat(fd, &st) || st.st_size < 0 ||
154 st.st_size > EV_SSIZE_MAX-1 ) {
155 close(fd);
156 return -2;
158 mem = mm_malloc((size_t)st.st_size + 1);
159 if (!mem) {
160 close(fd);
161 return -2;
163 read_so_far = 0;
164 #ifdef WIN32
165 #define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
166 #else
167 #define N_TO_READ(x) (x)
168 #endif
169 while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) {
170 read_so_far += r;
171 if (read_so_far >= (size_t)st.st_size)
172 break;
173 EVUTIL_ASSERT(read_so_far < (size_t)st.st_size);
175 close(fd);
176 if (r < 0) {
177 mm_free(mem);
178 return -2;
180 mem[read_so_far] = 0;
182 *len_out = read_so_far;
183 *content_out = mem;
184 return 0;
188 evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
190 #ifndef WIN32
191 return socketpair(family, type, protocol, fd);
192 #else
193 return evutil_ersatz_socketpair(family, type, protocol, fd);
194 #endif
198 evutil_ersatz_socketpair(int family, int type, int protocol,
199 evutil_socket_t fd[2])
201 /* This code is originally from Tor. Used with permission. */
203 /* This socketpair does not work when localhost is down. So
204 * it's really not the same thing at all. But it's close enough
205 * for now, and really, when localhost is down sometimes, we
206 * have other problems too.
208 #ifdef WIN32
209 #define ERR(e) WSA##e
210 #else
211 #define ERR(e) e
212 #endif
213 evutil_socket_t listener = -1;
214 evutil_socket_t connector = -1;
215 evutil_socket_t acceptor = -1;
216 struct sockaddr_in listen_addr;
217 struct sockaddr_in connect_addr;
218 ev_socklen_t size;
219 int saved_errno = -1;
221 if (protocol
222 || (family != AF_INET
223 #ifdef AF_UNIX
224 && family != AF_UNIX
225 #endif
226 )) {
227 EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
228 return -1;
230 if (!fd) {
231 EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
232 return -1;
235 listener = socket(AF_INET, type, 0);
236 if (listener < 0)
237 return -1;
238 memset(&listen_addr, 0, sizeof(listen_addr));
239 listen_addr.sin_family = AF_INET;
240 listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
241 listen_addr.sin_port = 0; /* kernel chooses port. */
242 if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
243 == -1)
244 goto tidy_up_and_fail;
245 if (listen(listener, 1) == -1)
246 goto tidy_up_and_fail;
248 connector = socket(AF_INET, type, 0);
249 if (connector < 0)
250 goto tidy_up_and_fail;
251 /* We want to find out the port number to connect to. */
252 size = sizeof(connect_addr);
253 if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
254 goto tidy_up_and_fail;
255 if (size != sizeof (connect_addr))
256 goto abort_tidy_up_and_fail;
257 if (connect(connector, (struct sockaddr *) &connect_addr,
258 sizeof(connect_addr)) == -1)
259 goto tidy_up_and_fail;
261 size = sizeof(listen_addr);
262 acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
263 if (acceptor < 0)
264 goto tidy_up_and_fail;
265 if (size != sizeof(listen_addr))
266 goto abort_tidy_up_and_fail;
267 /* Now check we are talking to ourself by matching port and host on the
268 two sockets. */
269 if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
270 goto tidy_up_and_fail;
271 if (size != sizeof (connect_addr)
272 || listen_addr.sin_family != connect_addr.sin_family
273 || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
274 || listen_addr.sin_port != connect_addr.sin_port)
275 goto abort_tidy_up_and_fail;
276 evutil_closesocket(listener);
277 fd[0] = connector;
278 fd[1] = acceptor;
280 return 0;
282 abort_tidy_up_and_fail:
283 saved_errno = ERR(ECONNABORTED);
284 tidy_up_and_fail:
285 if (saved_errno < 0)
286 saved_errno = EVUTIL_SOCKET_ERROR();
287 if (listener != -1)
288 evutil_closesocket(listener);
289 if (connector != -1)
290 evutil_closesocket(connector);
291 if (acceptor != -1)
292 evutil_closesocket(acceptor);
294 EVUTIL_SET_SOCKET_ERROR(saved_errno);
295 return -1;
296 #undef ERR
300 evutil_make_socket_nonblocking(evutil_socket_t fd)
302 #ifdef WIN32
304 u_long nonblocking = 1;
305 if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
306 event_sock_warn(fd, "fcntl(%d, F_GETFL)", (int)fd);
307 return -1;
310 #elif defined(FIONBIO)
312 int nonblocking = 1;
313 if (ioctl(fd, FIONBIO, &nonblocking) != 0) {
314 event_warn("ioctl(%d, FIONBIO, 1)", fd);
315 return -1;
318 #else
320 int flags;
321 if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
322 event_warn("fcntl(%d, F_GETFL)", fd);
323 return -1;
325 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
326 event_warn("fcntl(%d, F_SETFL)", fd);
327 return -1;
330 #endif
331 return 0;
335 evutil_make_listen_socket_reuseable(evutil_socket_t sock)
337 #ifndef WIN32
338 int one = 1;
339 /* REUSEADDR on Unix means, "don't hang on to this address after the
340 * listener is closed." On Windows, though, it means "don't keep other
341 * processes from binding to this address while we're using it. */
342 return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
343 (ev_socklen_t)sizeof(one));
344 #else
345 return 0;
346 #endif
350 evutil_make_socket_closeonexec(evutil_socket_t fd)
352 #if !defined(WIN32)
353 # ifdef FIOCLEX
354 if (ioctl(fd, FIOCLEX, NULL) != 0) {
355 event_warn("ioctl(%d, FIOCLEX, NULL)", fd);
356 return -1;
358 # elif defined(_EVENT_HAVE_SETFD)
359 int flags;
360 if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
361 event_warn("fcntl(%d, F_GETFD)", fd);
362 return -1;
364 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
365 event_warn("fcntl(%d, F_SETFD)", fd);
366 return -1;
368 # endif
369 #endif
370 return 0;
374 evutil_closesocket(evutil_socket_t sock)
376 #ifndef WIN32
377 return close(sock);
378 #else
379 return closesocket(sock);
380 #endif
383 ev_int64_t
384 evutil_strtoll(const char *s, char **endptr, int base)
386 #ifdef _EVENT_HAVE_STRTOLL
387 return (ev_int64_t)strtoll(s, endptr, base);
388 #elif _EVENT_SIZEOF_LONG == 8
389 return (ev_int64_t)strtol(s, endptr, base);
390 #elif defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
391 /* XXXX on old versions of MS APIs, we only support base
392 * 10. */
393 ev_int64_t r;
394 if (base != 10)
395 return 0;
396 r = (ev_int64_t) _atoi64(s);
397 while (isspace(*s))
398 ++s;
399 if (*s == '-')
400 ++s;
401 while (isdigit(*s))
402 ++s;
403 if (endptr)
404 *endptr = (char*) s;
405 return r;
406 #elif defined(WIN32)
407 return (ev_int64_t) _strtoi64(s, endptr, base);
408 #elif defined(_EVENT_SIZEOF_LONG_LONG) && _EVENT_SIZEOF_LONG_LONG == 8
409 long long r;
410 int n;
411 if (base != 10 && base != 16)
412 return 0;
413 if (base == 10) {
414 n = sscanf(s, "%lld", &r);
415 } else {
416 unsigned long long ru=0;
417 n = sscanf(s, "%llx", &ru);
418 if (ru > EV_INT64_MAX)
419 return 0;
420 r = (long long) ru;
422 if (n != 1)
423 return 0;
424 while (EVUTIL_ISSPACE(*s))
425 ++s;
426 if (*s == '-')
427 ++s;
428 if (base == 10) {
429 while (EVUTIL_ISDIGIT(*s))
430 ++s;
431 } else {
432 while (EVUTIL_ISXDIGIT(*s))
433 ++s;
435 if (endptr)
436 *endptr = (char*) s;
437 return r;
438 #else
439 #error "I don't know how to parse 64-bit integers."
440 #endif
443 #ifndef _EVENT_HAVE_GETTIMEOFDAY
444 /* No gettimeofday; this muse be windows. */
446 evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
448 struct _timeb tb;
450 if (tv == NULL)
451 return -1;
453 /* XXXX
454 * _ftime is not the greatest interface here; GetSystemTimeAsFileTime
455 * would give us better resolution, whereas something cobbled together
456 * with GetTickCount could maybe give us monotonic behavior.
458 * Either way, I think this value might be skewed to ignore the
459 * timezone, and just return local time. That's not so good.
461 _ftime(&tb);
462 tv->tv_sec = (long) tb.time;
463 tv->tv_usec = ((int) tb.millitm) * 1000;
464 return 0;
466 #endif
468 #ifdef WIN32
470 evutil_socket_geterror(evutil_socket_t sock)
472 int optval, optvallen=sizeof(optval);
473 int err = WSAGetLastError();
474 if (err == WSAEWOULDBLOCK && sock >= 0) {
475 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
476 &optvallen))
477 return err;
478 if (optval)
479 return optval;
481 return err;
483 #endif
485 /* XXX we should use an enum here. */
486 /* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
488 evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen)
490 int made_fd = 0;
492 if (*fd_ptr < 0) {
493 if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
494 goto err;
495 made_fd = 1;
496 if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
497 goto err;
501 if (connect(*fd_ptr, sa, socklen) < 0) {
502 int e = evutil_socket_geterror(*fd_ptr);
503 if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
504 return 0;
505 if (EVUTIL_ERR_CONNECT_REFUSED(e))
506 return 2;
507 goto err;
508 } else {
509 return 1;
512 err:
513 if (made_fd) {
514 evutil_closesocket(*fd_ptr);
515 *fd_ptr = -1;
517 return -1;
520 /* Check whether a socket on which we called connect() is done
521 connecting. Return 1 for connected, 0 for not yet, -1 for error. In the
522 error case, set the current socket errno to the error that happened during
523 the connect operation. */
525 evutil_socket_finished_connecting(evutil_socket_t fd)
527 int e;
528 ev_socklen_t elen = sizeof(e);
530 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
531 return -1;
533 if (e) {
534 if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
535 return 0;
536 EVUTIL_SET_SOCKET_ERROR(e);
537 return -1;
540 return 1;
543 #if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
544 EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
545 EVUTIL_AI_ADDRCONFIG) != \
546 (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
547 EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
548 EVUTIL_AI_ADDRCONFIG)
549 #error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
550 #endif
552 /* We sometimes need to know whether we have an ipv4 address and whether we
553 have an ipv6 address. If 'have_checked_interfaces', then we've already done
554 the test. If 'had_ipv4_address', then it turns out we had an ipv4 address.
555 If 'had_ipv6_address', then it turns out we had an ipv6 address. These are
556 set by evutil_check_interfaces. */
557 static int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
559 /* Macro: True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8
561 #define EVUTIL_V4ADDR_IS_LOCALHOST(addr) (((addr)>>24) == 127)
563 /* Macro: True iff the IPv4 address 'addr', in host order, is a class D
564 * (multiclass) address.
566 #define EVUTIL_V4ADDR_IS_CLASSD(addr) ((((addr)>>24) & 0xf0) == 0xe0)
568 /* Test whether we have an ipv4 interface and an ipv6 interface. Return 0 if
569 * the test seemed successful. */
570 static int
571 evutil_check_interfaces(int force_recheck)
573 const char ZEROES[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
574 "\x00\x00\x00\x00\x00\x00\x00\x00";
575 evutil_socket_t fd = -1;
576 struct sockaddr_in sin, sin_out;
577 struct sockaddr_in6 sin6, sin6_out;
578 ev_socklen_t sin_out_len = sizeof(sin_out);
579 ev_socklen_t sin6_out_len = sizeof(sin6_out);
580 int r;
581 char buf[128];
582 if (have_checked_interfaces && !force_recheck)
583 return 0;
585 /* To check whether we have an interface open for a given protocol, we
586 * try to make a UDP 'connection' to a remote host on the internet.
587 * We don't actually use it, so the address doesn't matter, but we
588 * want to pick one that keep us from using a host- or link-local
589 * interface. */
590 memset(&sin, 0, sizeof(sin));
591 sin.sin_family = AF_INET;
592 sin.sin_port = htons(53);
593 r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
594 EVUTIL_ASSERT(r);
596 memset(&sin6, 0, sizeof(sin6));
597 sin6.sin6_family = AF_INET6;
598 sin6.sin6_port = htons(53);
599 r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
600 EVUTIL_ASSERT(r);
602 memset(&sin_out, 0, sizeof(sin_out));
603 memset(&sin6_out, 0, sizeof(sin6_out));
605 /* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
606 if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
607 connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
608 getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
609 /* We might have an IPv4 interface. */
610 ev_uint32_t addr = ntohl(sin_out.sin_addr.s_addr);
611 if (addr == 0 ||
612 EVUTIL_V4ADDR_IS_LOCALHOST(addr) ||
613 EVUTIL_V4ADDR_IS_CLASSD(addr)) {
614 evutil_inet_ntop(AF_INET, &sin_out.sin_addr,
615 buf, sizeof(buf));
616 /* This is a reserved, ipv4compat, ipv4map, loopback,
617 * link-local or unspecified address. The host should
618 * never have given it to us; it could never connect
619 * to sin. */
620 event_warnx("Got a strange local ipv4 address %s",buf);
621 } else {
622 event_debug(("Detected an IPv4 interface"));
623 had_ipv4_address = 1;
626 if (fd >= 0)
627 evutil_closesocket(fd);
629 if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
630 connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
631 getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
632 /* We might have an IPv6 interface. */
633 const unsigned char *addr =
634 (unsigned char*)sin6_out.sin6_addr.s6_addr;
635 if (!memcmp(addr, ZEROES, 8) ||
636 (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80)) {
637 /* This is a reserved, ipv4compat, ipv4map, loopback,
638 * link-local or unspecified address. The host should
639 * never have given it to us; it could never connect
640 * to sin6. */
641 evutil_inet_ntop(AF_INET6, &sin6_out.sin6_addr,
642 buf, sizeof(buf));
643 event_warnx("Got a strange local ipv6 address %s",buf);
644 } else {
645 event_debug(("Detected an IPv4 interface"));
646 had_ipv6_address = 1;
650 if (fd >= 0)
651 evutil_closesocket(fd);
653 return 0;
656 /* Internal addrinfo flag. This one is set when we allocate the addrinfo from
657 * inside libevent. Otherwise, the built-in getaddrinfo() function allocated
658 * it, and we should trust what they said.
660 #define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
662 /* Helper: construct a new addrinfo containing the socket address in
663 * 'sa', which must be a sockaddr_in or a sockaddr_in6. Take the
664 * socktype and protocol info from hints. If they weren't set, then
665 * allocate both a TCP and a UDP addrinfo.
667 struct evutil_addrinfo *
668 evutil_new_addrinfo(struct sockaddr *sa, ev_socklen_t socklen,
669 const struct evutil_addrinfo *hints)
671 struct evutil_addrinfo *res;
672 EVUTIL_ASSERT(hints);
674 if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
675 /* Indecisive user! Give them a UDP and a TCP. */
676 struct evutil_addrinfo *r1, *r2;
677 struct evutil_addrinfo tmp;
678 memcpy(&tmp, hints, sizeof(tmp));
679 tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
680 r1 = evutil_new_addrinfo(sa, socklen, &tmp);
681 if (!r1)
682 return NULL;
683 tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
684 r2 = evutil_new_addrinfo(sa, socklen, &tmp);
685 if (!r2) {
686 evutil_freeaddrinfo(r1);
687 return NULL;
689 r1->ai_next = r2;
690 return r1;
693 /* We're going to allocate extra space to hold the sockaddr. */
694 res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
695 if (!res)
696 return NULL;
697 res->ai_addr = (struct sockaddr*)
698 (((char*)res) + sizeof(struct evutil_addrinfo));
699 memcpy(res->ai_addr, sa, socklen);
700 res->ai_addrlen = socklen;
701 res->ai_family = sa->sa_family; /* Same or not? XXX */
702 res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
703 res->ai_socktype = hints->ai_socktype;
704 res->ai_protocol = hints->ai_protocol;
706 return res;
709 /* Append the addrinfo 'append' to the end of 'first', and return the start of
710 * the list. Either element can be NULL, in which case we return the element
711 * that is not NULL. */
712 struct evutil_addrinfo *
713 evutil_addrinfo_append(struct evutil_addrinfo *first,
714 struct evutil_addrinfo *append)
716 struct evutil_addrinfo *ai = first;
717 if (!ai)
718 return append;
719 while (ai->ai_next)
720 ai = ai->ai_next;
721 ai->ai_next = append;
723 return first;
726 static int
727 parse_numeric_servname(const char *servname)
729 int n;
730 char *endptr=NULL;
731 n = (int) strtol(servname, &endptr, 10);
732 if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
733 return n;
734 else
735 return -1;
738 /** Parse a service name in 'servname', which can be a decimal port.
739 * Return the port number, or -1 on error.
741 static int
742 evutil_parse_servname(const char *servname, const char *protocol,
743 const struct evutil_addrinfo *hints)
745 int n = parse_numeric_servname(servname);
746 if (n>=0)
747 return n;
748 #if defined(_EVENT_HAVE_GETSERVBYNAME) || defined(WIN32)
749 if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
750 struct servent *ent = getservbyname(servname, protocol);
751 if (ent) {
752 return ntohs(ent->s_port);
755 #endif
756 return -1;
759 /* Return a string corresponding to a protocol number that we can pass to
760 * getservyname. */
761 static const char *
762 evutil_unparse_protoname(int proto)
764 switch (proto) {
765 case 0:
766 return NULL;
767 case IPPROTO_TCP:
768 return "tcp";
769 case IPPROTO_UDP:
770 return "udp";
771 #ifdef IPPROTO_SCTP
772 case IPPROTO_SCTP:
773 return "sctp";
774 #endif
775 default:
776 #ifdef _EVENT_HAVE_GETPROTOBYNUMBER
778 struct protoent *ent = getprotobynumber(proto);
779 if (ent)
780 return ent->p_name;
782 #endif
783 return NULL;
787 static void
788 evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
790 /* If we can guess the protocol from the socktype, do so. */
791 if (!hints->ai_protocol && hints->ai_socktype) {
792 if (hints->ai_socktype == SOCK_DGRAM)
793 hints->ai_protocol = IPPROTO_UDP;
794 else if (hints->ai_socktype == SOCK_STREAM)
795 hints->ai_protocol = IPPROTO_TCP;
798 /* Set the socktype if it isn't set. */
799 if (!hints->ai_socktype && hints->ai_protocol) {
800 if (hints->ai_protocol == IPPROTO_UDP)
801 hints->ai_socktype = SOCK_DGRAM;
802 else if (hints->ai_protocol == IPPROTO_TCP)
803 hints->ai_socktype = SOCK_STREAM;
804 #ifdef IPPROTO_SCTP
805 else if (hints->ai_protocol == IPPROTO_SCTP)
806 hints->ai_socktype = SOCK_STREAM;
807 #endif
811 #if AF_UNSPEC != PF_UNSPEC
812 #error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
813 #endif
815 /** Implements the part of looking up hosts by name that's common to both
816 * the blocking and nonblocking resolver:
817 * - Adjust 'hints' to have a reasonable socktype and protocol.
818 * - Look up the port based on 'servname', and store it in *portnum,
819 * - Handle the nodename==NULL case
820 * - Handle some invalid arguments cases.
821 * - Handle the cases where nodename is an IPv4 or IPv6 address.
823 * If we need the resolver to look up the hostname, we return
824 * EVUTIL_EAI_NEED_RESOLVE. Otherwise, we can completely implement
825 * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
826 * set *res as getaddrinfo would.
829 evutil_getaddrinfo_common(const char *nodename, const char *servname,
830 struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
832 int port = 0;
833 const char *pname;
835 if (nodename == NULL && servname == NULL)
836 return EVUTIL_EAI_NONAME;
838 /* We only understand 3 families */
839 if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
840 hints->ai_family != PF_INET6)
841 return EVUTIL_EAI_FAMILY;
843 evutil_getaddrinfo_infer_protocols(hints);
845 /* Look up the port number and protocol, if possible. */
846 pname = evutil_unparse_protoname(hints->ai_protocol);
847 if (servname) {
848 /* XXXX We could look at the protocol we got back from
849 * getservbyname, but it doesn't seem too useful. */
850 port = evutil_parse_servname(servname, pname, hints);
851 if (port < 0) {
852 return EVUTIL_EAI_NONAME;
856 /* If we have no node name, then we're supposed to bind to 'any' and
857 * connect to localhost. */
858 if (nodename == NULL) {
859 struct evutil_addrinfo *res4=NULL, *res6=NULL;
860 if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
861 struct sockaddr_in6 sin6;
862 memset(&sin6, 0, sizeof(sin6));
863 sin6.sin6_family = AF_INET6;
864 sin6.sin6_port = htons(port);
865 if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
866 /* Bind to :: */
867 } else {
868 /* connect to ::1 */
869 sin6.sin6_addr.s6_addr[15] = 1;
871 res6 = evutil_new_addrinfo((struct sockaddr*)&sin6,
872 sizeof(sin6), hints);
873 if (!res6)
874 return EVUTIL_EAI_MEMORY;
877 if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
878 struct sockaddr_in sin;
879 memset(&sin, 0, sizeof(sin));
880 sin.sin_family = AF_INET;
881 sin.sin_port = htons(port);
882 if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
883 /* Bind to 0.0.0.0 */
884 } else {
885 /* connect to 127.0.0.1 */
886 sin.sin_addr.s_addr = htonl(0x7f000001);
888 res4 = evutil_new_addrinfo((struct sockaddr*)&sin,
889 sizeof(sin), hints);
890 if (!res4) {
891 if (res6)
892 evutil_freeaddrinfo(res6);
893 return EVUTIL_EAI_MEMORY;
896 *res = evutil_addrinfo_append(res4, res6);
897 return 0;
900 /* If we can, we should try to parse the hostname without resolving
901 * it. */
902 /* Try ipv6. */
903 if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
904 struct sockaddr_in6 sin6;
905 memset(&sin6, 0, sizeof(sin6));
906 if (1==evutil_inet_pton(AF_INET6, nodename, &sin6.sin6_addr)) {
907 /* Got an ipv6 address. */
908 sin6.sin6_family = AF_INET6;
909 sin6.sin6_port = htons(port);
910 *res = evutil_new_addrinfo((struct sockaddr*)&sin6,
911 sizeof(sin6), hints);
912 if (!*res)
913 return EVUTIL_EAI_MEMORY;
914 return 0;
918 /* Try ipv4. */
919 if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
920 struct sockaddr_in sin;
921 memset(&sin, 0, sizeof(sin));
922 if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
923 /* Got an ipv6 address. */
924 sin.sin_family = AF_INET;
925 sin.sin_port = htons(port);
926 *res = evutil_new_addrinfo((struct sockaddr*)&sin,
927 sizeof(sin), hints);
928 if (!*res)
929 return EVUTIL_EAI_MEMORY;
930 return 0;
935 /* If we have reached this point, we definitely need to do a DNS
936 * lookup. */
937 if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
938 /* If we're not allowed to do one, then say so. */
939 return EVUTIL_EAI_NONAME;
941 *portnum = port;
942 return EVUTIL_EAI_NEED_RESOLVE;
945 #ifdef _EVENT_HAVE_GETADDRINFO
946 #define USE_NATIVE_GETADDRINFO
947 #endif
949 #ifdef USE_NATIVE_GETADDRINFO
950 /* A mask of all the flags that we declare, so we can clear them before calling
951 * the native getaddrinfo */
952 static const unsigned int ALL_NONNATIVE_AI_FLAGS =
953 #ifndef AI_PASSIVE
954 EVUTIL_AI_PASSIVE |
955 #endif
956 #ifndef AI_CANONNAME
957 EVUTIL_AI_CANONNAME |
958 #endif
959 #ifndef AI_NUMERICHOST
960 EVUTIL_AI_NUMERICHOST |
961 #endif
962 #ifndef AI_NUMERICSERV
963 EVUTIL_AI_NUMERICSERV |
964 #endif
965 #ifndef AI_ADDRCONFIG
966 EVUTIL_AI_ADDRCONFIG |
967 #endif
968 #ifndef AI_ALL
969 EVUTIL_AI_ALL |
970 #endif
971 #ifndef AI_V4MAPPED
972 EVUTIL_AI_V4MAPPED |
973 #endif
974 EVUTIL_AI_LIBEVENT_ALLOCATED;
976 static const unsigned int ALL_NATIVE_AI_FLAGS =
977 #ifdef AI_PASSIVE
978 AI_PASSIVE |
979 #endif
980 #ifdef AI_CANONNAME
981 AI_CANONNAME |
982 #endif
983 #ifdef AI_NUMERICHOST
984 AI_NUMERICHOST |
985 #endif
986 #ifdef AI_NUMERICSERV
987 AI_NUMERICSERV |
988 #endif
989 #ifdef AI_ADDRCONFIG
990 AI_ADDRCONFIG |
991 #endif
992 #ifdef AI_ALL
993 AI_ALL |
994 #endif
995 #ifdef AI_V4MAPPED
996 AI_V4MAPPED |
997 #endif
999 #endif
1001 #ifndef USE_NATIVE_GETADDRINFO
1002 /* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
1003 * a struct hostent.
1005 static struct evutil_addrinfo *
1006 addrinfo_from_hostent(const struct hostent *ent,
1007 int port, const struct evutil_addrinfo *hints)
1009 int i;
1010 struct sockaddr_in sin;
1011 struct sockaddr_in6 sin6;
1012 struct sockaddr *sa;
1013 int socklen;
1014 struct evutil_addrinfo *res=NULL, *ai;
1015 void *addrp;
1017 if (ent->h_addrtype == PF_INET) {
1018 memset(&sin, 0, sizeof(sin));
1019 sin.sin_family = AF_INET;
1020 sin.sin_port = htons(port);
1021 sa = (struct sockaddr *)&sin;
1022 socklen = sizeof(struct sockaddr_in);
1023 addrp = &sin.sin_addr;
1024 if (ent->h_length != sizeof(sin.sin_addr)) {
1025 event_warnx("Weird h_length from gethostbyname");
1026 return NULL;
1028 } else if (ent->h_addrtype == PF_INET6) {
1029 memset(&sin6, 0, sizeof(sin6));
1030 sin6.sin6_family = AF_INET6;
1031 sin6.sin6_port = htons(port);
1032 sa = (struct sockaddr *)&sin6;
1033 socklen = sizeof(struct sockaddr_in);
1034 addrp = &sin6.sin6_addr;
1035 if (ent->h_length != sizeof(sin6.sin6_addr)) {
1036 event_warnx("Weird h_length from gethostbyname");
1037 return NULL;
1039 } else
1040 return NULL;
1042 for (i = 0; ent->h_addr_list[i]; ++i) {
1043 memcpy(addrp, ent->h_addr_list[i], ent->h_length);
1044 ai = evutil_new_addrinfo(sa, socklen, hints);
1045 if (!ai) {
1046 evutil_freeaddrinfo(res);
1047 return NULL;
1049 res = evutil_addrinfo_append(res, ai);
1052 if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
1053 res->ai_canonname = mm_strdup(ent->h_name);
1054 if (res->ai_canonname == NULL) {
1055 evutil_freeaddrinfo(res);
1056 return NULL;
1060 return res;
1062 #endif
1064 /* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
1065 * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
1066 * that we'll only get addresses we could maybe connect to.
1068 void
1069 evutil_adjust_hints_for_addrconfig(struct evutil_addrinfo *hints)
1071 if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
1072 return;
1073 if (hints->ai_family != PF_UNSPEC)
1074 return;
1075 if (!have_checked_interfaces)
1076 evutil_check_interfaces(0);
1077 if (had_ipv4_address && !had_ipv6_address) {
1078 hints->ai_family = PF_INET;
1079 } else if (!had_ipv4_address && had_ipv6_address) {
1080 hints->ai_family = PF_INET6;
1084 #ifdef USE_NATIVE_GETADDRINFO
1085 static int need_numeric_port_hack_=0;
1086 static int need_socktype_protocol_hack_=0;
1087 static int tested_for_getaddrinfo_hacks=0;
1089 /* Some older BSDs (like OpenBSD up to 4.6) used to believe that
1090 giving a numeric port without giving an ai_socktype was verboten.
1091 We test for this so we can apply an appropriate workaround. If it
1092 turns out that the bug is present, then:
1094 - If nodename==NULL and servname is numeric, we build an answer
1095 ourselves using evutil_getaddrinfo_common().
1097 - If nodename!=NULL and servname is numeric, then we set
1098 servname=NULL when calling getaddrinfo, and post-process the
1099 result to set the ports on it.
1101 We test for this bug at runtime, since otherwise we can't have the
1102 same binary run on multiple BSD versions.
1104 - Some versions of Solaris believe that it's nice to leave to protocol
1105 field set to 0. We test for this so we can apply an appropriate
1106 workaround.
1108 static void
1109 test_for_getaddrinfo_hacks(void)
1111 int r, r2;
1112 struct evutil_addrinfo *ai=NULL, *ai2=NULL;
1113 struct evutil_addrinfo hints;
1115 memset(&hints,0,sizeof(hints));
1116 hints.ai_family = PF_UNSPEC;
1117 hints.ai_flags =
1118 #ifdef AI_NUMERICHOST
1119 AI_NUMERICHOST |
1120 #endif
1121 #ifdef AI_NUMERICSERV
1122 AI_NUMERICSERV |
1123 #endif
1125 r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
1126 hints.ai_socktype = SOCK_STREAM;
1127 r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
1128 if (r2 == 0 && r != 0) {
1129 need_numeric_port_hack_=1;
1131 if (ai2 && ai2->ai_protocol == 0) {
1132 need_socktype_protocol_hack_=1;
1135 if (ai)
1136 freeaddrinfo(ai);
1137 if (ai2)
1138 freeaddrinfo(ai2);
1139 tested_for_getaddrinfo_hacks=1;
1142 static inline int
1143 need_numeric_port_hack(void)
1145 if (!tested_for_getaddrinfo_hacks)
1146 test_for_getaddrinfo_hacks();
1147 return need_numeric_port_hack_;
1150 static inline int
1151 need_socktype_protocol_hack(void)
1153 if (!tested_for_getaddrinfo_hacks)
1154 test_for_getaddrinfo_hacks();
1155 return need_socktype_protocol_hack_;
1158 static void
1159 apply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
1161 /* Now we run through the list and set the ports on all of the
1162 * results where ports would make sense. */
1163 for ( ; *ai; ai = &(*ai)->ai_next) {
1164 struct sockaddr *sa = (*ai)->ai_addr;
1165 if (sa && sa->sa_family == AF_INET) {
1166 struct sockaddr_in *sin = (struct sockaddr_in*)sa;
1167 sin->sin_port = htons(port);
1168 } else if (sa && sa->sa_family == AF_INET6) {
1169 struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
1170 sin6->sin6_port = htons(port);
1171 } else {
1172 /* A numeric port makes no sense here; remove this one
1173 * from the list. */
1174 struct evutil_addrinfo *victim = *ai;
1175 *ai = victim->ai_next;
1176 victim->ai_next = NULL;
1177 freeaddrinfo(victim);
1182 static int
1183 apply_socktype_protocol_hack(struct evutil_addrinfo *ai)
1185 struct evutil_addrinfo *ai_new;
1186 for (; ai; ai = ai->ai_next) {
1187 evutil_getaddrinfo_infer_protocols(ai);
1188 if (ai->ai_socktype || ai->ai_protocol)
1189 continue;
1190 ai_new = mm_malloc(sizeof(*ai_new));
1191 if (!ai_new)
1192 return -1;
1193 memcpy(ai_new, ai, sizeof(*ai_new));
1194 ai->ai_socktype = SOCK_STREAM;
1195 ai->ai_protocol = IPPROTO_TCP;
1196 ai_new->ai_socktype = SOCK_DGRAM;
1197 ai_new->ai_protocol = IPPROTO_UDP;
1199 ai_new->ai_next = ai->ai_next;
1200 ai->ai_next = ai_new;
1202 return 0;
1204 #endif
1207 evutil_getaddrinfo(const char *nodename, const char *servname,
1208 const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
1210 #ifdef USE_NATIVE_GETADDRINFO
1211 struct evutil_addrinfo hints;
1212 int portnum=-1, need_np_hack, err;
1214 if (hints_in) {
1215 memcpy(&hints, hints_in, sizeof(hints));
1216 } else {
1217 memset(&hints, 0, sizeof(hints));
1218 hints.ai_family = PF_UNSPEC;
1221 #ifndef AI_ADDRCONFIG
1222 /* Not every system has AI_ADDRCONFIG, so fake it. */
1223 if (hints.ai_family == PF_UNSPEC &&
1224 (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
1225 evutil_adjust_hints_for_addrconfig(&hints);
1227 #endif
1229 #ifndef AI_NUMERICSERV
1230 /* Not every system has AI_NUMERICSERV, so fake it. */
1231 if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
1232 if (servname && parse_numeric_servname(servname)<0)
1233 return EVUTIL_EAI_NONAME;
1235 #endif
1237 /* Enough operating systems handle enough common non-resolve
1238 * cases here weirdly enough that we are better off just
1239 * overriding them. For example:
1241 * - Windows doesn't like to infer the protocol from the
1242 * socket type, or fill in socket or protocol types much at
1243 * all. It also seems to do its own broken implicit
1244 * always-on version of AI_ADDRCONFIG that keeps it from
1245 * ever resolving even a literal IPv6 address when
1246 * ai_addrtype is PF_UNSPEC.
1248 #ifdef WIN32
1250 int tmp_port;
1251 err = evutil_getaddrinfo_common(nodename,servname,&hints,
1252 res, &tmp_port);
1253 if (err == 0 ||
1254 err == EVUTIL_EAI_MEMORY ||
1255 err == EVUTIL_EAI_NONAME)
1256 return err;
1257 /* If we make it here, the system getaddrinfo can
1258 * have a crack at it. */
1260 #endif
1262 /* See documentation for need_numeric_port_hack above.*/
1263 need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
1264 && ((portnum=parse_numeric_servname(servname)) >= 0);
1265 if (need_np_hack) {
1266 if (!nodename)
1267 return evutil_getaddrinfo_common(
1268 NULL,servname,&hints, res, &portnum);
1269 servname = NULL;
1272 if (need_socktype_protocol_hack()) {
1273 evutil_getaddrinfo_infer_protocols(&hints);
1276 /* Make sure that we didn't actually steal any AI_FLAGS values that
1277 * the system is using. (This is a constant expression, and should ge
1278 * optimized out.)
1280 * XXXX Turn this into a compile-time failure rather than a run-time
1281 * failure.
1283 EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
1285 /* Clear any flags that only libevent understands. */
1286 hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
1288 err = getaddrinfo(nodename, servname, &hints, res);
1289 if (need_np_hack)
1290 apply_numeric_port_hack(portnum, res);
1292 if (need_socktype_protocol_hack()) {
1293 if (apply_socktype_protocol_hack(*res) < 0) {
1294 evutil_freeaddrinfo(*res);
1295 *res = NULL;
1296 return EVUTIL_EAI_MEMORY;
1299 return err;
1300 #else
1301 int port=0, err;
1302 struct hostent *ent = NULL;
1303 struct evutil_addrinfo hints;
1305 if (hints_in) {
1306 memcpy(&hints, hints_in, sizeof(hints));
1307 } else {
1308 memset(&hints, 0, sizeof(hints));
1309 hints.ai_family = PF_UNSPEC;
1312 evutil_adjust_hints_for_addrconfig(&hints);
1314 err = evutil_getaddrinfo_common(nodename, servname, &hints, res, &port);
1315 if (err != EVUTIL_EAI_NEED_RESOLVE) {
1316 /* We either succeeded or failed. No need to continue */
1317 return err;
1320 err = 0;
1321 /* Use any of the various gethostbyname_r variants as available. */
1323 #ifdef _EVENT_HAVE_GETHOSTBYNAME_R_6_ARG
1324 /* This one is what glibc provides. */
1325 char buf[2048];
1326 struct hostent hostent;
1327 int r;
1328 r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
1329 &err);
1330 #elif defined(_EVENT_HAVE_GETHOSTBYNAME_R_5_ARG)
1331 char buf[2048];
1332 struct hostent hostent;
1333 ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
1334 &err);
1335 #elif defined(_EVENT_HAVE_GETHOSTBYNAME_R_3_ARG)
1336 struct hostent_data data;
1337 struct hostent hostent;
1338 memset(&data, 0, sizeof(data));
1339 err = gethostbyname_r(nodename, &hostent, &data);
1340 ent = err ? NULL : &hostent;
1341 #else
1342 /* fall back to gethostbyname. */
1343 /* XXXX This needs a lock everywhere but Windows. */
1344 ent = gethostbyname(nodename);
1345 #ifdef WIN32
1346 err = WSAGetLastError();
1347 #else
1348 err = h_errno;
1349 #endif
1350 #endif
1352 /* Now we have either ent or err set. */
1353 if (!ent) {
1354 /* XXX is this right for windows ? */
1355 switch (err) {
1356 case TRY_AGAIN:
1357 return EVUTIL_EAI_AGAIN;
1358 case NO_RECOVERY:
1359 default:
1360 return EVUTIL_EAI_FAIL;
1361 case HOST_NOT_FOUND:
1362 return EVUTIL_EAI_NONAME;
1363 case NO_ADDRESS:
1364 #if NO_DATA != NO_ADDRESS
1365 case NO_DATA:
1366 #endif
1367 return EVUTIL_EAI_NODATA;
1371 if (ent->h_addrtype != hints.ai_family &&
1372 hints.ai_family != PF_UNSPEC) {
1373 /* This wasn't the type we were hoping for. Too bad
1374 * we never had a chance to ask gethostbyname for what
1375 * we wanted. */
1376 return EVUTIL_EAI_NONAME;
1379 /* Make sure we got _some_ answers. */
1380 if (ent->h_length == 0)
1381 return EVUTIL_EAI_NODATA;
1383 /* If we got an address type we don't know how to make a
1384 sockaddr for, give up. */
1385 if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
1386 return EVUTIL_EAI_FAMILY;
1388 *res = addrinfo_from_hostent(ent, port, &hints);
1389 if (! *res)
1390 return EVUTIL_EAI_MEMORY;
1393 return 0;
1394 #endif
1397 void
1398 evutil_freeaddrinfo(struct evutil_addrinfo *ai)
1400 #ifdef _EVENT_HAVE_GETADDRINFO
1401 if (!(ai->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED)) {
1402 freeaddrinfo(ai);
1403 return;
1405 #endif
1406 while (ai) {
1407 struct evutil_addrinfo *next = ai->ai_next;
1408 if (ai->ai_canonname)
1409 mm_free(ai->ai_canonname);
1410 mm_free(ai);
1411 ai = next;
1415 static evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
1417 void
1418 evutil_set_evdns_getaddrinfo_fn(evdns_getaddrinfo_fn fn)
1420 if (!evdns_getaddrinfo_impl)
1421 evdns_getaddrinfo_impl = fn;
1424 /* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
1425 * otherwise do a blocking resolve and pass the result to the callback in the
1426 * way that evdns_getaddrinfo would.
1429 evutil_getaddrinfo_async(struct evdns_base *dns_base,
1430 const char *nodename, const char *servname,
1431 const struct evutil_addrinfo *hints_in,
1432 void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
1434 if (dns_base && evdns_getaddrinfo_impl) {
1435 evdns_getaddrinfo_impl(
1436 dns_base, nodename, servname, hints_in, cb, arg);
1437 } else {
1438 struct evutil_addrinfo *ai=NULL;
1439 int err;
1440 err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
1441 cb(err, ai, arg);
1443 return 0;
1446 const char *
1447 evutil_gai_strerror(int err)
1449 /* As a sneaky side-benefit, this case statement will get most
1450 * compilers to tell us if any of the error codes we defined
1451 * conflict with the platform's native error codes. */
1452 switch (err) {
1453 case EVUTIL_EAI_CANCEL:
1454 return "Request canceled";
1455 case 0:
1456 return "No error";
1458 case EVUTIL_EAI_ADDRFAMILY:
1459 return "address family for nodename not supported";
1460 case EVUTIL_EAI_AGAIN:
1461 return "temporary failure in name resolution";
1462 case EVUTIL_EAI_BADFLAGS:
1463 return "invalid value for ai_flags";
1464 case EVUTIL_EAI_FAIL:
1465 return "non-recoverable failure in name resolution";
1466 case EVUTIL_EAI_FAMILY:
1467 return "ai_family not supported";
1468 case EVUTIL_EAI_MEMORY:
1469 return "memory allocation failure";
1470 case EVUTIL_EAI_NODATA:
1471 return "no address associated with nodename";
1472 case EVUTIL_EAI_NONAME:
1473 return "nodename nor servname provided, or not known";
1474 case EVUTIL_EAI_SERVICE:
1475 return "servname not supported for ai_socktype";
1476 case EVUTIL_EAI_SOCKTYPE:
1477 return "ai_socktype not supported";
1478 case EVUTIL_EAI_SYSTEM:
1479 return "system error";
1480 default:
1481 #if defined(USE_NATIVE_GETADDRINFO) && defined(WIN32)
1482 return gai_strerrorA(err);
1483 #elif defined(USE_NATIVE_GETADDRINFO)
1484 return gai_strerror(err);
1485 #else
1486 return "Unknown error code";
1487 #endif
1491 #ifdef WIN32
1492 #define E(code, s) { code, (s " [" #code " ]") }
1493 static struct { int code; const char *msg; } windows_socket_errors[] = {
1494 E(WSAEINTR, "Interrupted function call"),
1495 E(WSAEACCES, "Permission denied"),
1496 E(WSAEFAULT, "Bad address"),
1497 E(WSAEINVAL, "Invalid argument"),
1498 E(WSAEMFILE, "Too many open files"),
1499 E(WSAEWOULDBLOCK, "Resource temporarily unavailable"),
1500 E(WSAEINPROGRESS, "Operation now in progress"),
1501 E(WSAEALREADY, "Operation already in progress"),
1502 E(WSAENOTSOCK, "Socket operation on nonsocket"),
1503 E(WSAEDESTADDRREQ, "Destination address required"),
1504 E(WSAEMSGSIZE, "Message too long"),
1505 E(WSAEPROTOTYPE, "Protocol wrong for socket"),
1506 E(WSAENOPROTOOPT, "Bad protocol option"),
1507 E(WSAEPROTONOSUPPORT, "Protocol not supported"),
1508 E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
1509 /* What's the difference between NOTSUPP and NOSUPPORT? :) */
1510 E(WSAEOPNOTSUPP, "Operation not supported"),
1511 E(WSAEPFNOSUPPORT, "Protocol family not supported"),
1512 E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
1513 E(WSAEADDRINUSE, "Address already in use"),
1514 E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
1515 E(WSAENETDOWN, "Network is down"),
1516 E(WSAENETUNREACH, "Network is unreachable"),
1517 E(WSAENETRESET, "Network dropped connection on reset"),
1518 E(WSAECONNABORTED, "Software caused connection abort"),
1519 E(WSAECONNRESET, "Connection reset by peer"),
1520 E(WSAENOBUFS, "No buffer space available"),
1521 E(WSAEISCONN, "Socket is already connected"),
1522 E(WSAENOTCONN, "Socket is not connected"),
1523 E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
1524 E(WSAETIMEDOUT, "Connection timed out"),
1525 E(WSAECONNREFUSED, "Connection refused"),
1526 E(WSAEHOSTDOWN, "Host is down"),
1527 E(WSAEHOSTUNREACH, "No route to host"),
1528 E(WSAEPROCLIM, "Too many processes"),
1530 /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
1531 E(WSASYSNOTREADY, "Network subsystem is unavailable"),
1532 E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
1533 E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
1534 E(WSAEDISCON, "Graceful shutdown now in progress"),
1535 #ifdef WSATYPE_NOT_FOUND
1536 E(WSATYPE_NOT_FOUND, "Class type not found"),
1537 #endif
1538 E(WSAHOST_NOT_FOUND, "Host not found"),
1539 E(WSATRY_AGAIN, "Nonauthoritative host not found"),
1540 E(WSANO_RECOVERY, "This is a nonrecoverable error"),
1541 E(WSANO_DATA, "Valid name, no data record of requested type)"),
1543 /* There are some more error codes whose numeric values are marked
1544 * <b>OS dependent</b>. They start with WSA_, apparently for the same
1545 * reason that practitioners of some craft traditions deliberately
1546 * introduce imperfections into their baskets and rugs "to allow the
1547 * evil spirits to escape." If we catch them, then our binaries
1548 * might not report consistent results across versions of Windows.
1549 * Thus, I'm going to let them all fall through.
1551 { -1, NULL },
1553 #undef E
1554 /** Equivalent to strerror, but for windows socket errors. */
1555 const char *
1556 evutil_socket_error_to_string(int errcode)
1558 /* XXXX Is there really no built-in function to do this? */
1559 int i;
1560 for (i=0; windows_socket_errors[i].code >= 0; ++i) {
1561 if (errcode == windows_socket_errors[i].code)
1562 return windows_socket_errors[i].msg;
1564 return strerror(errcode);
1566 #endif
1569 evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
1571 int r;
1572 va_list ap;
1573 va_start(ap, format);
1574 r = evutil_vsnprintf(buf, buflen, format, ap);
1575 va_end(ap);
1576 return r;
1580 evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
1582 int r;
1583 if (!buflen)
1584 return 0;
1585 #ifdef _MSC_VER
1586 r = _vsnprintf(buf, buflen, format, ap);
1587 if (r < 0)
1588 r = _vscprintf(format, ap);
1589 #elif defined(sgi)
1590 /* Make sure we always use the correct vsnprintf on IRIX */
1591 extern int _xpg5_vsnprintf(char * __restrict,
1592 __SGI_LIBC_NAMESPACE_QUALIFIER size_t,
1593 const char * __restrict, /* va_list */ char *);
1595 r = _xpg5_vsnprintf(buf, buflen, format, ap);
1596 #else
1597 r = vsnprintf(buf, buflen, format, ap);
1598 #endif
1599 buf[buflen-1] = '\0';
1600 return r;
1603 #define USE_INTERNAL_NTOP
1604 #define USE_INTERNAL_PTON
1606 const char *
1607 evutil_inet_ntop(int af, const void *src, char *dst, size_t len)
1609 #if defined(_EVENT_HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
1610 return inet_ntop(af, src, dst, len);
1611 #else
1612 if (af == AF_INET) {
1613 const struct in_addr *in = src;
1614 const ev_uint32_t a = ntohl(in->s_addr);
1615 int r;
1616 r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
1617 (int)(ev_uint8_t)((a>>24)&0xff),
1618 (int)(ev_uint8_t)((a>>16)&0xff),
1619 (int)(ev_uint8_t)((a>>8 )&0xff),
1620 (int)(ev_uint8_t)((a )&0xff));
1621 if (r<0||(size_t)r>=len)
1622 return NULL;
1623 else
1624 return dst;
1625 #ifdef AF_INET6
1626 } else if (af == AF_INET6) {
1627 const struct in6_addr *addr = src;
1628 char buf[64], *cp;
1629 int longestGapLen = 0, longestGapPos = -1, i,
1630 curGapPos = -1, curGapLen = 0;
1631 ev_uint16_t words[8];
1632 for (i = 0; i < 8; ++i) {
1633 words[i] =
1634 (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
1636 if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
1637 words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
1638 (words[5] == 0xffff))) {
1639 /* This is an IPv4 address. */
1640 if (words[5] == 0) {
1641 evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
1642 addr->s6_addr[12], addr->s6_addr[13],
1643 addr->s6_addr[14], addr->s6_addr[15]);
1644 } else {
1645 evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
1646 addr->s6_addr[12], addr->s6_addr[13],
1647 addr->s6_addr[14], addr->s6_addr[15]);
1649 if (strlen(buf) > len)
1650 return NULL;
1651 strlcpy(dst, buf, len);
1652 return dst;
1654 i = 0;
1655 while (i < 8) {
1656 if (words[i] == 0) {
1657 curGapPos = i++;
1658 curGapLen = 1;
1659 while (i<8 && words[i] == 0) {
1660 ++i; ++curGapLen;
1662 if (curGapLen > longestGapLen) {
1663 longestGapPos = curGapPos;
1664 longestGapLen = curGapLen;
1666 } else {
1667 ++i;
1670 if (longestGapLen<=1)
1671 longestGapPos = -1;
1673 cp = buf;
1674 for (i = 0; i < 8; ++i) {
1675 if (words[i] == 0 && longestGapPos == i) {
1676 if (i == 0)
1677 *cp++ = ':';
1678 *cp++ = ':';
1679 while (i < 8 && words[i] == 0)
1680 ++i;
1681 --i; /* to compensate for loop increment. */
1682 } else {
1683 evutil_snprintf(cp,
1684 sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
1685 cp += strlen(cp);
1686 if (i != 7)
1687 *cp++ = ':';
1690 *cp = '\0';
1691 if (strlen(buf) > len)
1692 return NULL;
1693 strlcpy(dst, buf, len);
1694 return dst;
1695 #endif
1696 } else {
1697 return NULL;
1699 #endif
1703 evutil_inet_pton(int af, const char *src, void *dst)
1705 #if defined(_EVENT_HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
1706 return inet_pton(af, src, dst);
1707 #else
1708 if (af == AF_INET) {
1709 int a,b,c,d;
1710 char more;
1711 struct in_addr *addr = dst;
1712 if (sscanf(src, "%d.%d.%d.%d%c", &a,&b,&c,&d,&more) != 4)
1713 return 0;
1714 if (a < 0 || a > 255) return 0;
1715 if (b < 0 || b > 255) return 0;
1716 if (c < 0 || c > 255) return 0;
1717 if (d < 0 || d > 255) return 0;
1718 addr->s_addr = htonl((((ev_uint32_t) a)<<24) | (b<<16) | (c<<8) | d);
1719 return 1;
1720 #ifdef AF_INET6
1721 } else if (af == AF_INET6) {
1722 struct in6_addr *out = dst;
1723 ev_uint16_t words[8];
1724 int gapPos = -1, i, setWords=0;
1725 const char *dot = strchr(src, '.');
1726 const char *eow; /* end of words. */
1727 if (dot == src)
1728 return 0;
1729 else if (!dot)
1730 eow = src+strlen(src);
1731 else {
1732 int byte1,byte2,byte3,byte4;
1733 char more;
1734 for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT(*eow); --eow)
1736 ++eow;
1738 /* We use "scanf" because some platform inet_aton()s are too lax
1739 * about IPv4 addresses of the form "1.2.3" */
1740 if (sscanf(eow, "%d.%d.%d.%d%c",
1741 &byte1,&byte2,&byte3,&byte4,&more) != 4)
1742 return 0;
1744 if (byte1 > 255 || byte1 < 0 ||
1745 byte2 > 255 || byte2 < 0 ||
1746 byte3 > 255 || byte3 < 0 ||
1747 byte4 > 255 || byte4 < 0)
1748 return 0;
1750 words[6] = (byte1<<8) | byte2;
1751 words[7] = (byte3<<8) | byte4;
1752 setWords += 2;
1755 i = 0;
1756 while (src < eow) {
1757 if (i > 7)
1758 return 0;
1759 if (EVUTIL_ISXDIGIT(*src)) {
1760 char *next;
1761 long r = strtol(src, &next, 16);
1762 if (next > 4+src)
1763 return 0;
1764 if (next == src)
1765 return 0;
1766 if (r<0 || r>65536)
1767 return 0;
1769 words[i++] = (ev_uint16_t)r;
1770 setWords++;
1771 src = next;
1772 if (*src != ':' && src != eow)
1773 return 0;
1774 ++src;
1775 } else if (*src == ':' && i > 0 && gapPos==-1) {
1776 gapPos = i;
1777 ++src;
1778 } else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
1779 gapPos = i;
1780 src += 2;
1781 } else {
1782 return 0;
1786 if (setWords > 8 ||
1787 (setWords == 8 && gapPos != -1) ||
1788 (setWords < 8 && gapPos == -1))
1789 return 0;
1791 if (gapPos >= 0) {
1792 int nToMove = setWords - (dot ? 2 : 0) - gapPos;
1793 int gapLen = 8 - setWords;
1794 /* assert(nToMove >= 0); */
1795 if (nToMove < 0)
1796 return -1; /* should be impossible */
1797 memmove(&words[gapPos+gapLen], &words[gapPos],
1798 sizeof(ev_uint16_t)*nToMove);
1799 memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
1801 for (i = 0; i < 8; ++i) {
1802 out->s6_addr[2*i ] = words[i] >> 8;
1803 out->s6_addr[2*i+1] = words[i] & 0xff;
1806 return 1;
1807 #endif
1808 } else {
1809 return -1;
1811 #endif
1815 evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
1817 int port;
1818 char buf[128];
1819 const char *cp, *addr_part, *port_part;
1820 int is_ipv6;
1821 /* recognized formats are:
1822 * [ipv6]:port
1823 * ipv6
1824 * [ipv6]
1825 * ipv4:port
1826 * ipv4
1829 cp = strchr(ip_as_string, ':');
1830 if (*ip_as_string == '[') {
1831 int len;
1832 if (!(cp = strchr(ip_as_string, ']'))) {
1833 return -1;
1835 len = (int) ( cp-(ip_as_string + 1) );
1836 if (len > (int)sizeof(buf)-1) {
1837 return -1;
1839 memcpy(buf, ip_as_string+1, len);
1840 buf[len] = '\0';
1841 addr_part = buf;
1842 if (cp[1] == ':')
1843 port_part = cp+2;
1844 else
1845 port_part = NULL;
1846 is_ipv6 = 1;
1847 } else if (cp && strchr(cp+1, ':')) {
1848 is_ipv6 = 1;
1849 addr_part = ip_as_string;
1850 port_part = NULL;
1851 } else if (cp) {
1852 is_ipv6 = 0;
1853 if (cp - ip_as_string > (int)sizeof(buf)-1) {
1854 return -1;
1856 memcpy(buf, ip_as_string, cp-ip_as_string);
1857 buf[cp-ip_as_string] = '\0';
1858 addr_part = buf;
1859 port_part = cp+1;
1860 } else {
1861 addr_part = ip_as_string;
1862 port_part = NULL;
1863 is_ipv6 = 0;
1866 if (port_part == NULL) {
1867 port = 0;
1868 } else {
1869 port = atoi(port_part);
1870 if (port <= 0 || port > 65535) {
1871 return -1;
1875 if (!addr_part)
1876 return -1; /* Should be impossible. */
1877 #ifdef AF_INET6
1878 if (is_ipv6)
1880 struct sockaddr_in6 sin6;
1881 memset(&sin6, 0, sizeof(sin6));
1882 #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
1883 sin6.sin6_len = sizeof(sin6);
1884 #endif
1885 sin6.sin6_family = AF_INET6;
1886 sin6.sin6_port = htons(port);
1887 if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr))
1888 return -1;
1889 if ((int)sizeof(sin6) > *outlen)
1890 return -1;
1891 memset(out, 0, *outlen);
1892 memcpy(out, &sin6, sizeof(sin6));
1893 *outlen = sizeof(sin6);
1894 return 0;
1896 else
1897 #endif
1899 struct sockaddr_in sin;
1900 memset(&sin, 0, sizeof(sin));
1901 #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1902 sin.sin_len = sizeof(sin);
1903 #endif
1904 sin.sin_family = AF_INET;
1905 sin.sin_port = htons(port);
1906 if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
1907 return -1;
1908 if ((int)sizeof(sin) > *outlen)
1909 return -1;
1910 memset(out, 0, *outlen);
1911 memcpy(out, &sin, sizeof(sin));
1912 *outlen = sizeof(sin);
1913 return 0;
1917 const char *
1918 evutil_format_sockaddr_port(const struct sockaddr *sa, char *out, size_t outlen)
1920 char b[128];
1921 const char *res=NULL;
1922 int port;
1923 if (sa->sa_family == AF_INET) {
1924 const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
1925 res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
1926 port = ntohs(sin->sin_port);
1927 if (res) {
1928 evutil_snprintf(out, outlen, "%s:%d", b, port);
1929 return out;
1931 } else if (sa->sa_family == AF_INET6) {
1932 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
1933 res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
1934 port = ntohs(sin6->sin6_port);
1935 if (res) {
1936 evutil_snprintf(out, outlen, "[%s]:%d", b, port);
1937 return out;
1941 evutil_snprintf(out, outlen, "<addr with socktype %d>",
1942 (int)sa->sa_family);
1943 return out;
1947 evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
1948 int include_port)
1950 int r;
1951 if (0 != (r = (sa1->sa_family - sa2->sa_family)))
1952 return r;
1954 if (sa1->sa_family == AF_INET) {
1955 const struct sockaddr_in *sin1, *sin2;
1956 sin1 = (const struct sockaddr_in *)sa1;
1957 sin2 = (const struct sockaddr_in *)sa2;
1958 if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
1959 return -1;
1960 else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
1961 return 1;
1962 else if (include_port &&
1963 (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
1964 return r;
1965 else
1966 return 0;
1968 #ifdef AF_INET6
1969 else if (sa1->sa_family == AF_INET6) {
1970 const struct sockaddr_in6 *sin1, *sin2;
1971 sin1 = (const struct sockaddr_in6 *)sa1;
1972 sin2 = (const struct sockaddr_in6 *)sa2;
1973 if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
1974 return r;
1975 else if (include_port &&
1976 (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
1977 return r;
1978 else
1979 return 0;
1981 #endif
1982 return 1;
1985 /* Tables to implement ctypes-replacement EVUTIL_IS*() functions. Each table
1986 * has 256 bits to look up whether a character is in some set or not. This
1987 * fails on non-ASCII platforms, but so does every other place where we
1988 * take a char and write it onto the network.
1990 static const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
1991 { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
1992 static const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
1993 { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
1994 static const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
1995 static const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
1996 { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
1997 static const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
1998 static const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
1999 { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
2000 static const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
2001 static const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
2002 /* Upper-casing and lowercasing tables to map characters to upper/lowercase
2003 * equivalents. */
2004 static const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
2005 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2006 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2007 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2008 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2009 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2010 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
2011 96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2012 80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
2013 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2014 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2015 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2016 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2017 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2018 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2019 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2020 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2022 static const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
2023 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2024 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2025 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2026 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2027 64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2028 112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
2029 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2030 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
2031 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2032 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2033 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2034 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2035 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2036 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2037 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2038 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2041 #define IMPL_CTYPE_FN(name) \
2042 int EVUTIL_##name(char c) { \
2043 ev_uint8_t u = c; \
2044 return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
2046 IMPL_CTYPE_FN(ISALPHA)
2047 IMPL_CTYPE_FN(ISALNUM)
2048 IMPL_CTYPE_FN(ISSPACE)
2049 IMPL_CTYPE_FN(ISDIGIT)
2050 IMPL_CTYPE_FN(ISXDIGIT)
2051 IMPL_CTYPE_FN(ISPRINT)
2052 IMPL_CTYPE_FN(ISLOWER)
2053 IMPL_CTYPE_FN(ISUPPER)
2055 char EVUTIL_TOLOWER(char c)
2057 return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
2059 char EVUTIL_TOUPPER(char c)
2061 return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
2064 evutil_ascii_strcasecmp(const char *s1, const char *s2)
2066 char c1, c2;
2067 while (1) {
2068 c1 = EVUTIL_TOLOWER(*s1++);
2069 c2 = EVUTIL_TOLOWER(*s2++);
2070 if (c1 < c2)
2071 return -1;
2072 else if (c1 > c2)
2073 return 1;
2074 else if (c1 == 0)
2075 return 0;
2078 int evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
2080 char c1, c2;
2081 while (n--) {
2082 c1 = EVUTIL_TOLOWER(*s1++);
2083 c2 = EVUTIL_TOLOWER(*s2++);
2084 if (c1 < c2)
2085 return -1;
2086 else if (c1 > c2)
2087 return 1;
2088 else if (c1 == 0)
2089 return 0;
2091 return 0;
2094 static int
2095 evutil_issetugid(void)
2097 #ifdef _EVENT_HAVE_ISSETUGID
2098 return issetugid();
2099 #else
2101 #ifdef _EVENT_HAVE_GETEUID
2102 if (getuid() != geteuid())
2103 return 1;
2104 #endif
2105 #ifdef _EVENT_HAVE_GETEGID
2106 if (getgid() != getegid())
2107 return 1;
2108 #endif
2109 return 0;
2110 #endif
2113 const char *
2114 evutil_getenv(const char *varname)
2116 if (evutil_issetugid())
2117 return NULL;
2119 return getenv(varname);
2122 long
2123 _evutil_weakrand(void)
2125 #ifdef WIN32
2126 return rand();
2127 #else
2128 return random();
2129 #endif
2133 evutil_sockaddr_is_loopback(const struct sockaddr *addr)
2135 static const char LOOPBACK_S6[16] =
2136 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
2137 if (addr->sa_family == AF_INET) {
2138 struct sockaddr_in *sin = (struct sockaddr_in *)addr;
2139 return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
2140 } else if (addr->sa_family == AF_INET6) {
2141 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
2142 return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
2144 return 0;
2147 #define MAX_SECONDS_IN_MSEC_LONG \
2148 (((LONG_MAX) - 999) / 1000)
2150 long
2151 evutil_tv_to_msec(const struct timeval *tv)
2153 if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
2154 return -1;
2156 return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
2160 evutil_hex_char_to_int(char c)
2162 switch(c)
2164 case '0': return 0;
2165 case '1': return 1;
2166 case '2': return 2;
2167 case '3': return 3;
2168 case '4': return 4;
2169 case '5': return 5;
2170 case '6': return 6;
2171 case '7': return 7;
2172 case '8': return 8;
2173 case '9': return 9;
2174 case 'A': case 'a': return 10;
2175 case 'B': case 'b': return 11;
2176 case 'C': case 'c': return 12;
2177 case 'D': case 'd': return 13;
2178 case 'E': case 'e': return 14;
2179 case 'F': case 'f': return 15;
2181 return -1;
2184 #ifdef WIN32
2185 HANDLE
2186 evutil_load_windows_system_library(const TCHAR *library_name)
2188 TCHAR path[MAX_PATH];
2189 unsigned n;
2190 n = GetSystemDirectory(path, MAX_PATH);
2191 if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
2192 return 0;
2193 _tcscat(path, TEXT("\\"));
2194 _tcscat(path, library_name);
2195 return LoadLibrary(path);
2197 #endif