blob: 3412c2aeda25bf8b6e1cab51c544f1f8ad02e52e [file] [log] [blame]
Christopher Wileye8679812015-07-01 13:36:18 -07001/*
2 * Copyright (c) 2007-2012 Niels Provos and Nick Mathewson
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#include "event2/event-config.h"
Narayan Kamathfc74cb42017-09-13 12:53:52 +010028#include "evconfig-private.h"
Christopher Wileye8679812015-07-01 13:36:18 -070029
Narayan Kamathfc74cb42017-09-13 12:53:52 +010030#ifdef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -070031#include <winsock2.h>
Haibo Huang45729092019-08-01 16:15:45 -070032#include <winerror.h>
Christopher Wileye8679812015-07-01 13:36:18 -070033#include <ws2tcpip.h>
34#define WIN32_LEAN_AND_MEAN
35#include <windows.h>
36#undef WIN32_LEAN_AND_MEAN
37#include <io.h>
38#include <tchar.h>
Narayan Kamathfc74cb42017-09-13 12:53:52 +010039#include <process.h>
40#undef _WIN32_WINNT
41/* For structs needed by GetAdaptersAddresses */
42#define _WIN32_WINNT 0x0501
43#include <iphlpapi.h>
Christopher Wileye8679812015-07-01 13:36:18 -070044#endif
45
46#include <sys/types.h>
Narayan Kamathfc74cb42017-09-13 12:53:52 +010047#ifdef EVENT__HAVE_SYS_SOCKET_H
Christopher Wileye8679812015-07-01 13:36:18 -070048#include <sys/socket.h>
49#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +010050#ifdef EVENT__HAVE_UNISTD_H
Christopher Wileye8679812015-07-01 13:36:18 -070051#include <unistd.h>
52#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +010053#ifdef EVENT__HAVE_FCNTL_H
Christopher Wileye8679812015-07-01 13:36:18 -070054#include <fcntl.h>
55#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +010056#ifdef EVENT__HAVE_STDLIB_H
Christopher Wileye8679812015-07-01 13:36:18 -070057#include <stdlib.h>
58#endif
59#include <errno.h>
60#include <limits.h>
61#include <stdio.h>
62#include <string.h>
Narayan Kamathfc74cb42017-09-13 12:53:52 +010063#ifdef EVENT__HAVE_NETINET_IN_H
Christopher Wileye8679812015-07-01 13:36:18 -070064#include <netinet/in.h>
65#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +010066#ifdef EVENT__HAVE_NETINET_IN6_H
Christopher Wileye8679812015-07-01 13:36:18 -070067#include <netinet/in6.h>
68#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +010069#ifdef EVENT__HAVE_NETINET_TCP_H
70#include <netinet/tcp.h>
71#endif
72#ifdef EVENT__HAVE_ARPA_INET_H
Christopher Wileye8679812015-07-01 13:36:18 -070073#include <arpa/inet.h>
74#endif
Christopher Wileye8679812015-07-01 13:36:18 -070075#include <time.h>
Josh Gao83a0c9c2017-08-10 12:30:25 -070076#include <sys/stat.h>
Narayan Kamathfc74cb42017-09-13 12:53:52 +010077#ifdef EVENT__HAVE_IFADDRS_H
78#include <ifaddrs.h>
79#endif
Christopher Wileye8679812015-07-01 13:36:18 -070080
81#include "event2/util.h"
82#include "util-internal.h"
83#include "log-internal.h"
84#include "mm-internal.h"
Narayan Kamathfc74cb42017-09-13 12:53:52 +010085#include "evthread-internal.h"
Christopher Wileye8679812015-07-01 13:36:18 -070086
87#include "strlcpy-internal.h"
88#include "ipv6-internal.h"
89
Narayan Kamathfc74cb42017-09-13 12:53:52 +010090#ifdef _WIN32
91#define HT_NO_CACHE_HASH_VALUES
92#include "ht-internal.h"
Christopher Wileye8679812015-07-01 13:36:18 -070093#define open _open
94#define read _read
95#define close _close
Narayan Kamathfc74cb42017-09-13 12:53:52 +010096#ifndef fstat
Christopher Wileye8679812015-07-01 13:36:18 -070097#define fstat _fstati64
Narayan Kamathfc74cb42017-09-13 12:53:52 +010098#endif
99#ifndef stat
Christopher Wileye8679812015-07-01 13:36:18 -0700100#define stat _stati64
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100101#endif
Christopher Wileye8679812015-07-01 13:36:18 -0700102#define mode_t int
103#endif
104
105int
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100106evutil_open_closeonexec_(const char *pathname, int flags, unsigned mode)
Christopher Wileye8679812015-07-01 13:36:18 -0700107{
108 int fd;
109
110#ifdef O_CLOEXEC
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100111 fd = open(pathname, flags|O_CLOEXEC, (mode_t)mode);
112 if (fd >= 0 || errno == EINVAL)
113 return fd;
114 /* If we got an EINVAL, fall through and try without O_CLOEXEC */
Christopher Wileye8679812015-07-01 13:36:18 -0700115#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100116 fd = open(pathname, flags, (mode_t)mode);
Christopher Wileye8679812015-07-01 13:36:18 -0700117 if (fd < 0)
118 return -1;
119
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100120#if defined(FD_CLOEXEC)
121 if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
122 close(fd);
Christopher Wileye8679812015-07-01 13:36:18 -0700123 return -1;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100124 }
Christopher Wileye8679812015-07-01 13:36:18 -0700125#endif
126
127 return fd;
128}
129
130/**
131 Read the contents of 'filename' into a newly allocated NUL-terminated
132 string. Set *content_out to hold this string, and *len_out to hold its
133 length (not including the appended NUL). If 'is_binary', open the file in
134 binary mode.
135
136 Returns 0 on success, -1 if the open fails, and -2 for all other failures.
137
138 Used internally only; may go away in a future version.
139 */
140int
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100141evutil_read_file_(const char *filename, char **content_out, size_t *len_out,
Christopher Wileye8679812015-07-01 13:36:18 -0700142 int is_binary)
143{
144 int fd, r;
145 struct stat st;
146 char *mem;
147 size_t read_so_far=0;
148 int mode = O_RDONLY;
149
150 EVUTIL_ASSERT(content_out);
151 EVUTIL_ASSERT(len_out);
152 *content_out = NULL;
153 *len_out = 0;
154
155#ifdef O_BINARY
156 if (is_binary)
157 mode |= O_BINARY;
158#endif
159
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100160 fd = evutil_open_closeonexec_(filename, mode, 0);
Christopher Wileye8679812015-07-01 13:36:18 -0700161 if (fd < 0)
162 return -1;
163 if (fstat(fd, &st) || st.st_size < 0 ||
164 st.st_size > EV_SSIZE_MAX-1 ) {
165 close(fd);
166 return -2;
167 }
168 mem = mm_malloc((size_t)st.st_size + 1);
169 if (!mem) {
170 close(fd);
171 return -2;
172 }
173 read_so_far = 0;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100174#ifdef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -0700175#define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
176#else
177#define N_TO_READ(x) (x)
178#endif
179 while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) {
180 read_so_far += r;
181 if (read_so_far >= (size_t)st.st_size)
182 break;
183 EVUTIL_ASSERT(read_so_far < (size_t)st.st_size);
184 }
185 close(fd);
186 if (r < 0) {
187 mm_free(mem);
188 return -2;
189 }
190 mem[read_so_far] = 0;
191
192 *len_out = read_so_far;
193 *content_out = mem;
194 return 0;
195}
196
197int
198evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
199{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100200#ifndef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -0700201 return socketpair(family, type, protocol, fd);
202#else
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100203 return evutil_ersatz_socketpair_(family, type, protocol, fd);
Christopher Wileye8679812015-07-01 13:36:18 -0700204#endif
205}
206
207int
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100208evutil_ersatz_socketpair_(int family, int type, int protocol,
Christopher Wileye8679812015-07-01 13:36:18 -0700209 evutil_socket_t fd[2])
210{
211 /* This code is originally from Tor. Used with permission. */
212
213 /* This socketpair does not work when localhost is down. So
214 * it's really not the same thing at all. But it's close enough
215 * for now, and really, when localhost is down sometimes, we
216 * have other problems too.
217 */
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100218#ifdef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -0700219#define ERR(e) WSA##e
220#else
221#define ERR(e) e
222#endif
223 evutil_socket_t listener = -1;
224 evutil_socket_t connector = -1;
225 evutil_socket_t acceptor = -1;
226 struct sockaddr_in listen_addr;
227 struct sockaddr_in connect_addr;
228 ev_socklen_t size;
229 int saved_errno = -1;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100230 int family_test;
231
232 family_test = family != AF_INET;
Christopher Wileye8679812015-07-01 13:36:18 -0700233#ifdef AF_UNIX
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100234 family_test = family_test && (family != AF_UNIX);
Christopher Wileye8679812015-07-01 13:36:18 -0700235#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100236 if (protocol || family_test) {
Christopher Wileye8679812015-07-01 13:36:18 -0700237 EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
238 return -1;
239 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100240
Christopher Wileye8679812015-07-01 13:36:18 -0700241 if (!fd) {
242 EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
243 return -1;
244 }
245
246 listener = socket(AF_INET, type, 0);
247 if (listener < 0)
248 return -1;
249 memset(&listen_addr, 0, sizeof(listen_addr));
250 listen_addr.sin_family = AF_INET;
251 listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
252 listen_addr.sin_port = 0; /* kernel chooses port. */
253 if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
254 == -1)
255 goto tidy_up_and_fail;
256 if (listen(listener, 1) == -1)
257 goto tidy_up_and_fail;
258
259 connector = socket(AF_INET, type, 0);
260 if (connector < 0)
261 goto tidy_up_and_fail;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100262
263 memset(&connect_addr, 0, sizeof(connect_addr));
264
Christopher Wileye8679812015-07-01 13:36:18 -0700265 /* We want to find out the port number to connect to. */
266 size = sizeof(connect_addr);
267 if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
268 goto tidy_up_and_fail;
269 if (size != sizeof (connect_addr))
270 goto abort_tidy_up_and_fail;
271 if (connect(connector, (struct sockaddr *) &connect_addr,
272 sizeof(connect_addr)) == -1)
273 goto tidy_up_and_fail;
274
275 size = sizeof(listen_addr);
276 acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
277 if (acceptor < 0)
278 goto tidy_up_and_fail;
279 if (size != sizeof(listen_addr))
280 goto abort_tidy_up_and_fail;
281 /* Now check we are talking to ourself by matching port and host on the
282 two sockets. */
283 if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
284 goto tidy_up_and_fail;
285 if (size != sizeof (connect_addr)
286 || listen_addr.sin_family != connect_addr.sin_family
287 || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
288 || listen_addr.sin_port != connect_addr.sin_port)
289 goto abort_tidy_up_and_fail;
290 evutil_closesocket(listener);
291 fd[0] = connector;
292 fd[1] = acceptor;
293
294 return 0;
295
296 abort_tidy_up_and_fail:
297 saved_errno = ERR(ECONNABORTED);
298 tidy_up_and_fail:
299 if (saved_errno < 0)
300 saved_errno = EVUTIL_SOCKET_ERROR();
301 if (listener != -1)
302 evutil_closesocket(listener);
303 if (connector != -1)
304 evutil_closesocket(connector);
305 if (acceptor != -1)
306 evutil_closesocket(acceptor);
307
308 EVUTIL_SET_SOCKET_ERROR(saved_errno);
309 return -1;
310#undef ERR
311}
312
313int
314evutil_make_socket_nonblocking(evutil_socket_t fd)
315{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100316#ifdef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -0700317 {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100318 unsigned long nonblocking = 1;
Christopher Wileye8679812015-07-01 13:36:18 -0700319 if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
320 event_sock_warn(fd, "fcntl(%d, F_GETFL)", (int)fd);
321 return -1;
322 }
323 }
324#else
325 {
326 int flags;
327 if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
328 event_warn("fcntl(%d, F_GETFL)", fd);
329 return -1;
330 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100331 if (!(flags & O_NONBLOCK)) {
332 if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
333 event_warn("fcntl(%d, F_SETFL)", fd);
334 return -1;
335 }
Christopher Wileye8679812015-07-01 13:36:18 -0700336 }
337 }
338#endif
339 return 0;
340}
341
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100342/* Faster version of evutil_make_socket_nonblocking for internal use.
343 *
344 * Requires that no F_SETFL flags were previously set on the fd.
345 */
346static int
347evutil_fast_socket_nonblocking(evutil_socket_t fd)
348{
349#ifdef _WIN32
350 return evutil_make_socket_nonblocking(fd);
351#else
352 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
353 event_warn("fcntl(%d, F_SETFL)", fd);
354 return -1;
355 }
356 return 0;
357#endif
358}
359
Christopher Wileye8679812015-07-01 13:36:18 -0700360int
361evutil_make_listen_socket_reuseable(evutil_socket_t sock)
362{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100363#if defined(SO_REUSEADDR) && !defined(_WIN32)
Christopher Wileye8679812015-07-01 13:36:18 -0700364 int one = 1;
365 /* REUSEADDR on Unix means, "don't hang on to this address after the
366 * listener is closed." On Windows, though, it means "don't keep other
367 * processes from binding to this address while we're using it. */
368 return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
369 (ev_socklen_t)sizeof(one));
370#else
371 return 0;
372#endif
373}
374
375int
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100376evutil_make_listen_socket_reuseable_port(evutil_socket_t sock)
377{
378#if defined __linux__ && defined(SO_REUSEPORT)
379 int one = 1;
380 /* REUSEPORT on Linux 3.9+ means, "Multiple servers (processes or
381 * threads) can bind to the same port if they each set the option. */
382 return setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void*) &one,
383 (ev_socklen_t)sizeof(one));
384#else
385 return 0;
386#endif
387}
388
389int
Haibo Huangb2279672019-05-31 16:12:39 -0700390evutil_make_listen_socket_ipv6only(evutil_socket_t sock)
391{
392#if defined(IPV6_V6ONLY)
393 int one = 1;
394 return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &one,
395 (ev_socklen_t)sizeof(one));
396#endif
397 return 0;
398}
399
400int
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100401evutil_make_tcp_listen_socket_deferred(evutil_socket_t sock)
402{
403#if defined(EVENT__HAVE_NETINET_TCP_H) && defined(TCP_DEFER_ACCEPT)
404 int one = 1;
405
406 /* TCP_DEFER_ACCEPT tells the kernel to call defer accept() only after data
407 * has arrived and ready to read */
408 return setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, &one,
409 (ev_socklen_t)sizeof(one));
410#endif
411 return 0;
412}
413
414int
Christopher Wileye8679812015-07-01 13:36:18 -0700415evutil_make_socket_closeonexec(evutil_socket_t fd)
416{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100417#if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
Christopher Wileye8679812015-07-01 13:36:18 -0700418 int flags;
419 if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
420 event_warn("fcntl(%d, F_GETFD)", fd);
421 return -1;
422 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100423 if (!(flags & FD_CLOEXEC)) {
424 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
425 event_warn("fcntl(%d, F_SETFD)", fd);
426 return -1;
427 }
428 }
429#endif
430 return 0;
431}
432
433/* Faster version of evutil_make_socket_closeonexec for internal use.
434 *
435 * Requires that no F_SETFD flags were previously set on the fd.
436 */
437static int
438evutil_fast_socket_closeonexec(evutil_socket_t fd)
439{
440#if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
441 if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
Christopher Wileye8679812015-07-01 13:36:18 -0700442 event_warn("fcntl(%d, F_SETFD)", fd);
443 return -1;
444 }
445#endif
446 return 0;
447}
448
449int
450evutil_closesocket(evutil_socket_t sock)
451{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100452#ifndef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -0700453 return close(sock);
454#else
455 return closesocket(sock);
456#endif
457}
458
459ev_int64_t
460evutil_strtoll(const char *s, char **endptr, int base)
461{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100462#ifdef EVENT__HAVE_STRTOLL
Christopher Wileye8679812015-07-01 13:36:18 -0700463 return (ev_int64_t)strtoll(s, endptr, base);
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100464#elif EVENT__SIZEOF_LONG == 8
Christopher Wileye8679812015-07-01 13:36:18 -0700465 return (ev_int64_t)strtol(s, endptr, base);
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100466#elif defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
Christopher Wileye8679812015-07-01 13:36:18 -0700467 /* XXXX on old versions of MS APIs, we only support base
468 * 10. */
469 ev_int64_t r;
470 if (base != 10)
471 return 0;
472 r = (ev_int64_t) _atoi64(s);
473 while (isspace(*s))
474 ++s;
475 if (*s == '-')
476 ++s;
477 while (isdigit(*s))
478 ++s;
479 if (endptr)
480 *endptr = (char*) s;
481 return r;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100482#elif defined(_WIN32)
Christopher Wileye8679812015-07-01 13:36:18 -0700483 return (ev_int64_t) _strtoi64(s, endptr, base);
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100484#elif defined(EVENT__SIZEOF_LONG_LONG) && EVENT__SIZEOF_LONG_LONG == 8
Christopher Wileye8679812015-07-01 13:36:18 -0700485 long long r;
486 int n;
487 if (base != 10 && base != 16)
488 return 0;
489 if (base == 10) {
490 n = sscanf(s, "%lld", &r);
491 } else {
492 unsigned long long ru=0;
493 n = sscanf(s, "%llx", &ru);
494 if (ru > EV_INT64_MAX)
495 return 0;
496 r = (long long) ru;
497 }
498 if (n != 1)
499 return 0;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100500 while (EVUTIL_ISSPACE_(*s))
Christopher Wileye8679812015-07-01 13:36:18 -0700501 ++s;
502 if (*s == '-')
503 ++s;
504 if (base == 10) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100505 while (EVUTIL_ISDIGIT_(*s))
Christopher Wileye8679812015-07-01 13:36:18 -0700506 ++s;
507 } else {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100508 while (EVUTIL_ISXDIGIT_(*s))
Christopher Wileye8679812015-07-01 13:36:18 -0700509 ++s;
510 }
511 if (endptr)
512 *endptr = (char*) s;
513 return r;
514#else
515#error "I don't know how to parse 64-bit integers."
516#endif
517}
518
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100519#ifdef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -0700520int
521evutil_socket_geterror(evutil_socket_t sock)
522{
523 int optval, optvallen=sizeof(optval);
524 int err = WSAGetLastError();
525 if (err == WSAEWOULDBLOCK && sock >= 0) {
526 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
527 &optvallen))
528 return err;
529 if (optval)
530 return optval;
531 }
532 return err;
533}
534#endif
535
536/* XXX we should use an enum here. */
537/* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
538int
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100539evutil_socket_connect_(evutil_socket_t *fd_ptr, const struct sockaddr *sa, int socklen)
Christopher Wileye8679812015-07-01 13:36:18 -0700540{
541 int made_fd = 0;
542
543 if (*fd_ptr < 0) {
544 if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
545 goto err;
546 made_fd = 1;
547 if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
548 goto err;
549 }
550 }
551
552 if (connect(*fd_ptr, sa, socklen) < 0) {
553 int e = evutil_socket_geterror(*fd_ptr);
554 if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
555 return 0;
556 if (EVUTIL_ERR_CONNECT_REFUSED(e))
557 return 2;
558 goto err;
559 } else {
560 return 1;
561 }
562
563err:
564 if (made_fd) {
565 evutil_closesocket(*fd_ptr);
566 *fd_ptr = -1;
567 }
568 return -1;
569}
570
571/* Check whether a socket on which we called connect() is done
572 connecting. Return 1 for connected, 0 for not yet, -1 for error. In the
573 error case, set the current socket errno to the error that happened during
574 the connect operation. */
575int
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100576evutil_socket_finished_connecting_(evutil_socket_t fd)
Christopher Wileye8679812015-07-01 13:36:18 -0700577{
578 int e;
579 ev_socklen_t elen = sizeof(e);
580
581 if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
582 return -1;
583
584 if (e) {
585 if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
586 return 0;
587 EVUTIL_SET_SOCKET_ERROR(e);
588 return -1;
589 }
590
591 return 1;
592}
593
594#if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
595 EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
596 EVUTIL_AI_ADDRCONFIG) != \
597 (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
598 EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
599 EVUTIL_AI_ADDRCONFIG)
600#error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
601#endif
602
603/* We sometimes need to know whether we have an ipv4 address and whether we
604 have an ipv6 address. If 'have_checked_interfaces', then we've already done
605 the test. If 'had_ipv4_address', then it turns out we had an ipv4 address.
606 If 'had_ipv6_address', then it turns out we had an ipv6 address. These are
607 set by evutil_check_interfaces. */
608static int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
609
Haibo Huangb2279672019-05-31 16:12:39 -0700610/* True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8 */
611static inline int evutil_v4addr_is_localhost(ev_uint32_t addr)
612{ return addr>>24 == 127; }
Christopher Wileye8679812015-07-01 13:36:18 -0700613
Haibo Huangb2279672019-05-31 16:12:39 -0700614/* True iff the IPv4 address 'addr', in host order, is link-local
615 * 169.254.0.0/16 (RFC3927) */
616static inline int evutil_v4addr_is_linklocal(ev_uint32_t addr)
617{ return ((addr & 0xffff0000U) == 0xa9fe0000U); }
618
619/* True iff the IPv4 address 'addr', in host order, is a class D
620 * (multiclass) address. */
621static inline int evutil_v4addr_is_classd(ev_uint32_t addr)
622{ return ((addr>>24) & 0xf0) == 0xe0; }
623
624int
625evutil_v4addr_is_local_(const struct in_addr *in)
626{
627 const ev_uint32_t addr = ntohl(in->s_addr);
628 return addr == INADDR_ANY ||
629 evutil_v4addr_is_localhost(addr) ||
630 evutil_v4addr_is_linklocal(addr) ||
631 evutil_v4addr_is_classd(addr);
632}
633int
634evutil_v6addr_is_local_(const struct in6_addr *in)
635{
636 static const char ZEROES[] =
637 "\x00\x00\x00\x00\x00\x00\x00\x00"
638 "\x00\x00\x00\x00\x00\x00\x00\x00";
639
640 const unsigned char *addr = (const unsigned char *)in->s6_addr;
641 return !memcmp(addr, ZEROES, 8) ||
642 ((addr[0] & 0xfe) == 0xfc) ||
643 (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) ||
644 (addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) ||
645 (addr[0] == 0xff);
646}
Christopher Wileye8679812015-07-01 13:36:18 -0700647
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100648static void
649evutil_found_ifaddr(const struct sockaddr *sa)
650{
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100651 if (sa->sa_family == AF_INET) {
652 const struct sockaddr_in *sin = (struct sockaddr_in *)sa;
Haibo Huangb2279672019-05-31 16:12:39 -0700653 if (!evutil_v4addr_is_local_(&sin->sin_addr)) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100654 event_debug(("Detected an IPv4 interface"));
655 had_ipv4_address = 1;
656 }
657 } else if (sa->sa_family == AF_INET6) {
658 const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
Haibo Huangb2279672019-05-31 16:12:39 -0700659 if (!evutil_v6addr_is_local_(&sin6->sin6_addr)) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100660 event_debug(("Detected an IPv6 interface"));
661 had_ipv6_address = 1;
662 }
663 }
664}
665
666#ifdef _WIN32
667typedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
668 ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
669#endif
670
671static int
672evutil_check_ifaddrs(void)
673{
674#if defined(EVENT__HAVE_GETIFADDRS)
675 /* Most free Unixy systems provide getifaddrs, which gives us a linked list
676 * of struct ifaddrs. */
677 struct ifaddrs *ifa = NULL;
678 const struct ifaddrs *i;
679 if (getifaddrs(&ifa) < 0) {
680 event_warn("Unable to call getifaddrs()");
681 return -1;
682 }
683
684 for (i = ifa; i; i = i->ifa_next) {
685 if (!i->ifa_addr)
686 continue;
687 evutil_found_ifaddr(i->ifa_addr);
688 }
689
690 freeifaddrs(ifa);
691 return 0;
692#elif defined(_WIN32)
693 /* Windows XP began to provide GetAdaptersAddresses. Windows 2000 had a
694 "GetAdaptersInfo", but that's deprecated; let's just try
695 GetAdaptersAddresses and fall back to connect+getsockname.
696 */
697 HMODULE lib = evutil_load_windows_system_library_(TEXT("ihplapi.dll"));
698 GetAdaptersAddresses_fn_t fn;
699 ULONG size, res;
700 IP_ADAPTER_ADDRESSES *addresses = NULL, *address;
701 int result = -1;
702
703#define FLAGS (GAA_FLAG_SKIP_ANYCAST | \
704 GAA_FLAG_SKIP_MULTICAST | \
705 GAA_FLAG_SKIP_DNS_SERVER)
706
707 if (!lib)
708 goto done;
709
710 if (!(fn = (GetAdaptersAddresses_fn_t) GetProcAddress(lib, "GetAdaptersAddresses")))
711 goto done;
712
713 /* Guess how much space we need. */
714 size = 15*1024;
715 addresses = mm_malloc(size);
716 if (!addresses)
717 goto done;
718 res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
719 if (res == ERROR_BUFFER_OVERFLOW) {
720 /* we didn't guess that we needed enough space; try again */
721 mm_free(addresses);
722 addresses = mm_malloc(size);
723 if (!addresses)
724 goto done;
725 res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
726 }
727 if (res != NO_ERROR)
728 goto done;
729
730 for (address = addresses; address; address = address->Next) {
731 IP_ADAPTER_UNICAST_ADDRESS *a;
732 for (a = address->FirstUnicastAddress; a; a = a->Next) {
733 /* Yes, it's a linked list inside a linked list */
734 struct sockaddr *sa = a->Address.lpSockaddr;
735 evutil_found_ifaddr(sa);
736 }
737 }
738
739 result = 0;
740done:
741 if (lib)
742 FreeLibrary(lib);
743 if (addresses)
744 mm_free(addresses);
745 return result;
746#else
747 return -1;
748#endif
749}
750
Christopher Wileye8679812015-07-01 13:36:18 -0700751/* Test whether we have an ipv4 interface and an ipv6 interface. Return 0 if
752 * the test seemed successful. */
753static int
Haibo Huang45729092019-08-01 16:15:45 -0700754evutil_check_interfaces(void)
Christopher Wileye8679812015-07-01 13:36:18 -0700755{
Christopher Wileye8679812015-07-01 13:36:18 -0700756 evutil_socket_t fd = -1;
757 struct sockaddr_in sin, sin_out;
758 struct sockaddr_in6 sin6, sin6_out;
759 ev_socklen_t sin_out_len = sizeof(sin_out);
760 ev_socklen_t sin6_out_len = sizeof(sin6_out);
761 int r;
Haibo Huang45729092019-08-01 16:15:45 -0700762 if (have_checked_interfaces)
Christopher Wileye8679812015-07-01 13:36:18 -0700763 return 0;
764
Haibo Huang45729092019-08-01 16:15:45 -0700765 /* From this point on we have done the ipv4/ipv6 interface check */
766 have_checked_interfaces = 1;
767
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100768 if (evutil_check_ifaddrs() == 0) {
769 /* Use a nice sane interface, if this system has one. */
770 return 0;
771 }
772
773 /* Ugh. There was no nice sane interface. So to check whether we have
774 * an interface open for a given protocol, will try to make a UDP
775 * 'connection' to a remote host on the internet. We don't actually
776 * use it, so the address doesn't matter, but we want to pick one that
777 * keep us from using a host- or link-local interface. */
Christopher Wileye8679812015-07-01 13:36:18 -0700778 memset(&sin, 0, sizeof(sin));
779 sin.sin_family = AF_INET;
780 sin.sin_port = htons(53);
781 r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
782 EVUTIL_ASSERT(r);
783
784 memset(&sin6, 0, sizeof(sin6));
785 sin6.sin6_family = AF_INET6;
786 sin6.sin6_port = htons(53);
787 r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
788 EVUTIL_ASSERT(r);
789
790 memset(&sin_out, 0, sizeof(sin_out));
791 memset(&sin6_out, 0, sizeof(sin6_out));
792
793 /* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
794 if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
795 connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
796 getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
797 /* We might have an IPv4 interface. */
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100798 evutil_found_ifaddr((struct sockaddr*) &sin_out);
Christopher Wileye8679812015-07-01 13:36:18 -0700799 }
800 if (fd >= 0)
801 evutil_closesocket(fd);
802
803 if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
804 connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
805 getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
806 /* We might have an IPv6 interface. */
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100807 evutil_found_ifaddr((struct sockaddr*) &sin6_out);
Christopher Wileye8679812015-07-01 13:36:18 -0700808 }
809
810 if (fd >= 0)
811 evutil_closesocket(fd);
812
813 return 0;
814}
815
816/* Internal addrinfo flag. This one is set when we allocate the addrinfo from
817 * inside libevent. Otherwise, the built-in getaddrinfo() function allocated
818 * it, and we should trust what they said.
819 **/
820#define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
821
822/* Helper: construct a new addrinfo containing the socket address in
823 * 'sa', which must be a sockaddr_in or a sockaddr_in6. Take the
824 * socktype and protocol info from hints. If they weren't set, then
825 * allocate both a TCP and a UDP addrinfo.
826 */
827struct evutil_addrinfo *
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100828evutil_new_addrinfo_(struct sockaddr *sa, ev_socklen_t socklen,
Christopher Wileye8679812015-07-01 13:36:18 -0700829 const struct evutil_addrinfo *hints)
830{
831 struct evutil_addrinfo *res;
832 EVUTIL_ASSERT(hints);
833
834 if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
835 /* Indecisive user! Give them a UDP and a TCP. */
836 struct evutil_addrinfo *r1, *r2;
837 struct evutil_addrinfo tmp;
838 memcpy(&tmp, hints, sizeof(tmp));
839 tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100840 r1 = evutil_new_addrinfo_(sa, socklen, &tmp);
Christopher Wileye8679812015-07-01 13:36:18 -0700841 if (!r1)
842 return NULL;
843 tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100844 r2 = evutil_new_addrinfo_(sa, socklen, &tmp);
Christopher Wileye8679812015-07-01 13:36:18 -0700845 if (!r2) {
846 evutil_freeaddrinfo(r1);
847 return NULL;
848 }
849 r1->ai_next = r2;
850 return r1;
851 }
852
853 /* We're going to allocate extra space to hold the sockaddr. */
854 res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
855 if (!res)
856 return NULL;
857 res->ai_addr = (struct sockaddr*)
858 (((char*)res) + sizeof(struct evutil_addrinfo));
859 memcpy(res->ai_addr, sa, socklen);
860 res->ai_addrlen = socklen;
861 res->ai_family = sa->sa_family; /* Same or not? XXX */
862 res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
863 res->ai_socktype = hints->ai_socktype;
864 res->ai_protocol = hints->ai_protocol;
865
866 return res;
867}
868
869/* Append the addrinfo 'append' to the end of 'first', and return the start of
870 * the list. Either element can be NULL, in which case we return the element
871 * that is not NULL. */
872struct evutil_addrinfo *
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100873evutil_addrinfo_append_(struct evutil_addrinfo *first,
Christopher Wileye8679812015-07-01 13:36:18 -0700874 struct evutil_addrinfo *append)
875{
876 struct evutil_addrinfo *ai = first;
877 if (!ai)
878 return append;
879 while (ai->ai_next)
880 ai = ai->ai_next;
881 ai->ai_next = append;
882
883 return first;
884}
885
886static int
887parse_numeric_servname(const char *servname)
888{
889 int n;
890 char *endptr=NULL;
891 n = (int) strtol(servname, &endptr, 10);
892 if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
893 return n;
894 else
895 return -1;
896}
897
898/** Parse a service name in 'servname', which can be a decimal port.
899 * Return the port number, or -1 on error.
900 */
901static int
902evutil_parse_servname(const char *servname, const char *protocol,
903 const struct evutil_addrinfo *hints)
904{
905 int n = parse_numeric_servname(servname);
906 if (n>=0)
907 return n;
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100908#if defined(EVENT__HAVE_GETSERVBYNAME) || defined(_WIN32)
Christopher Wileye8679812015-07-01 13:36:18 -0700909 if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
910 struct servent *ent = getservbyname(servname, protocol);
911 if (ent) {
912 return ntohs(ent->s_port);
913 }
914 }
915#endif
916 return -1;
917}
918
919/* Return a string corresponding to a protocol number that we can pass to
920 * getservyname. */
921static const char *
922evutil_unparse_protoname(int proto)
923{
924 switch (proto) {
925 case 0:
926 return NULL;
927 case IPPROTO_TCP:
928 return "tcp";
929 case IPPROTO_UDP:
930 return "udp";
931#ifdef IPPROTO_SCTP
932 case IPPROTO_SCTP:
933 return "sctp";
934#endif
935 default:
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100936#ifdef EVENT__HAVE_GETPROTOBYNUMBER
Christopher Wileye8679812015-07-01 13:36:18 -0700937 {
938 struct protoent *ent = getprotobynumber(proto);
939 if (ent)
940 return ent->p_name;
941 }
942#endif
943 return NULL;
944 }
945}
946
947static void
948evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
949{
950 /* If we can guess the protocol from the socktype, do so. */
951 if (!hints->ai_protocol && hints->ai_socktype) {
952 if (hints->ai_socktype == SOCK_DGRAM)
953 hints->ai_protocol = IPPROTO_UDP;
954 else if (hints->ai_socktype == SOCK_STREAM)
955 hints->ai_protocol = IPPROTO_TCP;
956 }
957
958 /* Set the socktype if it isn't set. */
959 if (!hints->ai_socktype && hints->ai_protocol) {
960 if (hints->ai_protocol == IPPROTO_UDP)
961 hints->ai_socktype = SOCK_DGRAM;
962 else if (hints->ai_protocol == IPPROTO_TCP)
963 hints->ai_socktype = SOCK_STREAM;
964#ifdef IPPROTO_SCTP
965 else if (hints->ai_protocol == IPPROTO_SCTP)
966 hints->ai_socktype = SOCK_STREAM;
967#endif
968 }
969}
970
971#if AF_UNSPEC != PF_UNSPEC
972#error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
973#endif
974
975/** Implements the part of looking up hosts by name that's common to both
976 * the blocking and nonblocking resolver:
977 * - Adjust 'hints' to have a reasonable socktype and protocol.
978 * - Look up the port based on 'servname', and store it in *portnum,
979 * - Handle the nodename==NULL case
980 * - Handle some invalid arguments cases.
981 * - Handle the cases where nodename is an IPv4 or IPv6 address.
982 *
983 * If we need the resolver to look up the hostname, we return
984 * EVUTIL_EAI_NEED_RESOLVE. Otherwise, we can completely implement
985 * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
986 * set *res as getaddrinfo would.
987 */
988int
Narayan Kamathfc74cb42017-09-13 12:53:52 +0100989evutil_getaddrinfo_common_(const char *nodename, const char *servname,
Christopher Wileye8679812015-07-01 13:36:18 -0700990 struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
991{
992 int port = 0;
993 const char *pname;
994
995 if (nodename == NULL && servname == NULL)
996 return EVUTIL_EAI_NONAME;
997
998 /* We only understand 3 families */
999 if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
1000 hints->ai_family != PF_INET6)
1001 return EVUTIL_EAI_FAMILY;
1002
1003 evutil_getaddrinfo_infer_protocols(hints);
1004
1005 /* Look up the port number and protocol, if possible. */
1006 pname = evutil_unparse_protoname(hints->ai_protocol);
1007 if (servname) {
1008 /* XXXX We could look at the protocol we got back from
1009 * getservbyname, but it doesn't seem too useful. */
1010 port = evutil_parse_servname(servname, pname, hints);
1011 if (port < 0) {
1012 return EVUTIL_EAI_NONAME;
1013 }
1014 }
1015
1016 /* If we have no node name, then we're supposed to bind to 'any' and
1017 * connect to localhost. */
1018 if (nodename == NULL) {
1019 struct evutil_addrinfo *res4=NULL, *res6=NULL;
1020 if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
1021 struct sockaddr_in6 sin6;
1022 memset(&sin6, 0, sizeof(sin6));
1023 sin6.sin6_family = AF_INET6;
1024 sin6.sin6_port = htons(port);
1025 if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
1026 /* Bind to :: */
1027 } else {
1028 /* connect to ::1 */
1029 sin6.sin6_addr.s6_addr[15] = 1;
1030 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001031 res6 = evutil_new_addrinfo_((struct sockaddr*)&sin6,
Christopher Wileye8679812015-07-01 13:36:18 -07001032 sizeof(sin6), hints);
1033 if (!res6)
1034 return EVUTIL_EAI_MEMORY;
1035 }
1036
1037 if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
1038 struct sockaddr_in sin;
1039 memset(&sin, 0, sizeof(sin));
1040 sin.sin_family = AF_INET;
1041 sin.sin_port = htons(port);
1042 if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
1043 /* Bind to 0.0.0.0 */
1044 } else {
1045 /* connect to 127.0.0.1 */
1046 sin.sin_addr.s_addr = htonl(0x7f000001);
1047 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001048 res4 = evutil_new_addrinfo_((struct sockaddr*)&sin,
Christopher Wileye8679812015-07-01 13:36:18 -07001049 sizeof(sin), hints);
1050 if (!res4) {
1051 if (res6)
1052 evutil_freeaddrinfo(res6);
1053 return EVUTIL_EAI_MEMORY;
1054 }
1055 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001056 *res = evutil_addrinfo_append_(res4, res6);
Christopher Wileye8679812015-07-01 13:36:18 -07001057 return 0;
1058 }
1059
1060 /* If we can, we should try to parse the hostname without resolving
1061 * it. */
1062 /* Try ipv6. */
1063 if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
1064 struct sockaddr_in6 sin6;
1065 memset(&sin6, 0, sizeof(sin6));
1066 if (1==evutil_inet_pton(AF_INET6, nodename, &sin6.sin6_addr)) {
1067 /* Got an ipv6 address. */
1068 sin6.sin6_family = AF_INET6;
1069 sin6.sin6_port = htons(port);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001070 *res = evutil_new_addrinfo_((struct sockaddr*)&sin6,
Christopher Wileye8679812015-07-01 13:36:18 -07001071 sizeof(sin6), hints);
1072 if (!*res)
1073 return EVUTIL_EAI_MEMORY;
1074 return 0;
1075 }
1076 }
1077
1078 /* Try ipv4. */
1079 if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
1080 struct sockaddr_in sin;
1081 memset(&sin, 0, sizeof(sin));
1082 if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
Haibo Huangb2279672019-05-31 16:12:39 -07001083 /* Got an ipv4 address. */
Christopher Wileye8679812015-07-01 13:36:18 -07001084 sin.sin_family = AF_INET;
1085 sin.sin_port = htons(port);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001086 *res = evutil_new_addrinfo_((struct sockaddr*)&sin,
Christopher Wileye8679812015-07-01 13:36:18 -07001087 sizeof(sin), hints);
1088 if (!*res)
1089 return EVUTIL_EAI_MEMORY;
1090 return 0;
1091 }
1092 }
1093
1094
1095 /* If we have reached this point, we definitely need to do a DNS
1096 * lookup. */
1097 if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
1098 /* If we're not allowed to do one, then say so. */
1099 return EVUTIL_EAI_NONAME;
1100 }
1101 *portnum = port;
1102 return EVUTIL_EAI_NEED_RESOLVE;
1103}
1104
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001105#ifdef EVENT__HAVE_GETADDRINFO
Christopher Wileye8679812015-07-01 13:36:18 -07001106#define USE_NATIVE_GETADDRINFO
1107#endif
1108
1109#ifdef USE_NATIVE_GETADDRINFO
1110/* A mask of all the flags that we declare, so we can clear them before calling
1111 * the native getaddrinfo */
1112static const unsigned int ALL_NONNATIVE_AI_FLAGS =
1113#ifndef AI_PASSIVE
1114 EVUTIL_AI_PASSIVE |
1115#endif
1116#ifndef AI_CANONNAME
1117 EVUTIL_AI_CANONNAME |
1118#endif
1119#ifndef AI_NUMERICHOST
1120 EVUTIL_AI_NUMERICHOST |
1121#endif
1122#ifndef AI_NUMERICSERV
1123 EVUTIL_AI_NUMERICSERV |
1124#endif
1125#ifndef AI_ADDRCONFIG
1126 EVUTIL_AI_ADDRCONFIG |
1127#endif
1128#ifndef AI_ALL
1129 EVUTIL_AI_ALL |
1130#endif
1131#ifndef AI_V4MAPPED
1132 EVUTIL_AI_V4MAPPED |
1133#endif
1134 EVUTIL_AI_LIBEVENT_ALLOCATED;
1135
1136static const unsigned int ALL_NATIVE_AI_FLAGS =
1137#ifdef AI_PASSIVE
1138 AI_PASSIVE |
1139#endif
1140#ifdef AI_CANONNAME
1141 AI_CANONNAME |
1142#endif
1143#ifdef AI_NUMERICHOST
1144 AI_NUMERICHOST |
1145#endif
1146#ifdef AI_NUMERICSERV
1147 AI_NUMERICSERV |
1148#endif
1149#ifdef AI_ADDRCONFIG
1150 AI_ADDRCONFIG |
1151#endif
1152#ifdef AI_ALL
1153 AI_ALL |
1154#endif
1155#ifdef AI_V4MAPPED
1156 AI_V4MAPPED |
1157#endif
1158 0;
1159#endif
1160
1161#ifndef USE_NATIVE_GETADDRINFO
1162/* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
1163 * a struct hostent.
1164 */
1165static struct evutil_addrinfo *
1166addrinfo_from_hostent(const struct hostent *ent,
1167 int port, const struct evutil_addrinfo *hints)
1168{
1169 int i;
1170 struct sockaddr_in sin;
1171 struct sockaddr_in6 sin6;
1172 struct sockaddr *sa;
1173 int socklen;
1174 struct evutil_addrinfo *res=NULL, *ai;
1175 void *addrp;
1176
1177 if (ent->h_addrtype == PF_INET) {
1178 memset(&sin, 0, sizeof(sin));
1179 sin.sin_family = AF_INET;
1180 sin.sin_port = htons(port);
1181 sa = (struct sockaddr *)&sin;
1182 socklen = sizeof(struct sockaddr_in);
1183 addrp = &sin.sin_addr;
1184 if (ent->h_length != sizeof(sin.sin_addr)) {
1185 event_warnx("Weird h_length from gethostbyname");
1186 return NULL;
1187 }
1188 } else if (ent->h_addrtype == PF_INET6) {
1189 memset(&sin6, 0, sizeof(sin6));
1190 sin6.sin6_family = AF_INET6;
1191 sin6.sin6_port = htons(port);
1192 sa = (struct sockaddr *)&sin6;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001193 socklen = sizeof(struct sockaddr_in6);
Christopher Wileye8679812015-07-01 13:36:18 -07001194 addrp = &sin6.sin6_addr;
1195 if (ent->h_length != sizeof(sin6.sin6_addr)) {
1196 event_warnx("Weird h_length from gethostbyname");
1197 return NULL;
1198 }
1199 } else
1200 return NULL;
1201
1202 for (i = 0; ent->h_addr_list[i]; ++i) {
1203 memcpy(addrp, ent->h_addr_list[i], ent->h_length);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001204 ai = evutil_new_addrinfo_(sa, socklen, hints);
Christopher Wileye8679812015-07-01 13:36:18 -07001205 if (!ai) {
1206 evutil_freeaddrinfo(res);
1207 return NULL;
1208 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001209 res = evutil_addrinfo_append_(res, ai);
Christopher Wileye8679812015-07-01 13:36:18 -07001210 }
1211
1212 if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
1213 res->ai_canonname = mm_strdup(ent->h_name);
1214 if (res->ai_canonname == NULL) {
1215 evutil_freeaddrinfo(res);
1216 return NULL;
1217 }
1218 }
1219
1220 return res;
1221}
1222#endif
1223
1224/* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
1225 * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
1226 * that we'll only get addresses we could maybe connect to.
1227 */
1228void
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001229evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints)
Christopher Wileye8679812015-07-01 13:36:18 -07001230{
1231 if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
1232 return;
1233 if (hints->ai_family != PF_UNSPEC)
1234 return;
Haibo Huang45729092019-08-01 16:15:45 -07001235 evutil_check_interfaces();
Christopher Wileye8679812015-07-01 13:36:18 -07001236 if (had_ipv4_address && !had_ipv6_address) {
1237 hints->ai_family = PF_INET;
1238 } else if (!had_ipv4_address && had_ipv6_address) {
1239 hints->ai_family = PF_INET6;
1240 }
1241}
1242
1243#ifdef USE_NATIVE_GETADDRINFO
1244static int need_numeric_port_hack_=0;
1245static int need_socktype_protocol_hack_=0;
1246static int tested_for_getaddrinfo_hacks=0;
1247
1248/* Some older BSDs (like OpenBSD up to 4.6) used to believe that
1249 giving a numeric port without giving an ai_socktype was verboten.
1250 We test for this so we can apply an appropriate workaround. If it
1251 turns out that the bug is present, then:
1252
1253 - If nodename==NULL and servname is numeric, we build an answer
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001254 ourselves using evutil_getaddrinfo_common_().
Christopher Wileye8679812015-07-01 13:36:18 -07001255
1256 - If nodename!=NULL and servname is numeric, then we set
1257 servname=NULL when calling getaddrinfo, and post-process the
1258 result to set the ports on it.
1259
1260 We test for this bug at runtime, since otherwise we can't have the
1261 same binary run on multiple BSD versions.
1262
1263 - Some versions of Solaris believe that it's nice to leave to protocol
1264 field set to 0. We test for this so we can apply an appropriate
1265 workaround.
1266*/
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001267static struct evutil_addrinfo *ai_find_protocol(struct evutil_addrinfo *ai)
1268{
1269 while (ai) {
1270 if (ai->ai_protocol)
1271 return ai;
1272 ai = ai->ai_next;
1273 }
1274 return NULL;
1275}
Christopher Wileye8679812015-07-01 13:36:18 -07001276static void
1277test_for_getaddrinfo_hacks(void)
1278{
1279 int r, r2;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001280 struct evutil_addrinfo *ai=NULL, *ai2=NULL, *ai3=NULL;
Christopher Wileye8679812015-07-01 13:36:18 -07001281 struct evutil_addrinfo hints;
1282
1283 memset(&hints,0,sizeof(hints));
1284 hints.ai_family = PF_UNSPEC;
1285 hints.ai_flags =
1286#ifdef AI_NUMERICHOST
1287 AI_NUMERICHOST |
1288#endif
1289#ifdef AI_NUMERICSERV
1290 AI_NUMERICSERV |
1291#endif
1292 0;
1293 r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001294 getaddrinfo("1.2.3.4", NULL, &hints, &ai3);
Christopher Wileye8679812015-07-01 13:36:18 -07001295 hints.ai_socktype = SOCK_STREAM;
1296 r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
1297 if (r2 == 0 && r != 0) {
1298 need_numeric_port_hack_=1;
1299 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001300 if (!ai_find_protocol(ai2) || !ai_find_protocol(ai3)) {
Christopher Wileye8679812015-07-01 13:36:18 -07001301 need_socktype_protocol_hack_=1;
1302 }
1303
1304 if (ai)
1305 freeaddrinfo(ai);
1306 if (ai2)
1307 freeaddrinfo(ai2);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001308 if (ai3)
1309 freeaddrinfo(ai3);
Christopher Wileye8679812015-07-01 13:36:18 -07001310 tested_for_getaddrinfo_hacks=1;
1311}
1312
1313static inline int
1314need_numeric_port_hack(void)
1315{
1316 if (!tested_for_getaddrinfo_hacks)
1317 test_for_getaddrinfo_hacks();
1318 return need_numeric_port_hack_;
1319}
1320
1321static inline int
1322need_socktype_protocol_hack(void)
1323{
1324 if (!tested_for_getaddrinfo_hacks)
1325 test_for_getaddrinfo_hacks();
1326 return need_socktype_protocol_hack_;
1327}
1328
1329static void
1330apply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
1331{
1332 /* Now we run through the list and set the ports on all of the
1333 * results where ports would make sense. */
1334 for ( ; *ai; ai = &(*ai)->ai_next) {
1335 struct sockaddr *sa = (*ai)->ai_addr;
1336 if (sa && sa->sa_family == AF_INET) {
1337 struct sockaddr_in *sin = (struct sockaddr_in*)sa;
1338 sin->sin_port = htons(port);
1339 } else if (sa && sa->sa_family == AF_INET6) {
1340 struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
1341 sin6->sin6_port = htons(port);
1342 } else {
1343 /* A numeric port makes no sense here; remove this one
1344 * from the list. */
1345 struct evutil_addrinfo *victim = *ai;
1346 *ai = victim->ai_next;
1347 victim->ai_next = NULL;
1348 freeaddrinfo(victim);
1349 }
1350 }
1351}
1352
1353static int
1354apply_socktype_protocol_hack(struct evutil_addrinfo *ai)
1355{
1356 struct evutil_addrinfo *ai_new;
1357 for (; ai; ai = ai->ai_next) {
1358 evutil_getaddrinfo_infer_protocols(ai);
1359 if (ai->ai_socktype || ai->ai_protocol)
1360 continue;
1361 ai_new = mm_malloc(sizeof(*ai_new));
1362 if (!ai_new)
1363 return -1;
1364 memcpy(ai_new, ai, sizeof(*ai_new));
1365 ai->ai_socktype = SOCK_STREAM;
1366 ai->ai_protocol = IPPROTO_TCP;
1367 ai_new->ai_socktype = SOCK_DGRAM;
1368 ai_new->ai_protocol = IPPROTO_UDP;
1369
1370 ai_new->ai_next = ai->ai_next;
1371 ai->ai_next = ai_new;
1372 }
1373 return 0;
1374}
1375#endif
1376
1377int
1378evutil_getaddrinfo(const char *nodename, const char *servname,
1379 const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
1380{
1381#ifdef USE_NATIVE_GETADDRINFO
1382 struct evutil_addrinfo hints;
1383 int portnum=-1, need_np_hack, err;
1384
1385 if (hints_in) {
1386 memcpy(&hints, hints_in, sizeof(hints));
1387 } else {
1388 memset(&hints, 0, sizeof(hints));
1389 hints.ai_family = PF_UNSPEC;
1390 }
1391
1392#ifndef AI_ADDRCONFIG
1393 /* Not every system has AI_ADDRCONFIG, so fake it. */
1394 if (hints.ai_family == PF_UNSPEC &&
1395 (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001396 evutil_adjust_hints_for_addrconfig_(&hints);
Christopher Wileye8679812015-07-01 13:36:18 -07001397 }
1398#endif
1399
1400#ifndef AI_NUMERICSERV
1401 /* Not every system has AI_NUMERICSERV, so fake it. */
1402 if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
1403 if (servname && parse_numeric_servname(servname)<0)
1404 return EVUTIL_EAI_NONAME;
1405 }
1406#endif
1407
1408 /* Enough operating systems handle enough common non-resolve
1409 * cases here weirdly enough that we are better off just
1410 * overriding them. For example:
1411 *
1412 * - Windows doesn't like to infer the protocol from the
1413 * socket type, or fill in socket or protocol types much at
1414 * all. It also seems to do its own broken implicit
1415 * always-on version of AI_ADDRCONFIG that keeps it from
1416 * ever resolving even a literal IPv6 address when
1417 * ai_addrtype is PF_UNSPEC.
1418 */
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001419#ifdef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -07001420 {
1421 int tmp_port;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001422 err = evutil_getaddrinfo_common_(nodename,servname,&hints,
Christopher Wileye8679812015-07-01 13:36:18 -07001423 res, &tmp_port);
1424 if (err == 0 ||
1425 err == EVUTIL_EAI_MEMORY ||
1426 err == EVUTIL_EAI_NONAME)
1427 return err;
1428 /* If we make it here, the system getaddrinfo can
1429 * have a crack at it. */
1430 }
1431#endif
1432
1433 /* See documentation for need_numeric_port_hack above.*/
1434 need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
1435 && ((portnum=parse_numeric_servname(servname)) >= 0);
1436 if (need_np_hack) {
1437 if (!nodename)
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001438 return evutil_getaddrinfo_common_(
Christopher Wileye8679812015-07-01 13:36:18 -07001439 NULL,servname,&hints, res, &portnum);
1440 servname = NULL;
1441 }
1442
1443 if (need_socktype_protocol_hack()) {
1444 evutil_getaddrinfo_infer_protocols(&hints);
1445 }
1446
1447 /* Make sure that we didn't actually steal any AI_FLAGS values that
1448 * the system is using. (This is a constant expression, and should ge
1449 * optimized out.)
1450 *
1451 * XXXX Turn this into a compile-time failure rather than a run-time
1452 * failure.
1453 */
1454 EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
1455
1456 /* Clear any flags that only libevent understands. */
1457 hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
1458
1459 err = getaddrinfo(nodename, servname, &hints, res);
1460 if (need_np_hack)
1461 apply_numeric_port_hack(portnum, res);
1462
1463 if (need_socktype_protocol_hack()) {
1464 if (apply_socktype_protocol_hack(*res) < 0) {
1465 evutil_freeaddrinfo(*res);
1466 *res = NULL;
1467 return EVUTIL_EAI_MEMORY;
1468 }
1469 }
1470 return err;
1471#else
1472 int port=0, err;
1473 struct hostent *ent = NULL;
1474 struct evutil_addrinfo hints;
1475
1476 if (hints_in) {
1477 memcpy(&hints, hints_in, sizeof(hints));
1478 } else {
1479 memset(&hints, 0, sizeof(hints));
1480 hints.ai_family = PF_UNSPEC;
1481 }
1482
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001483 evutil_adjust_hints_for_addrconfig_(&hints);
Christopher Wileye8679812015-07-01 13:36:18 -07001484
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001485 err = evutil_getaddrinfo_common_(nodename, servname, &hints, res, &port);
Christopher Wileye8679812015-07-01 13:36:18 -07001486 if (err != EVUTIL_EAI_NEED_RESOLVE) {
1487 /* We either succeeded or failed. No need to continue */
1488 return err;
1489 }
1490
1491 err = 0;
1492 /* Use any of the various gethostbyname_r variants as available. */
1493 {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001494#ifdef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG
Christopher Wileye8679812015-07-01 13:36:18 -07001495 /* This one is what glibc provides. */
1496 char buf[2048];
1497 struct hostent hostent;
1498 int r;
1499 r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
1500 &err);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001501#elif defined(EVENT__HAVE_GETHOSTBYNAME_R_5_ARG)
Christopher Wileye8679812015-07-01 13:36:18 -07001502 char buf[2048];
1503 struct hostent hostent;
1504 ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
1505 &err);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001506#elif defined(EVENT__HAVE_GETHOSTBYNAME_R_3_ARG)
Christopher Wileye8679812015-07-01 13:36:18 -07001507 struct hostent_data data;
1508 struct hostent hostent;
1509 memset(&data, 0, sizeof(data));
1510 err = gethostbyname_r(nodename, &hostent, &data);
1511 ent = err ? NULL : &hostent;
1512#else
1513 /* fall back to gethostbyname. */
1514 /* XXXX This needs a lock everywhere but Windows. */
1515 ent = gethostbyname(nodename);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001516#ifdef _WIN32
Christopher Wileye8679812015-07-01 13:36:18 -07001517 err = WSAGetLastError();
1518#else
1519 err = h_errno;
1520#endif
1521#endif
1522
1523 /* Now we have either ent or err set. */
1524 if (!ent) {
1525 /* XXX is this right for windows ? */
1526 switch (err) {
1527 case TRY_AGAIN:
1528 return EVUTIL_EAI_AGAIN;
1529 case NO_RECOVERY:
1530 default:
1531 return EVUTIL_EAI_FAIL;
1532 case HOST_NOT_FOUND:
1533 return EVUTIL_EAI_NONAME;
1534 case NO_ADDRESS:
1535#if NO_DATA != NO_ADDRESS
1536 case NO_DATA:
1537#endif
1538 return EVUTIL_EAI_NODATA;
1539 }
1540 }
1541
1542 if (ent->h_addrtype != hints.ai_family &&
1543 hints.ai_family != PF_UNSPEC) {
1544 /* This wasn't the type we were hoping for. Too bad
1545 * we never had a chance to ask gethostbyname for what
1546 * we wanted. */
1547 return EVUTIL_EAI_NONAME;
1548 }
1549
1550 /* Make sure we got _some_ answers. */
1551 if (ent->h_length == 0)
1552 return EVUTIL_EAI_NODATA;
1553
1554 /* If we got an address type we don't know how to make a
1555 sockaddr for, give up. */
1556 if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
1557 return EVUTIL_EAI_FAMILY;
1558
1559 *res = addrinfo_from_hostent(ent, port, &hints);
1560 if (! *res)
1561 return EVUTIL_EAI_MEMORY;
1562 }
1563
1564 return 0;
1565#endif
1566}
1567
1568void
1569evutil_freeaddrinfo(struct evutil_addrinfo *ai)
1570{
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001571#ifdef EVENT__HAVE_GETADDRINFO
Christopher Wileye8679812015-07-01 13:36:18 -07001572 if (!(ai->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED)) {
1573 freeaddrinfo(ai);
1574 return;
1575 }
1576#endif
1577 while (ai) {
1578 struct evutil_addrinfo *next = ai->ai_next;
1579 if (ai->ai_canonname)
1580 mm_free(ai->ai_canonname);
1581 mm_free(ai);
1582 ai = next;
1583 }
1584}
1585
1586static evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001587static evdns_getaddrinfo_cancel_fn evdns_getaddrinfo_cancel_impl = NULL;
Christopher Wileye8679812015-07-01 13:36:18 -07001588
1589void
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001590evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn)
Christopher Wileye8679812015-07-01 13:36:18 -07001591{
1592 if (!evdns_getaddrinfo_impl)
1593 evdns_getaddrinfo_impl = fn;
1594}
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001595void
1596evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn)
1597{
1598 if (!evdns_getaddrinfo_cancel_impl)
1599 evdns_getaddrinfo_cancel_impl = fn;
1600}
Christopher Wileye8679812015-07-01 13:36:18 -07001601
1602/* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
1603 * otherwise do a blocking resolve and pass the result to the callback in the
1604 * way that evdns_getaddrinfo would.
1605 */
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001606struct evdns_getaddrinfo_request *evutil_getaddrinfo_async_(
1607 struct evdns_base *dns_base,
Christopher Wileye8679812015-07-01 13:36:18 -07001608 const char *nodename, const char *servname,
1609 const struct evutil_addrinfo *hints_in,
1610 void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
1611{
1612 if (dns_base && evdns_getaddrinfo_impl) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001613 return evdns_getaddrinfo_impl(
Christopher Wileye8679812015-07-01 13:36:18 -07001614 dns_base, nodename, servname, hints_in, cb, arg);
1615 } else {
1616 struct evutil_addrinfo *ai=NULL;
1617 int err;
1618 err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
1619 cb(err, ai, arg);
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001620 return NULL;
Christopher Wileye8679812015-07-01 13:36:18 -07001621 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001622}
1623
1624void evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request *data)
1625{
1626 if (evdns_getaddrinfo_cancel_impl && data) {
1627 evdns_getaddrinfo_cancel_impl(data);
1628 }
Christopher Wileye8679812015-07-01 13:36:18 -07001629}
1630
1631const char *
1632evutil_gai_strerror(int err)
1633{
1634 /* As a sneaky side-benefit, this case statement will get most
1635 * compilers to tell us if any of the error codes we defined
1636 * conflict with the platform's native error codes. */
1637 switch (err) {
1638 case EVUTIL_EAI_CANCEL:
1639 return "Request canceled";
1640 case 0:
1641 return "No error";
1642
1643 case EVUTIL_EAI_ADDRFAMILY:
1644 return "address family for nodename not supported";
1645 case EVUTIL_EAI_AGAIN:
1646 return "temporary failure in name resolution";
1647 case EVUTIL_EAI_BADFLAGS:
1648 return "invalid value for ai_flags";
1649 case EVUTIL_EAI_FAIL:
1650 return "non-recoverable failure in name resolution";
1651 case EVUTIL_EAI_FAMILY:
1652 return "ai_family not supported";
1653 case EVUTIL_EAI_MEMORY:
1654 return "memory allocation failure";
1655 case EVUTIL_EAI_NODATA:
1656 return "no address associated with nodename";
1657 case EVUTIL_EAI_NONAME:
1658 return "nodename nor servname provided, or not known";
1659 case EVUTIL_EAI_SERVICE:
1660 return "servname not supported for ai_socktype";
1661 case EVUTIL_EAI_SOCKTYPE:
1662 return "ai_socktype not supported";
1663 case EVUTIL_EAI_SYSTEM:
1664 return "system error";
1665 default:
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001666#if defined(USE_NATIVE_GETADDRINFO) && defined(_WIN32)
Christopher Wileye8679812015-07-01 13:36:18 -07001667 return gai_strerrorA(err);
1668#elif defined(USE_NATIVE_GETADDRINFO)
1669 return gai_strerror(err);
1670#else
1671 return "Unknown error code";
1672#endif
1673 }
1674}
1675
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001676#ifdef _WIN32
1677/* destructively remove a trailing line terminator from s */
1678static void
1679chomp (char *s)
1680{
1681 size_t len;
1682 if (s && (len = strlen (s)) > 0 && s[len - 1] == '\n') {
1683 s[--len] = 0;
1684 if (len > 0 && s[len - 1] == '\r')
1685 s[--len] = 0;
1686 }
1687}
Christopher Wileye8679812015-07-01 13:36:18 -07001688
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001689/* FormatMessage returns allocated strings, but evutil_socket_error_to_string
1690 * is supposed to return a string which is good indefinitely without having
1691 * to be freed. To make this work without leaking memory, we cache the
1692 * string the first time FormatMessage is called on a particular error
1693 * code, and then return the cached string on subsequent calls with the
1694 * same code. The strings aren't freed until libevent_global_shutdown
1695 * (or never). We use a linked list to cache the errors, because we
1696 * only expect there to be a few dozen, and that should be fast enough.
1697 */
Elliott Hughes2a572d12017-08-07 14:18:18 -07001698
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001699struct cached_sock_errs_entry {
1700 HT_ENTRY(cached_sock_errs_entry) node;
1701 DWORD code;
1702 char *msg; /* allocated with LocalAlloc; free with LocalFree */
Josh Gao83a0c9c2017-08-10 12:30:25 -07001703};
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001704
1705static inline unsigned
1706hash_cached_sock_errs(const struct cached_sock_errs_entry *e)
1707{
1708 /* Use Murmur3's 32-bit finalizer as an integer hash function */
1709 DWORD h = e->code;
1710 h ^= h >> 16;
1711 h *= 0x85ebca6b;
1712 h ^= h >> 13;
1713 h *= 0xc2b2ae35;
1714 h ^= h >> 16;
1715 return h;
1716}
1717
1718static inline int
1719eq_cached_sock_errs(const struct cached_sock_errs_entry *a,
1720 const struct cached_sock_errs_entry *b)
1721{
1722 return a->code == b->code;
1723}
1724
1725#ifndef EVENT__DISABLE_THREAD_SUPPORT
1726static void *windows_socket_errors_lock_ = NULL;
1727#endif
1728
1729static HT_HEAD(cached_sock_errs_map, cached_sock_errs_entry)
1730 windows_socket_errors = HT_INITIALIZER();
1731
1732HT_PROTOTYPE(cached_sock_errs_map,
1733 cached_sock_errs_entry,
1734 node,
1735 hash_cached_sock_errs,
1736 eq_cached_sock_errs);
1737
1738HT_GENERATE(cached_sock_errs_map,
1739 cached_sock_errs_entry,
1740 node,
1741 hash_cached_sock_errs,
1742 eq_cached_sock_errs,
1743 0.5,
1744 mm_malloc,
1745 mm_realloc,
1746 mm_free);
1747
Christopher Wileye8679812015-07-01 13:36:18 -07001748/** Equivalent to strerror, but for windows socket errors. */
1749const char *
1750evutil_socket_error_to_string(int errcode)
1751{
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001752 struct cached_sock_errs_entry *errs, *newerr, find;
1753 char *msg = NULL;
1754
1755 EVLOCK_LOCK(windows_socket_errors_lock_, 0);
1756
1757 find.code = errcode;
1758 errs = HT_FIND(cached_sock_errs_map, &windows_socket_errors, &find);
1759 if (errs) {
1760 msg = errs->msg;
1761 goto done;
1762 }
1763
1764 if (0 != FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
1765 FORMAT_MESSAGE_IGNORE_INSERTS |
1766 FORMAT_MESSAGE_ALLOCATE_BUFFER,
1767 NULL, errcode, 0, (char *)&msg, 0, NULL))
1768 chomp (msg); /* because message has trailing newline */
1769 else {
1770 size_t len = 50;
1771 /* use LocalAlloc because FormatMessage does */
1772 msg = LocalAlloc(LMEM_FIXED, len);
1773 if (!msg) {
1774 msg = (char *)"LocalAlloc failed during Winsock error";
1775 goto done;
1776 }
1777 evutil_snprintf(msg, len, "winsock error 0x%08x", errcode);
1778 }
1779
1780 newerr = (struct cached_sock_errs_entry *)
1781 mm_malloc(sizeof (struct cached_sock_errs_entry));
1782
1783 if (!newerr) {
1784 LocalFree(msg);
1785 msg = (char *)"malloc failed during Winsock error";
1786 goto done;
1787 }
1788
1789 newerr->code = errcode;
1790 newerr->msg = msg;
1791 HT_INSERT(cached_sock_errs_map, &windows_socket_errors, newerr);
1792
1793 done:
1794 EVLOCK_UNLOCK(windows_socket_errors_lock_, 0);
1795
1796 return msg;
Christopher Wileye8679812015-07-01 13:36:18 -07001797}
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001798
1799#ifndef EVENT__DISABLE_THREAD_SUPPORT
1800int
1801evutil_global_setup_locks_(const int enable_locks)
1802{
1803 EVTHREAD_SETUP_GLOBAL_LOCK(windows_socket_errors_lock_, 0);
1804 return 0;
1805}
1806#endif
1807
1808static void
1809evutil_free_sock_err_globals(void)
1810{
1811 struct cached_sock_errs_entry **errs, *tofree;
1812
1813 for (errs = HT_START(cached_sock_errs_map, &windows_socket_errors)
1814 ; errs; ) {
1815 tofree = *errs;
1816 errs = HT_NEXT_RMV(cached_sock_errs_map,
1817 &windows_socket_errors,
1818 errs);
1819 LocalFree(tofree->msg);
1820 mm_free(tofree);
1821 }
1822
1823 HT_CLEAR(cached_sock_errs_map, &windows_socket_errors);
1824
1825#ifndef EVENT__DISABLE_THREAD_SUPPORT
1826 if (windows_socket_errors_lock_ != NULL) {
1827 EVTHREAD_FREE_LOCK(windows_socket_errors_lock_, 0);
1828 windows_socket_errors_lock_ = NULL;
1829 }
1830#endif
1831}
1832
1833#else
1834
1835#ifndef EVENT__DISABLE_THREAD_SUPPORT
1836int
1837evutil_global_setup_locks_(const int enable_locks)
1838{
1839 return 0;
1840}
1841#endif
1842
1843static void
1844evutil_free_sock_err_globals(void)
1845{
1846}
1847
Christopher Wileye8679812015-07-01 13:36:18 -07001848#endif
1849
1850int
1851evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
1852{
1853 int r;
1854 va_list ap;
1855 va_start(ap, format);
1856 r = evutil_vsnprintf(buf, buflen, format, ap);
1857 va_end(ap);
1858 return r;
1859}
1860
1861int
1862evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
1863{
1864 int r;
1865 if (!buflen)
1866 return 0;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001867#if defined(_MSC_VER) || defined(_WIN32)
Christopher Wileye8679812015-07-01 13:36:18 -07001868 r = _vsnprintf(buf, buflen, format, ap);
1869 if (r < 0)
1870 r = _vscprintf(format, ap);
1871#elif defined(sgi)
1872 /* Make sure we always use the correct vsnprintf on IRIX */
1873 extern int _xpg5_vsnprintf(char * __restrict,
1874 __SGI_LIBC_NAMESPACE_QUALIFIER size_t,
1875 const char * __restrict, /* va_list */ char *);
1876
1877 r = _xpg5_vsnprintf(buf, buflen, format, ap);
1878#else
1879 r = vsnprintf(buf, buflen, format, ap);
1880#endif
1881 buf[buflen-1] = '\0';
1882 return r;
1883}
1884
1885#define USE_INTERNAL_NTOP
1886#define USE_INTERNAL_PTON
1887
1888const char *
1889evutil_inet_ntop(int af, const void *src, char *dst, size_t len)
1890{
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001891#if defined(EVENT__HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
Christopher Wileye8679812015-07-01 13:36:18 -07001892 return inet_ntop(af, src, dst, len);
1893#else
1894 if (af == AF_INET) {
1895 const struct in_addr *in = src;
1896 const ev_uint32_t a = ntohl(in->s_addr);
1897 int r;
1898 r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
1899 (int)(ev_uint8_t)((a>>24)&0xff),
1900 (int)(ev_uint8_t)((a>>16)&0xff),
1901 (int)(ev_uint8_t)((a>>8 )&0xff),
1902 (int)(ev_uint8_t)((a )&0xff));
1903 if (r<0||(size_t)r>=len)
1904 return NULL;
1905 else
1906 return dst;
1907#ifdef AF_INET6
1908 } else if (af == AF_INET6) {
1909 const struct in6_addr *addr = src;
1910 char buf[64], *cp;
1911 int longestGapLen = 0, longestGapPos = -1, i,
1912 curGapPos = -1, curGapLen = 0;
1913 ev_uint16_t words[8];
1914 for (i = 0; i < 8; ++i) {
1915 words[i] =
1916 (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
1917 }
1918 if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
1919 words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
1920 (words[5] == 0xffff))) {
1921 /* This is an IPv4 address. */
1922 if (words[5] == 0) {
1923 evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
1924 addr->s6_addr[12], addr->s6_addr[13],
1925 addr->s6_addr[14], addr->s6_addr[15]);
1926 } else {
1927 evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
1928 addr->s6_addr[12], addr->s6_addr[13],
1929 addr->s6_addr[14], addr->s6_addr[15]);
1930 }
1931 if (strlen(buf) > len)
1932 return NULL;
1933 strlcpy(dst, buf, len);
1934 return dst;
1935 }
1936 i = 0;
1937 while (i < 8) {
1938 if (words[i] == 0) {
1939 curGapPos = i++;
1940 curGapLen = 1;
1941 while (i<8 && words[i] == 0) {
1942 ++i; ++curGapLen;
1943 }
1944 if (curGapLen > longestGapLen) {
1945 longestGapPos = curGapPos;
1946 longestGapLen = curGapLen;
1947 }
1948 } else {
1949 ++i;
1950 }
1951 }
1952 if (longestGapLen<=1)
1953 longestGapPos = -1;
1954
1955 cp = buf;
1956 for (i = 0; i < 8; ++i) {
1957 if (words[i] == 0 && longestGapPos == i) {
1958 if (i == 0)
1959 *cp++ = ':';
1960 *cp++ = ':';
1961 while (i < 8 && words[i] == 0)
1962 ++i;
1963 --i; /* to compensate for loop increment. */
1964 } else {
1965 evutil_snprintf(cp,
1966 sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
1967 cp += strlen(cp);
1968 if (i != 7)
1969 *cp++ = ':';
1970 }
1971 }
1972 *cp = '\0';
1973 if (strlen(buf) > len)
1974 return NULL;
1975 strlcpy(dst, buf, len);
1976 return dst;
1977#endif
1978 } else {
1979 return NULL;
1980 }
1981#endif
1982}
1983
1984int
1985evutil_inet_pton(int af, const char *src, void *dst)
1986{
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001987#if defined(EVENT__HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
Christopher Wileye8679812015-07-01 13:36:18 -07001988 return inet_pton(af, src, dst);
1989#else
1990 if (af == AF_INET) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001991 unsigned a,b,c,d;
Christopher Wileye8679812015-07-01 13:36:18 -07001992 char more;
1993 struct in_addr *addr = dst;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001994 if (sscanf(src, "%u.%u.%u.%u%c", &a,&b,&c,&d,&more) != 4)
Christopher Wileye8679812015-07-01 13:36:18 -07001995 return 0;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01001996 if (a > 255) return 0;
1997 if (b > 255) return 0;
1998 if (c > 255) return 0;
1999 if (d > 255) return 0;
Christopher Wileye8679812015-07-01 13:36:18 -07002000 addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
2001 return 1;
2002#ifdef AF_INET6
2003 } else if (af == AF_INET6) {
2004 struct in6_addr *out = dst;
2005 ev_uint16_t words[8];
2006 int gapPos = -1, i, setWords=0;
2007 const char *dot = strchr(src, '.');
2008 const char *eow; /* end of words. */
2009 if (dot == src)
2010 return 0;
2011 else if (!dot)
2012 eow = src+strlen(src);
2013 else {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002014 unsigned byte1,byte2,byte3,byte4;
Christopher Wileye8679812015-07-01 13:36:18 -07002015 char more;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002016 for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT_(*eow); --eow)
Christopher Wileye8679812015-07-01 13:36:18 -07002017 ;
2018 ++eow;
2019
2020 /* We use "scanf" because some platform inet_aton()s are too lax
2021 * about IPv4 addresses of the form "1.2.3" */
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002022 if (sscanf(eow, "%u.%u.%u.%u%c",
Christopher Wileye8679812015-07-01 13:36:18 -07002023 &byte1,&byte2,&byte3,&byte4,&more) != 4)
2024 return 0;
2025
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002026 if (byte1 > 255 ||
2027 byte2 > 255 ||
2028 byte3 > 255 ||
2029 byte4 > 255)
Christopher Wileye8679812015-07-01 13:36:18 -07002030 return 0;
2031
2032 words[6] = (byte1<<8) | byte2;
2033 words[7] = (byte3<<8) | byte4;
2034 setWords += 2;
2035 }
2036
2037 i = 0;
2038 while (src < eow) {
2039 if (i > 7)
2040 return 0;
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002041 if (EVUTIL_ISXDIGIT_(*src)) {
Christopher Wileye8679812015-07-01 13:36:18 -07002042 char *next;
2043 long r = strtol(src, &next, 16);
2044 if (next > 4+src)
2045 return 0;
2046 if (next == src)
2047 return 0;
2048 if (r<0 || r>65536)
2049 return 0;
2050
2051 words[i++] = (ev_uint16_t)r;
2052 setWords++;
2053 src = next;
2054 if (*src != ':' && src != eow)
2055 return 0;
2056 ++src;
2057 } else if (*src == ':' && i > 0 && gapPos==-1) {
2058 gapPos = i;
2059 ++src;
2060 } else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
2061 gapPos = i;
2062 src += 2;
2063 } else {
2064 return 0;
2065 }
2066 }
2067
2068 if (setWords > 8 ||
2069 (setWords == 8 && gapPos != -1) ||
2070 (setWords < 8 && gapPos == -1))
2071 return 0;
2072
2073 if (gapPos >= 0) {
2074 int nToMove = setWords - (dot ? 2 : 0) - gapPos;
2075 int gapLen = 8 - setWords;
2076 /* assert(nToMove >= 0); */
2077 if (nToMove < 0)
2078 return -1; /* should be impossible */
2079 memmove(&words[gapPos+gapLen], &words[gapPos],
2080 sizeof(ev_uint16_t)*nToMove);
2081 memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
2082 }
2083 for (i = 0; i < 8; ++i) {
2084 out->s6_addr[2*i ] = words[i] >> 8;
2085 out->s6_addr[2*i+1] = words[i] & 0xff;
2086 }
2087
2088 return 1;
2089#endif
2090 } else {
2091 return -1;
2092 }
2093#endif
2094}
2095
2096int
2097evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
2098{
2099 int port;
2100 char buf[128];
2101 const char *cp, *addr_part, *port_part;
2102 int is_ipv6;
2103 /* recognized formats are:
2104 * [ipv6]:port
2105 * ipv6
2106 * [ipv6]
2107 * ipv4:port
2108 * ipv4
2109 */
2110
2111 cp = strchr(ip_as_string, ':');
2112 if (*ip_as_string == '[') {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002113 size_t len;
Christopher Wileye8679812015-07-01 13:36:18 -07002114 if (!(cp = strchr(ip_as_string, ']'))) {
2115 return -1;
2116 }
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002117 len = ( cp-(ip_as_string + 1) );
2118 if (len > sizeof(buf)-1) {
Christopher Wileye8679812015-07-01 13:36:18 -07002119 return -1;
2120 }
2121 memcpy(buf, ip_as_string+1, len);
2122 buf[len] = '\0';
2123 addr_part = buf;
2124 if (cp[1] == ':')
2125 port_part = cp+2;
2126 else
2127 port_part = NULL;
2128 is_ipv6 = 1;
2129 } else if (cp && strchr(cp+1, ':')) {
2130 is_ipv6 = 1;
2131 addr_part = ip_as_string;
2132 port_part = NULL;
2133 } else if (cp) {
2134 is_ipv6 = 0;
2135 if (cp - ip_as_string > (int)sizeof(buf)-1) {
2136 return -1;
2137 }
2138 memcpy(buf, ip_as_string, cp-ip_as_string);
2139 buf[cp-ip_as_string] = '\0';
2140 addr_part = buf;
2141 port_part = cp+1;
2142 } else {
2143 addr_part = ip_as_string;
2144 port_part = NULL;
2145 is_ipv6 = 0;
2146 }
2147
2148 if (port_part == NULL) {
2149 port = 0;
2150 } else {
2151 port = atoi(port_part);
2152 if (port <= 0 || port > 65535) {
2153 return -1;
2154 }
2155 }
2156
2157 if (!addr_part)
2158 return -1; /* Should be impossible. */
2159#ifdef AF_INET6
2160 if (is_ipv6)
2161 {
2162 struct sockaddr_in6 sin6;
2163 memset(&sin6, 0, sizeof(sin6));
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002164#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
Christopher Wileye8679812015-07-01 13:36:18 -07002165 sin6.sin6_len = sizeof(sin6);
2166#endif
2167 sin6.sin6_family = AF_INET6;
2168 sin6.sin6_port = htons(port);
2169 if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr))
2170 return -1;
2171 if ((int)sizeof(sin6) > *outlen)
2172 return -1;
2173 memset(out, 0, *outlen);
2174 memcpy(out, &sin6, sizeof(sin6));
2175 *outlen = sizeof(sin6);
2176 return 0;
2177 }
2178 else
2179#endif
2180 {
2181 struct sockaddr_in sin;
2182 memset(&sin, 0, sizeof(sin));
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002183#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
Christopher Wileye8679812015-07-01 13:36:18 -07002184 sin.sin_len = sizeof(sin);
2185#endif
2186 sin.sin_family = AF_INET;
2187 sin.sin_port = htons(port);
2188 if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
2189 return -1;
2190 if ((int)sizeof(sin) > *outlen)
2191 return -1;
2192 memset(out, 0, *outlen);
2193 memcpy(out, &sin, sizeof(sin));
2194 *outlen = sizeof(sin);
2195 return 0;
2196 }
2197}
2198
2199const char *
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002200evutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen)
Christopher Wileye8679812015-07-01 13:36:18 -07002201{
2202 char b[128];
2203 const char *res=NULL;
2204 int port;
2205 if (sa->sa_family == AF_INET) {
2206 const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
2207 res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
2208 port = ntohs(sin->sin_port);
2209 if (res) {
2210 evutil_snprintf(out, outlen, "%s:%d", b, port);
2211 return out;
2212 }
2213 } else if (sa->sa_family == AF_INET6) {
2214 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
2215 res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
2216 port = ntohs(sin6->sin6_port);
2217 if (res) {
2218 evutil_snprintf(out, outlen, "[%s]:%d", b, port);
2219 return out;
2220 }
2221 }
2222
2223 evutil_snprintf(out, outlen, "<addr with socktype %d>",
2224 (int)sa->sa_family);
2225 return out;
2226}
2227
2228int
2229evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
2230 int include_port)
2231{
2232 int r;
2233 if (0 != (r = (sa1->sa_family - sa2->sa_family)))
2234 return r;
2235
2236 if (sa1->sa_family == AF_INET) {
2237 const struct sockaddr_in *sin1, *sin2;
2238 sin1 = (const struct sockaddr_in *)sa1;
2239 sin2 = (const struct sockaddr_in *)sa2;
2240 if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
2241 return -1;
2242 else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
2243 return 1;
2244 else if (include_port &&
2245 (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
2246 return r;
2247 else
2248 return 0;
2249 }
2250#ifdef AF_INET6
2251 else if (sa1->sa_family == AF_INET6) {
2252 const struct sockaddr_in6 *sin1, *sin2;
2253 sin1 = (const struct sockaddr_in6 *)sa1;
2254 sin2 = (const struct sockaddr_in6 *)sa2;
2255 if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
2256 return r;
2257 else if (include_port &&
2258 (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
2259 return r;
2260 else
2261 return 0;
2262 }
2263#endif
2264 return 1;
2265}
2266
2267/* Tables to implement ctypes-replacement EVUTIL_IS*() functions. Each table
2268 * has 256 bits to look up whether a character is in some set or not. This
2269 * fails on non-ASCII platforms, but so does every other place where we
2270 * take a char and write it onto the network.
2271 **/
2272static const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
2273 { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
2274static const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
2275 { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
2276static const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
2277static const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
2278 { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
2279static const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
2280static const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
2281 { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
2282static const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
2283static const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
2284/* Upper-casing and lowercasing tables to map characters to upper/lowercase
2285 * equivalents. */
2286static const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
2287 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2288 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2289 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2290 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2291 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2292 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
2293 96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2294 80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
2295 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2296 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2297 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2298 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2299 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2300 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2301 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2302 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2303};
2304static const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
2305 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2306 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2307 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2308 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2309 64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2310 112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
2311 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2312 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
2313 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2314 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2315 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2316 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2317 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2318 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2319 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2320 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2321};
2322
2323#define IMPL_CTYPE_FN(name) \
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002324 int EVUTIL_##name##_(char c) { \
Christopher Wileye8679812015-07-01 13:36:18 -07002325 ev_uint8_t u = c; \
2326 return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
2327 }
2328IMPL_CTYPE_FN(ISALPHA)
2329IMPL_CTYPE_FN(ISALNUM)
2330IMPL_CTYPE_FN(ISSPACE)
2331IMPL_CTYPE_FN(ISDIGIT)
2332IMPL_CTYPE_FN(ISXDIGIT)
2333IMPL_CTYPE_FN(ISPRINT)
2334IMPL_CTYPE_FN(ISLOWER)
2335IMPL_CTYPE_FN(ISUPPER)
2336
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002337char EVUTIL_TOLOWER_(char c)
Christopher Wileye8679812015-07-01 13:36:18 -07002338{
2339 return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
2340}
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002341char EVUTIL_TOUPPER_(char c)
Christopher Wileye8679812015-07-01 13:36:18 -07002342{
2343 return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
2344}
2345int
2346evutil_ascii_strcasecmp(const char *s1, const char *s2)
2347{
2348 char c1, c2;
2349 while (1) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002350 c1 = EVUTIL_TOLOWER_(*s1++);
2351 c2 = EVUTIL_TOLOWER_(*s2++);
Christopher Wileye8679812015-07-01 13:36:18 -07002352 if (c1 < c2)
2353 return -1;
2354 else if (c1 > c2)
2355 return 1;
2356 else if (c1 == 0)
2357 return 0;
2358 }
2359}
2360int evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
2361{
2362 char c1, c2;
2363 while (n--) {
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002364 c1 = EVUTIL_TOLOWER_(*s1++);
2365 c2 = EVUTIL_TOLOWER_(*s2++);
Christopher Wileye8679812015-07-01 13:36:18 -07002366 if (c1 < c2)
2367 return -1;
2368 else if (c1 > c2)
2369 return 1;
2370 else if (c1 == 0)
2371 return 0;
2372 }
2373 return 0;
2374}
2375
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002376void
2377evutil_rtrim_lws_(char *str)
2378{
2379 char *cp;
2380
2381 if (str == NULL)
2382 return;
2383
2384 if ((cp = strchr(str, '\0')) == NULL || (cp == str))
2385 return;
2386
2387 --cp;
2388
2389 while (*cp == ' ' || *cp == '\t') {
2390 *cp = '\0';
2391 if (cp == str)
2392 break;
2393 --cp;
2394 }
2395}
2396
Christopher Wileye8679812015-07-01 13:36:18 -07002397static int
2398evutil_issetugid(void)
2399{
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002400#ifdef EVENT__HAVE_ISSETUGID
Christopher Wileye8679812015-07-01 13:36:18 -07002401 return issetugid();
2402#else
2403
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002404#ifdef EVENT__HAVE_GETEUID
Christopher Wileye8679812015-07-01 13:36:18 -07002405 if (getuid() != geteuid())
2406 return 1;
2407#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002408#ifdef EVENT__HAVE_GETEGID
Christopher Wileye8679812015-07-01 13:36:18 -07002409 if (getgid() != getegid())
2410 return 1;
2411#endif
2412 return 0;
2413#endif
2414}
2415
2416const char *
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002417evutil_getenv_(const char *varname)
Christopher Wileye8679812015-07-01 13:36:18 -07002418{
2419 if (evutil_issetugid())
2420 return NULL;
2421
2422 return getenv(varname);
2423}
2424
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002425ev_uint32_t
2426evutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed)
Christopher Wileye8679812015-07-01 13:36:18 -07002427{
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002428 if (seed == 0) {
2429 struct timeval tv;
2430 evutil_gettimeofday(&tv, NULL);
2431 seed = (ev_uint32_t)tv.tv_sec + (ev_uint32_t)tv.tv_usec;
2432#ifdef _WIN32
2433 seed += (ev_uint32_t) _getpid();
Christopher Wileye8679812015-07-01 13:36:18 -07002434#else
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002435 seed += (ev_uint32_t) getpid();
Christopher Wileye8679812015-07-01 13:36:18 -07002436#endif
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002437 }
2438 state->seed = seed;
2439 return seed;
2440}
2441
2442ev_int32_t
2443evutil_weakrand_(struct evutil_weakrand_state *state)
2444{
2445 /* This RNG implementation is a linear congruential generator, with
2446 * modulus 2^31, multiplier 1103515245, and addend 12345. It's also
2447 * used by OpenBSD, and by Glibc's TYPE_0 RNG.
2448 *
2449 * The linear congruential generator is not an industrial-strength
2450 * RNG! It's fast, but it can have higher-order patterns. Notably,
2451 * the low bits tend to have periodicity.
2452 */
2453 state->seed = ((state->seed) * 1103515245 + 12345) & 0x7fffffff;
2454 return (ev_int32_t)(state->seed);
2455}
2456
2457ev_int32_t
2458evutil_weakrand_range_(struct evutil_weakrand_state *state, ev_int32_t top)
2459{
2460 ev_int32_t divisor, result;
2461
2462 /* We can't just do weakrand() % top, since the low bits of the LCG
2463 * are less random than the high ones. (Specifically, since the LCG
2464 * modulus is 2^N, every 2^m for m<N will divide the modulus, and so
2465 * therefore the low m bits of the LCG will have period 2^m.) */
2466 divisor = EVUTIL_WEAKRAND_MAX / top;
2467 do {
2468 result = evutil_weakrand_(state) / divisor;
2469 } while (result >= top);
2470 return result;
Christopher Wileye8679812015-07-01 13:36:18 -07002471}
2472
2473/**
2474 * Volatile pointer to memset: we use this to keep the compiler from
2475 * eliminating our call to memset.
2476 */
2477void * (*volatile evutil_memset_volatile_)(void *, int, size_t) = memset;
2478
2479void
2480evutil_memclear_(void *mem, size_t len)
2481{
2482 evutil_memset_volatile_(mem, 0, len);
2483}
2484
2485int
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002486evutil_sockaddr_is_loopback_(const struct sockaddr *addr)
Christopher Wileye8679812015-07-01 13:36:18 -07002487{
2488 static const char LOOPBACK_S6[16] =
2489 "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
2490 if (addr->sa_family == AF_INET) {
2491 struct sockaddr_in *sin = (struct sockaddr_in *)addr;
2492 return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
2493 } else if (addr->sa_family == AF_INET6) {
2494 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
2495 return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
2496 }
2497 return 0;
2498}
2499
Christopher Wileye8679812015-07-01 13:36:18 -07002500int
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002501evutil_hex_char_to_int_(char c)
Christopher Wileye8679812015-07-01 13:36:18 -07002502{
2503 switch(c)
2504 {
2505 case '0': return 0;
2506 case '1': return 1;
2507 case '2': return 2;
2508 case '3': return 3;
2509 case '4': return 4;
2510 case '5': return 5;
2511 case '6': return 6;
2512 case '7': return 7;
2513 case '8': return 8;
2514 case '9': return 9;
2515 case 'A': case 'a': return 10;
2516 case 'B': case 'b': return 11;
2517 case 'C': case 'c': return 12;
2518 case 'D': case 'd': return 13;
2519 case 'E': case 'e': return 14;
2520 case 'F': case 'f': return 15;
2521 }
2522 return -1;
2523}
2524
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002525#ifdef _WIN32
2526HMODULE
2527evutil_load_windows_system_library_(const TCHAR *library_name)
Christopher Wileye8679812015-07-01 13:36:18 -07002528{
2529 TCHAR path[MAX_PATH];
2530 unsigned n;
2531 n = GetSystemDirectory(path, MAX_PATH);
2532 if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
2533 return 0;
2534 _tcscat(path, TEXT("\\"));
2535 _tcscat(path, library_name);
2536 return LoadLibrary(path);
2537}
2538#endif
2539
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002540/* Internal wrapper around 'socket' to provide Linux-style support for
2541 * syscall-saving methods where available.
2542 *
2543 * In addition to regular socket behavior, you can use a bitwise or to set the
2544 * flags EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'type' argument,
2545 * to make the socket nonblocking or close-on-exec with as few syscalls as
2546 * possible.
2547 */
2548evutil_socket_t
2549evutil_socket_(int domain, int type, int protocol)
2550{
2551 evutil_socket_t r;
2552#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
2553 r = socket(domain, type, protocol);
2554 if (r >= 0)
2555 return r;
2556 else if ((type & (SOCK_NONBLOCK|SOCK_CLOEXEC)) == 0)
2557 return -1;
2558#endif
2559#define SOCKET_TYPE_MASK (~(EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC))
2560 r = socket(domain, type & SOCKET_TYPE_MASK, protocol);
2561 if (r < 0)
2562 return -1;
2563 if (type & EVUTIL_SOCK_NONBLOCK) {
2564 if (evutil_fast_socket_nonblocking(r) < 0) {
2565 evutil_closesocket(r);
2566 return -1;
2567 }
2568 }
2569 if (type & EVUTIL_SOCK_CLOEXEC) {
2570 if (evutil_fast_socket_closeonexec(r) < 0) {
2571 evutil_closesocket(r);
2572 return -1;
2573 }
2574 }
2575 return r;
2576}
2577
2578/* Internal wrapper around 'accept' or 'accept4' to provide Linux-style
2579 * support for syscall-saving methods where available.
2580 *
2581 * In addition to regular accept behavior, you can set one or more of flags
2582 * EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'flags' argument, to
2583 * make the socket nonblocking or close-on-exec with as few syscalls as
2584 * possible.
2585 */
2586evutil_socket_t
2587evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
2588 ev_socklen_t *addrlen, int flags)
2589{
2590 evutil_socket_t result;
2591#if defined(EVENT__HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
2592 result = accept4(sockfd, addr, addrlen, flags);
2593 if (result >= 0 || (errno != EINVAL && errno != ENOSYS)) {
2594 /* A nonnegative result means that we succeeded, so return.
2595 * Failing with EINVAL means that an option wasn't supported,
2596 * and failing with ENOSYS means that the syscall wasn't
2597 * there: in those cases we want to fall back. Otherwise, we
2598 * got a real error, and we should return. */
2599 return result;
2600 }
2601#endif
2602 result = accept(sockfd, addr, addrlen);
2603 if (result < 0)
2604 return result;
2605
2606 if (flags & EVUTIL_SOCK_CLOEXEC) {
2607 if (evutil_fast_socket_closeonexec(result) < 0) {
2608 evutil_closesocket(result);
2609 return -1;
2610 }
2611 }
2612 if (flags & EVUTIL_SOCK_NONBLOCK) {
2613 if (evutil_fast_socket_nonblocking(result) < 0) {
2614 evutil_closesocket(result);
2615 return -1;
2616 }
2617 }
2618 return result;
2619}
2620
2621/* Internal function: Set fd[0] and fd[1] to a pair of fds such that writes on
Haibo Huangb2279672019-05-31 16:12:39 -07002622 * fd[1] get read from fd[0]. Make both fds nonblocking and close-on-exec.
Narayan Kamathfc74cb42017-09-13 12:53:52 +01002623 * Return 0 on success, -1 on failure.
2624 */
2625int
2626evutil_make_internal_pipe_(evutil_socket_t fd[2])
2627{
2628 /*
2629 Making the second socket nonblocking is a bit subtle, given that we
2630 ignore any EAGAIN returns when writing to it, and you don't usally
2631 do that for a nonblocking socket. But if the kernel gives us EAGAIN,
2632 then there's no need to add any more data to the buffer, since
2633 the main thread is already either about to wake up and drain it,
2634 or woken up and in the process of draining it.
2635 */
2636
2637#if defined(EVENT__HAVE_PIPE2)
2638 if (pipe2(fd, O_NONBLOCK|O_CLOEXEC) == 0)
2639 return 0;
2640#endif
2641#if defined(EVENT__HAVE_PIPE)
2642 if (pipe(fd) == 0) {
2643 if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
2644 evutil_fast_socket_nonblocking(fd[1]) < 0 ||
2645 evutil_fast_socket_closeonexec(fd[0]) < 0 ||
2646 evutil_fast_socket_closeonexec(fd[1]) < 0) {
2647 close(fd[0]);
2648 close(fd[1]);
2649 fd[0] = fd[1] = -1;
2650 return -1;
2651 }
2652 return 0;
2653 } else {
2654 event_warn("%s: pipe", __func__);
2655 }
2656#endif
2657
2658#ifdef _WIN32
2659#define LOCAL_SOCKETPAIR_AF AF_INET
2660#else
2661#define LOCAL_SOCKETPAIR_AF AF_UNIX
2662#endif
2663 if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM, 0, fd) == 0) {
2664 if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
2665 evutil_fast_socket_nonblocking(fd[1]) < 0 ||
2666 evutil_fast_socket_closeonexec(fd[0]) < 0 ||
2667 evutil_fast_socket_closeonexec(fd[1]) < 0) {
2668 evutil_closesocket(fd[0]);
2669 evutil_closesocket(fd[1]);
2670 fd[0] = fd[1] = -1;
2671 return -1;
2672 }
2673 return 0;
2674 }
2675 fd[0] = fd[1] = -1;
2676 return -1;
2677}
2678
2679/* Wrapper around eventfd on systems that provide it. Unlike the system
2680 * eventfd, it always supports EVUTIL_EFD_CLOEXEC and EVUTIL_EFD_NONBLOCK as
2681 * flags. Returns -1 on error or if eventfd is not supported.
2682 */
2683evutil_socket_t
2684evutil_eventfd_(unsigned initval, int flags)
2685{
2686#if defined(EVENT__HAVE_EVENTFD) && defined(EVENT__HAVE_SYS_EVENTFD_H)
2687 int r;
2688#if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
2689 r = eventfd(initval, flags);
2690 if (r >= 0 || flags == 0)
2691 return r;
2692#endif
2693 r = eventfd(initval, 0);
2694 if (r < 0)
2695 return r;
2696 if (flags & EVUTIL_EFD_CLOEXEC) {
2697 if (evutil_fast_socket_closeonexec(r) < 0) {
2698 evutil_closesocket(r);
2699 return -1;
2700 }
2701 }
2702 if (flags & EVUTIL_EFD_NONBLOCK) {
2703 if (evutil_fast_socket_nonblocking(r) < 0) {
2704 evutil_closesocket(r);
2705 return -1;
2706 }
2707 }
2708 return r;
2709#else
2710 return -1;
2711#endif
2712}
2713
2714void
2715evutil_free_globals_(void)
2716{
2717 evutil_free_secure_rng_globals_();
2718 evutil_free_sock_err_globals();
2719}