Coverage Report

Created: 2025-08-26 06:08

/src/libevent/evutil.c
Line
Count
Source (jump to first uncovered line)
1
/*
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
#ifdef _WIN32
28
#ifndef _WIN32_WINNT
29
/* For structs needed by GetAdaptersAddresses and AI_NUMERICSERV */
30
#define _WIN32_WINNT 0x0600
31
#endif
32
#define WIN32_LEAN_AND_MEAN
33
#endif
34
35
#include "event2/event-config.h"
36
#include "evconfig-private.h"
37
38
#ifdef _WIN32
39
#include <winsock2.h>
40
#include <winerror.h>
41
#include <ws2tcpip.h>
42
#ifdef _MSC_VER /* mstcpip.h is missing on MinGW */
43
#include <mstcpip.h> /* for SIO_KEEPALIVE_VALS and tcp_keepalive struct */
44
#endif
45
#ifdef EVENT__HAVE_AFUNIX_H
46
#include <afunix.h>
47
#endif
48
#include <windows.h>
49
#include <io.h>
50
#include <tchar.h>
51
#include <process.h>
52
#include <iphlpapi.h>
53
#include <netioapi.h>
54
#endif
55
56
#ifdef EVENT__HAVE_SYS_PARAM_H
57
#include <sys/param.h>
58
#endif
59
#include <sys/types.h>
60
#ifdef EVENT__HAVE_SYS_SOCKET_H
61
#include <sys/socket.h>
62
#endif
63
#ifdef EVENT__HAVE_UNISTD_H
64
#include <unistd.h>
65
#endif
66
#ifdef EVENT__HAVE_FCNTL_H
67
#include <fcntl.h>
68
#endif
69
#ifdef EVENT__HAVE_STDLIB_H
70
#include <stdlib.h>
71
#endif
72
#include <errno.h>
73
#include <limits.h>
74
#include <stdio.h>
75
#include <string.h>
76
#ifdef EVENT__HAVE_NETINET_IN_H
77
#include <netinet/in.h>
78
#endif
79
#ifdef EVENT__HAVE_NETINET_IN6_H
80
#include <netinet/in6.h>
81
#endif
82
#ifdef EVENT__HAVE_NETINET_TCP_H
83
#include <netinet/tcp.h>
84
#endif
85
#ifdef EVENT__HAVE_ARPA_INET_H
86
#include <arpa/inet.h>
87
#endif
88
#include <time.h>
89
#include <sys/stat.h>
90
#ifndef _WIN32
91
#include <net/if.h>
92
#endif
93
#ifdef EVENT__HAVE_IFADDRS_H
94
#include <ifaddrs.h>
95
#endif
96
97
#include "event2/util.h"
98
#include "util-internal.h"
99
#include "log-internal.h"
100
#include "mm-internal.h"
101
#include "evthread-internal.h"
102
103
#include "strlcpy-internal.h"
104
#include "ipv6-internal.h"
105
106
#ifdef _WIN32
107
#define HT_NO_CACHE_HASH_VALUES
108
#include "ht-internal.h"
109
#define open _open
110
#define read _read
111
#define close _close
112
#ifndef fstat
113
// i64 suffix is for 64-bit filesize support
114
#define fstat _fstati64
115
#endif
116
#ifndef stat
117
#define stat _stati64
118
#endif
119
#define mode_t int
120
#endif
121
122
#if defined(_WIN32) && !defined(SIO_KEEPALIVE_VALS)
123
#define SIO_KEEPALIVE_VALS    _WSAIOW(IOC_VENDOR,4)
124
struct tcp_keepalive {
125
  u_long onoff;
126
  u_long keepalivetime;
127
  u_long keepaliveinterval;
128
};
129
#endif
130
131
#ifndef O_RDONLY
132
#define O_RDONLY _O_RDONLY
133
#endif
134
135
#ifdef EVENT__HAVE_AFUNIX_H
136
int have_working_afunix_ = -1;
137
#endif
138
139
int
140
evutil_open_closeonexec_(const char *pathname, int flags, unsigned mode)
141
0
{
142
0
  int fd;
143
144
0
#ifdef O_CLOEXEC
145
0
  fd = open(pathname, flags|O_CLOEXEC, (mode_t)mode);
146
0
  if (fd >= 0 || errno == EINVAL)
147
0
    return fd;
148
  /* If we got an EINVAL, fall through and try without O_CLOEXEC */
149
0
#endif
150
0
  fd = open(pathname, flags, (mode_t)mode);
151
0
  if (fd < 0)
152
0
    return -1;
153
154
0
#if defined(FD_CLOEXEC)
155
0
  if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) {
156
0
    close(fd);
157
0
    return -1;
158
0
  }
159
0
#endif
160
161
0
  return fd;
162
0
}
163
164
ev_off_t evutil_fd_filesize(evutil_socket_t fd)
165
0
{
166
0
  struct stat st;
167
0
  if (fstat(fd, &st) < 0)
168
0
    return -1;
169
0
  return st.st_size;
170
0
}
171
172
/**
173
   Read the contents of 'filename' into a newly allocated NUL-terminated
174
   string.  Set *content_out to hold this string, and *len_out to hold its
175
   length (not including the appended NUL).  If 'is_binary', open the file in
176
   binary mode.
177
178
   Returns 0 on success, -1 if the open fails, and -2 for all other failures.
179
180
   Used internally only; may go away in a future version.
181
 */
182
int
183
evutil_read_file_(const char *filename, char **content_out, size_t *len_out,
184
    int is_binary)
185
0
{
186
0
  int fd;
187
0
  ev_ssize_t r;
188
0
  ev_off_t length;
189
0
  char *mem;
190
0
  size_t read_so_far = 0;
191
0
  int mode = O_RDONLY;
192
193
0
  EVUTIL_ASSERT(content_out);
194
0
  EVUTIL_ASSERT(len_out);
195
0
  *content_out = NULL;
196
0
  *len_out = 0;
197
198
#ifdef O_BINARY
199
  if (is_binary)
200
    mode |= O_BINARY;
201
#endif
202
203
0
  fd = evutil_open_closeonexec_(filename, mode, 0);
204
0
  if (fd < 0)
205
0
    return -1;
206
0
  length = evutil_fd_filesize(fd);
207
0
  if (length < 0 || length > EV_SSIZE_MAX-1) {
208
0
    close(fd);
209
0
    return -2;
210
0
  }
211
0
  mem = mm_malloc(length + 1);
212
0
  if (!mem) {
213
0
    close(fd);
214
0
    return -2;
215
0
  }
216
0
  read_so_far = 0;
217
#ifdef _WIN32
218
#define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
219
#else
220
0
#define N_TO_READ(x) (x)
221
0
#endif
222
0
  while ((r = read(fd, mem+read_so_far, N_TO_READ(length - read_so_far))) > 0) {
223
0
    read_so_far += r;
224
0
    if (read_so_far >= (size_t)length)
225
0
      break;
226
0
  }
227
0
  close(fd);
228
0
  if (r < 0) {
229
0
    mm_free(mem);
230
0
    return -2;
231
0
  }
232
0
  mem[read_so_far] = 0;
233
234
0
  *len_out = read_so_far;
235
0
  *content_out = mem;
236
0
  return 0;
237
0
}
238
239
#ifdef _WIN32
240
241
static int
242
create_tmpfile(WCHAR tmpfile[MAX_PATH])
243
{
244
  WCHAR short_path[MAX_PATH] = {0};
245
  WCHAR long_path[MAX_PATH] = {0};
246
  WCHAR prefix[4] = {0};
247
  // GetTempFileNameW() uses up to the first three characters of the prefix
248
  // and windows filesystems are case-insensitive
249
  const WCHAR *base32set = L"abcdefghijklmnopqrstuvwxyz012345";
250
  ev_uint16_t rnd;
251
252
  evutil_secure_rng_get_bytes(&rnd, sizeof(rnd));
253
  prefix[0] = base32set[(rnd      ) & 31];
254
  prefix[1] = base32set[(rnd >>  5) & 31];
255
  prefix[2] = base32set[(rnd >> 10) & 31];
256
  prefix[3] = '\0';
257
258
  GetTempPathW(MAX_PATH, short_path);
259
  GetLongPathNameW(short_path, long_path, MAX_PATH);
260
  if (!GetTempFileNameW(long_path, prefix, 0, tmpfile)) {
261
    event_warnx("GetTempFileName failed: %d", EVUTIL_SOCKET_ERROR());
262
    return -1;
263
  }
264
  return 0;
265
}
266
267
#ifdef EVENT__HAVE_AFUNIX_H
268
/* Test whether Unix domain socket works.
269
 * Return 1 if it works, otherwise 0    */
270
int
271
evutil_check_working_afunix_()
272
{
273
  /* Windows 10 began to support Unix domain socket. Let's just try
274
   * socket(AF_UNIX, , ) and fall back to socket(AF_INET, , ).
275
   * https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
276
   */
277
  evutil_socket_t sd = -1;
278
  if (have_working_afunix_ < 0) {
279
    if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
280
      have_working_afunix_ = 0;
281
    } else {
282
      have_working_afunix_ = 1;
283
      evutil_closesocket(sd);
284
    }
285
  }
286
  return have_working_afunix_;
287
}
288
289
/* XXX Copy from evutil_ersatz_socketpair_() */
290
static int
291
evutil_win_socketpair_afunix(int family, int type, int protocol,
292
    evutil_socket_t fd[2])
293
{
294
#undef ERR
295
#define ERR(e) WSA##e
296
  evutil_socket_t listener = -1;
297
  evutil_socket_t connector = -1;
298
  evutil_socket_t acceptor = -1;
299
300
  struct sockaddr_un listen_addr;
301
  struct sockaddr_un connect_addr;
302
  WCHAR tmp_file[MAX_PATH] = {0};
303
  char tmp_file_utf8[MAX_PATH] = {0};
304
305
  ev_socklen_t size;
306
  int saved_errno = -1;
307
308
  if (!fd) {
309
    EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
310
    return -1;
311
  }
312
313
  listener = socket(family, type, 0);
314
  if (listener < 0)
315
    return -1;
316
  memset(&listen_addr, 0, sizeof(listen_addr));
317
318
  if (create_tmpfile(tmp_file)) {
319
    goto tidy_up_and_fail;
320
  }
321
  DeleteFileW(tmp_file);
322
323
  /* Windows requires `sun_path` to be encoded by UTF-8 */
324
  WideCharToMultiByte(
325
    CP_UTF8, 0, tmp_file, MAX_PATH, tmp_file_utf8, MAX_PATH, NULL, NULL);
326
327
  listen_addr.sun_family = AF_UNIX;
328
  if (strlcpy(listen_addr.sun_path, tmp_file_utf8, UNIX_PATH_MAX) >=
329
    UNIX_PATH_MAX) {
330
    event_warnx("Temp file name is too long");
331
    goto tidy_up_and_fail;
332
  }
333
334
  if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
335
    == -1)
336
    goto tidy_up_and_fail;
337
  if (listen(listener, 1) == -1)
338
    goto tidy_up_and_fail;
339
340
  connector = socket(family, type, 0);
341
  if (connector < 0)
342
    goto tidy_up_and_fail;
343
344
  memset(&connect_addr, 0, sizeof(connect_addr));
345
346
  /* We want to find out the port number to connect to.  */
347
  size = sizeof(connect_addr);
348
  if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
349
    goto tidy_up_and_fail;
350
351
  if (connect(connector, (struct sockaddr *) &connect_addr,
352
        sizeof(connect_addr)) == -1)
353
    goto tidy_up_and_fail;
354
355
  size = sizeof(listen_addr);
356
  acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
357
  if (acceptor < 0)
358
    goto tidy_up_and_fail;
359
  if (size != sizeof(listen_addr))
360
    goto abort_tidy_up_and_fail;
361
  /* Now check we are talking to ourself by matching port and host on the
362
     two sockets.  */
363
  if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
364
    goto tidy_up_and_fail;
365
366
  if (size != sizeof(connect_addr) ||
367
      listen_addr.sun_family != connect_addr.sun_family ||
368
      evutil_ascii_strcasecmp(listen_addr.sun_path, connect_addr.sun_path))
369
    goto abort_tidy_up_and_fail;
370
371
  evutil_closesocket(listener);
372
  fd[0] = connector;
373
  fd[1] = acceptor;
374
375
  return 0;
376
377
 abort_tidy_up_and_fail:
378
  saved_errno = ERR(ECONNABORTED);
379
 tidy_up_and_fail:
380
  if (saved_errno < 0)
381
    saved_errno = EVUTIL_SOCKET_ERROR();
382
  if (listener != -1)
383
    evutil_closesocket(listener);
384
  if (connector != -1)
385
    evutil_closesocket(connector);
386
  if (acceptor != -1)
387
    evutil_closesocket(acceptor);
388
  if (tmp_file[0])
389
    DeleteFileW(tmp_file);
390
391
  EVUTIL_SET_SOCKET_ERROR(saved_errno);
392
  return -1;
393
#undef ERR
394
}
395
#endif
396
397
static int
398
evutil_win_socketpair(int family, int type, int protocol,
399
    evutil_socket_t fd[2])
400
{
401
#ifdef EVENT__HAVE_AFUNIX_H
402
  /* The family only support AF_UNIX and AF_INET */
403
  if (protocol || (family != AF_UNIX && family != AF_INET)) {
404
    EVUTIL_SET_SOCKET_ERROR(WSAEAFNOSUPPORT);
405
    return -1;
406
  }
407
  if (evutil_check_working_afunix_()) {
408
    /* If the AF_UNIX socket works, we will change the family to
409
     * AF_UNIX forcely. */
410
    family = AF_UNIX;
411
    if (type != SOCK_STREAM) {
412
      /* Win10 does not support AF_UNIX socket of a type other
413
       * than SOCK_STREAM still now. */
414
      EVUTIL_SET_SOCKET_ERROR(WSAEAFNOSUPPORT);
415
      return -1;
416
    }
417
  } else {
418
    /* If the AF_UNIX socket does not work, we will change the
419
     * family to AF_INET forcely. */
420
    family = AF_INET;
421
  }
422
  if (family == AF_UNIX)
423
    return evutil_win_socketpair_afunix(family, type, protocol, fd);
424
425
#endif
426
  return evutil_ersatz_socketpair_(family, type, protocol, fd);
427
}
428
#endif
429
430
int
431
evutil_make_socket_nonblocking(evutil_socket_t fd)
432
0
{
433
#ifdef _WIN32
434
  {
435
    unsigned long nonblocking = 1;
436
    if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
437
      event_sock_warn(fd, "ioctlsocket(%d, FIONBIO, &%lu)", (int)fd, (unsigned long)nonblocking);
438
      return -1;
439
    }
440
  }
441
#else
442
0
  {
443
0
    int flags;
444
0
    if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
445
0
      event_warn("fcntl(%d, F_GETFL)", fd);
446
0
      return -1;
447
0
    }
448
0
    if (!(flags & O_NONBLOCK)) {
449
0
      if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
450
0
        event_warn("fcntl(%d, F_SETFL)", fd);
451
0
        return -1;
452
0
      }
453
0
    }
454
0
  }
455
0
#endif
456
0
  return 0;
457
0
}
458
459
/* Faster version of evutil_make_socket_nonblocking for internal use.
460
 *
461
 * Requires that no F_SETFL flags were previously set on the fd.
462
 */
463
static int
464
evutil_fast_socket_nonblocking(evutil_socket_t fd)
465
0
{
466
#ifdef _WIN32
467
  return evutil_make_socket_nonblocking(fd);
468
#else
469
0
  if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
470
0
    event_warn("fcntl(%d, F_SETFL)", fd);
471
0
    return -1;
472
0
  }
473
0
  return 0;
474
0
#endif
475
0
}
476
477
int
478
evutil_make_listen_socket_reuseable(evutil_socket_t sock)
479
0
{
480
0
#if defined(SO_REUSEADDR) && !defined(_WIN32)
481
0
  int one = 1;
482
  /* REUSEADDR on Unix means, "don't hang on to this address after the
483
   * listener is closed."  On Windows, though, it means "don't keep other
484
   * processes from binding to this address while we're using it. */
485
0
  return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
486
0
      (ev_socklen_t)sizeof(one));
487
#else
488
  return 0;
489
#endif
490
0
}
491
492
int
493
evutil_make_listen_socket_reuseable_port(evutil_socket_t sock)
494
0
{
495
#if defined(__FreeBSD__) && __FreeBSD__ >= 12 && defined(SO_REUSEPORT_LB)
496
  /* FreeBSD 12 introduced a new socket option named SO_REUSEPORT_LB
497
   * with the capability of load balancing, it's the equivalent of
498
   * the SO_REUSEPORTs on Linux and DragonFlyBSD. */
499
  int enabled = 1;
500
  return setsockopt(sock, SOL_SOCKET, SO_REUSEPORT_LB, (void*)&enabled,
501
      (ev_socklen_t)sizeof(enabled));
502
#elif (defined(__linux__) || \
503
      defined(_AIX73) || \
504
      (defined(__DragonFly__) && __DragonFly_version >= 300600) || \
505
      (defined(EVENT__SOLARIS_11_4) && EVENT__SOLARIS_11_4)) && \
506
      defined(SO_REUSEPORT)
507
  int enabled = 1;
508
  /* SO_REUSEPORT on Linux 3.9+ means, "Multiple servers (processes or
509
   * threads) can bind to the same port if they each set the option".
510
   * In addition, the SO_REUSEPORT implementation distributes connections
511
   * or datagrams evenly across all of the threads (or processes).
512
   *
513
   * DragonFlyBSD 3.6.0 extended SO_REUSEPORT to distribute workload to
514
   * available sockets, which make it the same as Linux's SO_REUSEPORT.
515
   *
516
   * AIX 7.2.5 added the feature that would add the capability to distribute
517
   * incoming connections across all listening ports for SO_REUSEPORT.
518
   *
519
   * Solaris 11 supported SO_REUSEPORT, but it's implemented only for
520
   * binding to the same address and port, without load balancing.
521
   * Solaris 11.4 extended SO_REUSEPORT with the capability of load balancing.
522
   */
523
0
  return setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (void*)&enabled,
524
0
      (ev_socklen_t)sizeof(enabled));
525
#else
526
  /* SO_REUSEPORTs on macOS and other BSDs only enable duplicate address and
527
   * port bindings, load balancing is not included. Therefore, only the last
528
   * socket that binds to a given address and port will receive all the traffic,
529
   * which means that incoming connections/datagrams will be shifted from the
530
   * old thread (or process) to the new one. That's not what we want, so we fail
531
   * this operation on these systems to indicate that SO_REUSEPORT without load
532
   * balancing is not supported. Otherwise, the callers would expected the load
533
   * balancing capability when they get 0 as the return value of this function.
534
   */
535
  return -1;
536
#endif
537
0
}
538
539
int
540
evutil_make_listen_socket_ipv6only(evutil_socket_t sock)
541
0
{
542
0
#if defined(IPV6_V6ONLY)
543
0
  int one = 1;
544
0
  return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void*) &one,
545
0
      (ev_socklen_t)sizeof(one));
546
0
#endif
547
0
  return 0;
548
0
}
549
550
int
551
evutil_make_listen_socket_not_ipv6only(evutil_socket_t sock)
552
0
{
553
0
#if defined(IPV6_V6ONLY)
554
0
  int zero = 0;
555
0
  return setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&zero,
556
0
    (ev_socklen_t)sizeof(zero));
557
0
#endif
558
0
  return 0;
559
0
}
560
561
int
562
evutil_make_tcp_listen_socket_deferred(evutil_socket_t sock)
563
0
{
564
0
#if defined(EVENT__HAVE_NETINET_TCP_H) && defined(TCP_DEFER_ACCEPT)
565
0
  int one = 1;
566
567
  /* TCP_DEFER_ACCEPT tells the kernel to call defer accept() only after data
568
   * has arrived and ready to read */
569
0
  return setsockopt(sock, IPPROTO_TCP, TCP_DEFER_ACCEPT, &one,
570
0
    (ev_socklen_t)sizeof(one));
571
0
#endif
572
0
  return 0;
573
0
}
574
575
int
576
evutil_make_socket_closeonexec(evutil_socket_t fd)
577
0
{
578
0
#if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
579
0
  int flags;
580
0
  if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
581
0
    event_warn("fcntl(%d, F_GETFD)", fd);
582
0
    return -1;
583
0
  }
584
0
  if (!(flags & FD_CLOEXEC)) {
585
0
    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
586
0
      event_warn("fcntl(%d, F_SETFD)", fd);
587
0
      return -1;
588
0
    }
589
0
  }
590
0
#endif
591
0
  return 0;
592
0
}
593
594
/* Faster version of evutil_make_socket_closeonexec for internal use.
595
 *
596
 * Requires that no F_SETFD flags were previously set on the fd.
597
 */
598
static int
599
evutil_fast_socket_closeonexec(evutil_socket_t fd)
600
0
{
601
0
#if !defined(_WIN32) && defined(EVENT__HAVE_SETFD)
602
0
  if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
603
0
    event_warn("fcntl(%d, F_SETFD)", fd);
604
0
    return -1;
605
0
  }
606
0
#endif
607
0
  return 0;
608
0
}
609
610
int
611
evutil_closesocket(evutil_socket_t sock)
612
0
{
613
0
#ifndef _WIN32
614
0
  return close(sock);
615
#else
616
  return closesocket(sock);
617
#endif
618
0
}
619
620
ev_int64_t
621
evutil_strtoll(const char *s, char **endptr, int base)
622
0
{
623
0
#ifdef EVENT__HAVE_STRTOLL
624
0
  return (ev_int64_t)strtoll(s, endptr, base);
625
#elif EVENT__SIZEOF_LONG == 8
626
  return (ev_int64_t)strtol(s, endptr, base);
627
#elif defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
628
  /* XXXX on old versions of MS APIs, we only support base
629
   * 10. */
630
  ev_int64_t r;
631
  if (base != 10)
632
    return 0;
633
  r = (ev_int64_t) _atoi64(s);
634
  while (isspace(*s))
635
    ++s;
636
  if (*s == '-')
637
    ++s;
638
  while (isdigit(*s))
639
    ++s;
640
  if (endptr)
641
    *endptr = (char*) s;
642
  return r;
643
#elif defined(_WIN32)
644
  return (ev_int64_t) _strtoi64(s, endptr, base);
645
#elif defined(EVENT__SIZEOF_LONG_LONG) && EVENT__SIZEOF_LONG_LONG == 8
646
  long long r;
647
  int n;
648
  if (base != 10 && base != 16)
649
    return 0;
650
  if (base == 10) {
651
    n = sscanf(s, "%lld", &r);
652
  } else {
653
    unsigned long long ru=0;
654
    n = sscanf(s, "%llx", &ru);
655
    if (ru > EV_INT64_MAX)
656
      return 0;
657
    r = (long long) ru;
658
  }
659
  if (n != 1)
660
    return 0;
661
  while (EVUTIL_ISSPACE_(*s))
662
    ++s;
663
  if (*s == '-')
664
    ++s;
665
  if (base == 10) {
666
    while (EVUTIL_ISDIGIT_(*s))
667
      ++s;
668
  } else {
669
    while (EVUTIL_ISXDIGIT_(*s))
670
      ++s;
671
  }
672
  if (endptr)
673
    *endptr = (char*) s;
674
  return r;
675
#else
676
#error "I don't know how to parse 64-bit integers."
677
#endif
678
0
}
679
680
#ifdef _WIN32
681
int
682
evutil_socket_geterror(evutil_socket_t sock)
683
{
684
  int optval, optvallen=sizeof(optval);
685
  int err = WSAGetLastError();
686
  if (err == WSAEWOULDBLOCK && sock >= 0) {
687
    if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
688
             &optvallen))
689
      return err;
690
    if (optval)
691
      return optval;
692
  }
693
  return err;
694
}
695
#endif
696
697
/* XXX we should use an enum here. */
698
/* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
699
int
700
evutil_socket_connect_(evutil_socket_t *fd_ptr, const struct sockaddr *sa, int socklen)
701
0
{
702
0
  int made_fd = 0;
703
704
0
  if (*fd_ptr < 0) {
705
0
    if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
706
0
      goto err;
707
0
    made_fd = 1;
708
0
    if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
709
0
      goto err;
710
0
    }
711
0
  }
712
713
0
  if (connect(*fd_ptr, sa, socklen) < 0) {
714
0
    int e = evutil_socket_geterror(*fd_ptr);
715
0
    if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
716
0
      return 0;
717
0
    if (EVUTIL_ERR_CONNECT_REFUSED(e))
718
0
      return 2;
719
0
    goto err;
720
0
  } else {
721
0
    return 1;
722
0
  }
723
724
0
err:
725
0
  if (made_fd) {
726
0
    evutil_closesocket(*fd_ptr);
727
0
    *fd_ptr = -1;
728
0
  }
729
0
  return -1;
730
0
}
731
732
/* Check whether a socket on which we called connect() is done
733
   connecting. Return 1 for connected, 0 for not yet, -1 for error.  In the
734
   error case, set the current socket errno to the error that happened during
735
   the connect operation. */
736
int
737
evutil_socket_finished_connecting_(evutil_socket_t fd)
738
0
{
739
0
  int e;
740
0
  ev_socklen_t elen = sizeof(e);
741
742
0
  if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
743
0
    return -1;
744
745
0
  if (e) {
746
0
    if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
747
0
      return 0;
748
0
    EVUTIL_SET_SOCKET_ERROR(e);
749
0
    return -1;
750
0
  }
751
752
0
  return 1;
753
0
}
754
755
#if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
756
     EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
757
     EVUTIL_AI_ADDRCONFIG) != \
758
    (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
759
     EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
760
     EVUTIL_AI_ADDRCONFIG)
761
#error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
762
#endif
763
764
/* We sometimes need to know whether we have an ipv4 address and whether we
765
   have an ipv6 address. If 'have_checked_interfaces', then we've already done
766
   the test.  If 'had_ipv4_address', then it turns out we had an ipv4 address.
767
   If 'had_ipv6_address', then it turns out we had an ipv6 address.   These are
768
   set by evutil_check_interfaces. */
769
static int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
770
771
/* True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8 */
772
static inline int evutil_v4addr_is_localhost(ev_uint32_t addr)
773
0
{ return addr>>24 == 127; }
774
775
/* True iff the IPv4 address 'addr', in host order, is link-local
776
 * 169.254.0.0/16 (RFC3927) */
777
static inline int evutil_v4addr_is_linklocal(ev_uint32_t addr)
778
0
{ return ((addr & 0xffff0000U) == 0xa9fe0000U); }
779
780
/* True iff the IPv4 address 'addr', in host order, is a class D
781
 * (multiclass) address.  */
782
static inline int evutil_v4addr_is_classd(ev_uint32_t addr)
783
0
{ return ((addr>>24) & 0xf0) == 0xe0; }
784
785
int
786
evutil_v4addr_is_local_(const struct in_addr *in)
787
0
{
788
0
  const ev_uint32_t addr = ntohl(in->s_addr);
789
0
  return addr == INADDR_ANY ||
790
0
    evutil_v4addr_is_localhost(addr) ||
791
0
    evutil_v4addr_is_linklocal(addr) ||
792
0
    evutil_v4addr_is_classd(addr);
793
0
}
794
int
795
evutil_v6addr_is_local_(const struct in6_addr *in)
796
0
{
797
0
  static const char ZEROES[] =
798
0
    "\x00\x00\x00\x00\x00\x00\x00\x00"
799
0
    "\x00\x00\x00\x00\x00\x00\x00\x00";
800
801
0
  const unsigned char *addr = (const unsigned char *)in->s6_addr;
802
0
  return !memcmp(addr, ZEROES, 8) ||
803
0
    ((addr[0] & 0xfe) == 0xfc) ||
804
0
    (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80) ||
805
0
    (addr[0] == 0xfe && (addr[1] & 0xc0) == 0xc0) ||
806
0
    (addr[0] == 0xff);
807
0
}
808
809
static void
810
evutil_found_ifaddr(const struct sockaddr *sa)
811
0
{
812
0
  if (sa->sa_family == AF_INET) {
813
0
    const struct sockaddr_in *sin = (struct sockaddr_in *)sa;
814
0
    if (!evutil_v4addr_is_local_(&sin->sin_addr)) {
815
0
      event_debug(("Detected an IPv4 interface"));
816
0
      had_ipv4_address = 1;
817
0
    }
818
0
  } else if (sa->sa_family == AF_INET6) {
819
0
    const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
820
0
    if (!evutil_v6addr_is_local_(&sin6->sin6_addr)) {
821
0
      event_debug(("Detected an IPv6 interface"));
822
0
      had_ipv6_address = 1;
823
0
    }
824
0
  }
825
0
}
826
827
#ifdef _WIN32
828
typedef ULONG (WINAPI *GetAdaptersAddresses_fn_t)(
829
              ULONG, ULONG, PVOID, PIP_ADAPTER_ADDRESSES, PULONG);
830
#endif
831
832
static int
833
evutil_check_ifaddrs(void)
834
0
{
835
0
#if defined(EVENT__HAVE_GETIFADDRS)
836
  /* Most free Unixy systems provide getifaddrs, which gives us a linked list
837
   * of struct ifaddrs. */
838
0
  struct ifaddrs *ifa = NULL;
839
0
  const struct ifaddrs *i;
840
0
  if (getifaddrs(&ifa) < 0) {
841
0
    event_warn("Unable to call getifaddrs()");
842
0
    return -1;
843
0
  }
844
845
0
  for (i = ifa; i; i = i->ifa_next) {
846
0
    if (!i->ifa_addr)
847
0
      continue;
848
0
    evutil_found_ifaddr(i->ifa_addr);
849
0
  }
850
851
0
  freeifaddrs(ifa);
852
0
  return 0;
853
#elif defined(_WIN32)
854
  /* Windows XP began to provide GetAdaptersAddresses. Windows 2000 had a
855
     "GetAdaptersInfo", but that's deprecated; let's just try
856
     GetAdaptersAddresses and fall back to connect+getsockname.
857
  */
858
  HMODULE lib = evutil_load_windows_system_library_(TEXT("iphlpapi.dll"));
859
  GetAdaptersAddresses_fn_t fn;
860
  ULONG size, res;
861
  IP_ADAPTER_ADDRESSES *addresses = NULL, *address;
862
  int result = -1;
863
864
#define FLAGS (GAA_FLAG_SKIP_ANYCAST | \
865
               GAA_FLAG_SKIP_MULTICAST | \
866
               GAA_FLAG_SKIP_DNS_SERVER)
867
868
  if (!lib)
869
    goto done;
870
871
  if (!(fn = (GetAdaptersAddresses_fn_t) GetProcAddress(lib, "GetAdaptersAddresses")))
872
    goto done;
873
874
  /* Guess how much space we need. */
875
  size = 15*1024;
876
  addresses = mm_malloc(size);
877
  if (!addresses)
878
    goto done;
879
  res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
880
  if (res == ERROR_BUFFER_OVERFLOW) {
881
    /* we didn't guess that we needed enough space; try again */
882
    mm_free(addresses);
883
    addresses = mm_malloc(size);
884
    if (!addresses)
885
      goto done;
886
    res = fn(AF_UNSPEC, FLAGS, NULL, addresses, &size);
887
  }
888
  if (res != NO_ERROR)
889
    goto done;
890
891
  for (address = addresses; address; address = address->Next) {
892
    IP_ADAPTER_UNICAST_ADDRESS *a;
893
    for (a = address->FirstUnicastAddress; a; a = a->Next) {
894
      /* Yes, it's a linked list inside a linked list */
895
      struct sockaddr *sa = a->Address.lpSockaddr;
896
      evutil_found_ifaddr(sa);
897
    }
898
  }
899
900
  result = 0;
901
done:
902
  if (lib)
903
    FreeLibrary(lib);
904
  if (addresses)
905
    mm_free(addresses);
906
  return result;
907
#else
908
  return -1;
909
#endif
910
0
}
911
912
/* Test whether we have an ipv4 interface and an ipv6 interface.  Return 0 if
913
 * the test seemed successful. */
914
static int
915
evutil_check_interfaces(void)
916
0
{
917
0
  evutil_socket_t fd = -1;
918
0
  struct sockaddr_in sin, sin_out;
919
0
  struct sockaddr_in6 sin6, sin6_out;
920
0
  ev_socklen_t sin_out_len = sizeof(sin_out);
921
0
  ev_socklen_t sin6_out_len = sizeof(sin6_out);
922
0
  int r;
923
0
  if (have_checked_interfaces)
924
0
    return 0;
925
926
  /* From this point on we have done the ipv4/ipv6 interface check */
927
0
  have_checked_interfaces = 1;
928
929
0
  if (evutil_check_ifaddrs() == 0) {
930
    /* Use a nice sane interface, if this system has one. */
931
0
    return 0;
932
0
  }
933
934
  /* Ugh. There was no nice sane interface.  So to check whether we have
935
   * an interface open for a given protocol, will try to make a UDP
936
   * 'connection' to a remote host on the internet.  We don't actually
937
   * use it, so the address doesn't matter, but we want to pick one that
938
   * keep us from using a host- or link-local interface. */
939
0
  memset(&sin, 0, sizeof(sin));
940
0
  sin.sin_family = AF_INET;
941
0
  sin.sin_port = htons(53);
942
0
  r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
943
0
  EVUTIL_ASSERT(r);
944
945
0
  memset(&sin6, 0, sizeof(sin6));
946
0
  sin6.sin6_family = AF_INET6;
947
0
  sin6.sin6_port = htons(53);
948
0
  r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
949
0
  EVUTIL_ASSERT(r);
950
951
0
  memset(&sin_out, 0, sizeof(sin_out));
952
0
  memset(&sin6_out, 0, sizeof(sin6_out));
953
954
  /* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
955
0
  if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
956
0
      connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
957
0
      getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
958
    /* We might have an IPv4 interface. */
959
0
    evutil_found_ifaddr((struct sockaddr*) &sin_out);
960
0
  }
961
0
  if (fd >= 0)
962
0
    evutil_closesocket(fd);
963
964
0
  if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
965
0
      connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
966
0
      getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
967
    /* We might have an IPv6 interface. */
968
0
    evutil_found_ifaddr((struct sockaddr*) &sin6_out);
969
0
  }
970
971
0
  if (fd >= 0)
972
0
    evutil_closesocket(fd);
973
974
0
  return 0;
975
0
}
976
977
/* Internal addrinfo flag.  This one is set when we allocate the addrinfo from
978
 * inside libevent.  Otherwise, the built-in getaddrinfo() function allocated
979
 * it, and we should trust what they said.
980
 **/
981
829
#define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
982
983
/* Helper: construct a new addrinfo containing the socket address in
984
 * 'sa', which must be a sockaddr_in or a sockaddr_in6.  Take the
985
 * socktype and protocol info from hints.  If they weren't set, then
986
 * allocate both a TCP and a UDP addrinfo.
987
 */
988
struct evutil_addrinfo *
989
evutil_new_addrinfo_(struct sockaddr *sa, ev_socklen_t socklen,
990
    const struct evutil_addrinfo *hints)
991
381
{
992
381
  struct evutil_addrinfo *res;
993
381
  EVUTIL_ASSERT(hints);
994
995
381
  if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
996
    /* Indecisive user! Give them a UDP and a TCP. */
997
127
    struct evutil_addrinfo *r1, *r2;
998
127
    struct evutil_addrinfo tmp;
999
127
    memcpy(&tmp, hints, sizeof(tmp));
1000
127
    tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
1001
127
    r1 = evutil_new_addrinfo_(sa, socklen, &tmp);
1002
127
    if (!r1)
1003
0
      return NULL;
1004
127
    tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
1005
127
    r2 = evutil_new_addrinfo_(sa, socklen, &tmp);
1006
127
    if (!r2) {
1007
0
      evutil_freeaddrinfo(r1);
1008
0
      return NULL;
1009
0
    }
1010
127
    r1->ai_next = r2;
1011
127
    return r1;
1012
127
  }
1013
1014
  /* We're going to allocate extra space to hold the sockaddr. */
1015
254
  res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
1016
254
  if (!res)
1017
0
    return NULL;
1018
254
  res->ai_addr = (struct sockaddr*)
1019
254
      (((char*)res) + sizeof(struct evutil_addrinfo));
1020
254
  memcpy(res->ai_addr, sa, socklen);
1021
254
  res->ai_addrlen = socklen;
1022
254
  res->ai_family = sa->sa_family; /* Same or not? XXX */
1023
254
  res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
1024
254
  res->ai_socktype = hints->ai_socktype;
1025
254
  res->ai_protocol = hints->ai_protocol;
1026
1027
254
  return res;
1028
254
}
1029
1030
/* Append the addrinfo 'append' to the end of 'first', and return the start of
1031
 * the list.  Either element can be NULL, in which case we return the element
1032
 * that is not NULL. */
1033
struct evutil_addrinfo *
1034
evutil_addrinfo_append_(struct evutil_addrinfo *first,
1035
    struct evutil_addrinfo *append)
1036
32
{
1037
32
  struct evutil_addrinfo *ai = first;
1038
32
  if (!ai)
1039
0
    return append;
1040
64
  while (ai->ai_next)
1041
32
    ai = ai->ai_next;
1042
32
  ai->ai_next = append;
1043
1044
32
  return first;
1045
32
}
1046
1047
static int
1048
parse_numeric_servname(const char *servname)
1049
1.32k
{
1050
1.32k
  int n;
1051
1.32k
  char *endptr=NULL;
1052
1.32k
  n = (int) strtol(servname, &endptr, 10);
1053
1.32k
  if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
1054
32
    return n;
1055
1.29k
  else
1056
1.29k
    return -1;
1057
1.32k
}
1058
1059
/** Parse a service name in 'servname', which can be a decimal port.
1060
 * Return the port number, or -1 on error.
1061
 */
1062
static int
1063
evutil_parse_servname(const char *servname, const char *protocol,
1064
    const struct evutil_addrinfo *hints)
1065
1.32k
{
1066
1.32k
  int n = parse_numeric_servname(servname);
1067
1.32k
  if (n>=0)
1068
32
    return n;
1069
1.29k
#if defined(EVENT__HAVE_GETSERVBYNAME) || defined(_WIN32)
1070
1.29k
  if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
1071
1.29k
    struct servent *ent = getservbyname(servname, protocol);
1072
1.29k
    if (ent) {
1073
0
      return ntohs(ent->s_port);
1074
0
    }
1075
1.29k
  }
1076
1.29k
#endif
1077
1.29k
  return -1;
1078
1.29k
}
1079
1080
/* Return a string corresponding to a protocol number that we can pass to
1081
 * getservyname.  */
1082
static const char *
1083
evutil_unparse_protoname(int proto)
1084
2.64k
{
1085
2.64k
  switch (proto) {
1086
2.64k
  case 0:
1087
2.64k
    return NULL;
1088
0
  case IPPROTO_TCP:
1089
0
    return "tcp";
1090
0
  case IPPROTO_UDP:
1091
0
    return "udp";
1092
0
#ifdef IPPROTO_SCTP
1093
0
  case IPPROTO_SCTP:
1094
0
    return "sctp";
1095
0
#endif
1096
0
  default:
1097
0
#ifdef EVENT__HAVE_GETPROTOBYNUMBER
1098
0
    {
1099
0
      struct protoent *ent = getprotobynumber(proto);
1100
0
      if (ent)
1101
0
        return ent->p_name;
1102
0
    }
1103
0
#endif
1104
0
    return NULL;
1105
2.64k
  }
1106
2.64k
}
1107
1108
static void
1109
evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
1110
2.64k
{
1111
  /* If we can guess the protocol from the socktype, do so. */
1112
2.64k
  if (!hints->ai_protocol && hints->ai_socktype) {
1113
0
    if (hints->ai_socktype == SOCK_DGRAM)
1114
0
      hints->ai_protocol = IPPROTO_UDP;
1115
0
    else if (hints->ai_socktype == SOCK_STREAM)
1116
0
      hints->ai_protocol = IPPROTO_TCP;
1117
0
  }
1118
1119
  /* Set the socktype if it isn't set. */
1120
2.64k
  if (!hints->ai_socktype && hints->ai_protocol) {
1121
0
    if (hints->ai_protocol == IPPROTO_UDP)
1122
0
      hints->ai_socktype = SOCK_DGRAM;
1123
0
    else if (hints->ai_protocol == IPPROTO_TCP)
1124
0
      hints->ai_socktype = SOCK_STREAM;
1125
0
#ifdef IPPROTO_SCTP
1126
0
    else if (hints->ai_protocol == IPPROTO_SCTP)
1127
0
      hints->ai_socktype = SOCK_STREAM;
1128
0
#endif
1129
0
  }
1130
2.64k
}
1131
1132
#if AF_UNSPEC != PF_UNSPEC
1133
#error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
1134
#endif
1135
1136
/** Implements the part of looking up hosts by name that's common to both
1137
 * the blocking and nonblocking resolver:
1138
 *   - Adjust 'hints' to have a reasonable socktype and protocol.
1139
 *   - Look up the port based on 'servname', and store it in *portnum,
1140
 *   - Handle the nodename==NULL case
1141
 *   - Handle some invalid arguments cases.
1142
 *   - Handle the cases where nodename is an IPv4 or IPv6 address.
1143
 *
1144
 * If we need the resolver to look up the hostname, we return
1145
 * EVUTIL_EAI_NEED_RESOLVE.  Otherwise, we can completely implement
1146
 * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
1147
 * set *res as getaddrinfo would.
1148
 */
1149
int
1150
evutil_getaddrinfo_common_(const char *nodename, const char *servname,
1151
    struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
1152
2.64k
{
1153
2.64k
  int port = 0;
1154
2.64k
  unsigned int if_index;
1155
2.64k
  const char *pname;
1156
1157
2.64k
  if (nodename == NULL && servname == NULL)
1158
0
    return EVUTIL_EAI_NONAME;
1159
1160
  /* We only understand 3 families */
1161
2.64k
  if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
1162
2.64k
      hints->ai_family != PF_INET6)
1163
0
    return EVUTIL_EAI_FAMILY;
1164
1165
2.64k
  evutil_getaddrinfo_infer_protocols(hints);
1166
1167
  /* Look up the port number and protocol, if possible. */
1168
2.64k
  pname = evutil_unparse_protoname(hints->ai_protocol);
1169
2.64k
  if (servname) {
1170
    /* XXXX We could look at the protocol we got back from
1171
     * getservbyname, but it doesn't seem too useful. */
1172
1.32k
    port = evutil_parse_servname(servname, pname, hints);
1173
1.32k
    if (port < 0) {
1174
1.29k
      return EVUTIL_EAI_NONAME;
1175
1.29k
    }
1176
1.32k
  }
1177
1178
  /* If we have no node name, then we're supposed to bind to 'any' and
1179
   * connect to localhost. */
1180
1.35k
  if (nodename == NULL) {
1181
32
    struct evutil_addrinfo *res4=NULL, *res6=NULL;
1182
32
    if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
1183
32
      struct sockaddr_in6 sin6;
1184
32
      memset(&sin6, 0, sizeof(sin6));
1185
32
      sin6.sin6_family = AF_INET6;
1186
32
      sin6.sin6_port = htons(port);
1187
32
      if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
1188
        /* Bind to :: */
1189
32
      } else {
1190
        /* connect to ::1 */
1191
32
        sin6.sin6_addr.s6_addr[15] = 1;
1192
32
      }
1193
32
      res6 = evutil_new_addrinfo_((struct sockaddr*)&sin6,
1194
32
          sizeof(sin6), hints);
1195
32
      if (!res6)
1196
0
        return EVUTIL_EAI_MEMORY;
1197
32
    }
1198
1199
32
    if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
1200
32
      struct sockaddr_in sin;
1201
32
      memset(&sin, 0, sizeof(sin));
1202
32
      sin.sin_family = AF_INET;
1203
32
      sin.sin_port = htons(port);
1204
32
      if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
1205
        /* Bind to 0.0.0.0 */
1206
32
      } else {
1207
        /* connect to 127.0.0.1 */
1208
32
        sin.sin_addr.s_addr = htonl(0x7f000001);
1209
32
      }
1210
32
      res4 = evutil_new_addrinfo_((struct sockaddr*)&sin,
1211
32
          sizeof(sin), hints);
1212
32
      if (!res4) {
1213
0
        if (res6)
1214
0
          evutil_freeaddrinfo(res6);
1215
0
        return EVUTIL_EAI_MEMORY;
1216
0
      }
1217
32
    }
1218
32
    *res = evutil_addrinfo_append_(res4, res6);
1219
32
    return 0;
1220
32
  }
1221
1222
  /* If we can, we should try to parse the hostname without resolving
1223
   * it. */
1224
  /* Try ipv6. */
1225
1.32k
  if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
1226
1.32k
    struct sockaddr_in6 sin6;
1227
1.32k
    memset(&sin6, 0, sizeof(sin6));
1228
1.32k
    if (1 == evutil_inet_pton_scope(
1229
1.32k
      AF_INET6, nodename, &sin6.sin6_addr, &if_index)) {
1230
      /* Got an ipv6 address. */
1231
11
      sin6.sin6_family = AF_INET6;
1232
11
      sin6.sin6_port = htons(port);
1233
11
      sin6.sin6_scope_id = if_index;
1234
11
      *res = evutil_new_addrinfo_((struct sockaddr*)&sin6,
1235
11
          sizeof(sin6), hints);
1236
11
      if (!*res)
1237
0
        return EVUTIL_EAI_MEMORY;
1238
11
      return 0;
1239
11
    }
1240
1.32k
  }
1241
1242
  /* Try ipv4. */
1243
1.31k
  if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
1244
1.31k
    struct sockaddr_in sin;
1245
1.31k
    memset(&sin, 0, sizeof(sin));
1246
1.31k
    if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
1247
      /* Got an ipv4 address. */
1248
52
      sin.sin_family = AF_INET;
1249
52
      sin.sin_port = htons(port);
1250
52
      *res = evutil_new_addrinfo_((struct sockaddr*)&sin,
1251
52
          sizeof(sin), hints);
1252
52
      if (!*res)
1253
0
        return EVUTIL_EAI_MEMORY;
1254
52
      return 0;
1255
52
    }
1256
1.31k
  }
1257
1258
1259
  /* If we have reached this point, we definitely need to do a DNS
1260
   * lookup. */
1261
1.25k
  if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
1262
    /* If we're not allowed to do one, then say so. */
1263
0
    return EVUTIL_EAI_NONAME;
1264
0
  }
1265
1.25k
  *portnum = port;
1266
1.25k
  return EVUTIL_EAI_NEED_RESOLVE;
1267
1.25k
}
1268
1269
#ifdef EVENT__HAVE_GETADDRINFO
1270
#define USE_NATIVE_GETADDRINFO
1271
#endif
1272
1273
#ifdef USE_NATIVE_GETADDRINFO
1274
/* A mask of all the flags that we declare, so we can clear them before calling
1275
 * the native getaddrinfo */
1276
static const unsigned int ALL_NONNATIVE_AI_FLAGS =
1277
#ifndef AI_PASSIVE
1278
    EVUTIL_AI_PASSIVE |
1279
#endif
1280
#ifndef AI_CANONNAME
1281
    EVUTIL_AI_CANONNAME |
1282
#endif
1283
#ifndef AI_NUMERICHOST
1284
    EVUTIL_AI_NUMERICHOST |
1285
#endif
1286
#ifndef AI_NUMERICSERV
1287
    EVUTIL_AI_NUMERICSERV |
1288
#endif
1289
#ifndef AI_ADDRCONFIG
1290
    EVUTIL_AI_ADDRCONFIG |
1291
#endif
1292
#ifndef AI_ALL
1293
    EVUTIL_AI_ALL |
1294
#endif
1295
#ifndef AI_V4MAPPED
1296
    EVUTIL_AI_V4MAPPED |
1297
#endif
1298
    EVUTIL_AI_LIBEVENT_ALLOCATED;
1299
1300
static const unsigned int ALL_NATIVE_AI_FLAGS =
1301
#ifdef AI_PASSIVE
1302
    AI_PASSIVE |
1303
#endif
1304
#ifdef AI_CANONNAME
1305
    AI_CANONNAME |
1306
#endif
1307
#ifdef AI_NUMERICHOST
1308
    AI_NUMERICHOST |
1309
#endif
1310
#ifdef AI_NUMERICSERV
1311
    AI_NUMERICSERV |
1312
#endif
1313
#ifdef AI_ADDRCONFIG
1314
    AI_ADDRCONFIG |
1315
#endif
1316
#ifdef AI_ALL
1317
    AI_ALL |
1318
#endif
1319
#ifdef AI_V4MAPPED
1320
    AI_V4MAPPED |
1321
#endif
1322
    0;
1323
#endif
1324
1325
#ifndef USE_NATIVE_GETADDRINFO
1326
/* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
1327
 * a struct hostent.
1328
 */
1329
static struct evutil_addrinfo *
1330
addrinfo_from_hostent(const struct hostent *ent,
1331
    int port, const struct evutil_addrinfo *hints)
1332
{
1333
  int i;
1334
  struct sockaddr_in sin;
1335
  struct sockaddr_in6 sin6;
1336
  struct sockaddr *sa;
1337
  int socklen;
1338
  struct evutil_addrinfo *res=NULL, *ai;
1339
  void *addrp;
1340
1341
  if (ent->h_addrtype == PF_INET) {
1342
    memset(&sin, 0, sizeof(sin));
1343
    sin.sin_family = AF_INET;
1344
    sin.sin_port = htons(port);
1345
    sa = (struct sockaddr *)&sin;
1346
    socklen = sizeof(struct sockaddr_in);
1347
    addrp = &sin.sin_addr;
1348
    if (ent->h_length != sizeof(sin.sin_addr)) {
1349
      event_warnx("Weird h_length from gethostbyname");
1350
      return NULL;
1351
    }
1352
  } else if (ent->h_addrtype == PF_INET6) {
1353
    memset(&sin6, 0, sizeof(sin6));
1354
    sin6.sin6_family = AF_INET6;
1355
    sin6.sin6_port = htons(port);
1356
    sa = (struct sockaddr *)&sin6;
1357
    socklen = sizeof(struct sockaddr_in6);
1358
    addrp = &sin6.sin6_addr;
1359
    if (ent->h_length != sizeof(sin6.sin6_addr)) {
1360
      event_warnx("Weird h_length from gethostbyname");
1361
      return NULL;
1362
    }
1363
  } else
1364
    return NULL;
1365
1366
  for (i = 0; ent->h_addr_list[i]; ++i) {
1367
    memcpy(addrp, ent->h_addr_list[i], ent->h_length);
1368
    ai = evutil_new_addrinfo_(sa, socklen, hints);
1369
    if (!ai) {
1370
      evutil_freeaddrinfo(res);
1371
      return NULL;
1372
    }
1373
    res = evutil_addrinfo_append_(res, ai);
1374
  }
1375
1376
  if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
1377
    res->ai_canonname = mm_strdup(ent->h_name);
1378
    if (res->ai_canonname == NULL) {
1379
      evutil_freeaddrinfo(res);
1380
      return NULL;
1381
    }
1382
  }
1383
1384
  return res;
1385
}
1386
#endif
1387
1388
/* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
1389
 * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
1390
 * that we'll only get addresses we could maybe connect to.
1391
 */
1392
void
1393
evutil_adjust_hints_for_addrconfig_(struct evutil_addrinfo *hints)
1394
0
{
1395
0
  if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
1396
0
    return;
1397
0
  if (hints->ai_family != PF_UNSPEC)
1398
0
    return;
1399
0
  evutil_check_interfaces();
1400
0
  if (had_ipv4_address && !had_ipv6_address) {
1401
0
    hints->ai_family = PF_INET;
1402
0
  } else if (!had_ipv4_address && had_ipv6_address) {
1403
0
    hints->ai_family = PF_INET6;
1404
0
  }
1405
0
}
1406
1407
#ifdef USE_NATIVE_GETADDRINFO
1408
static int need_numeric_port_hack_=0;
1409
static int need_socktype_protocol_hack_=0;
1410
static int tested_for_getaddrinfo_hacks=0;
1411
1412
/* Some older BSDs (like OpenBSD up to 4.6) used to believe that
1413
   giving a numeric port without giving an ai_socktype was verboten.
1414
   We test for this so we can apply an appropriate workaround.  If it
1415
   turns out that the bug is present, then:
1416
1417
    - If nodename==NULL and servname is numeric, we build an answer
1418
      ourselves using evutil_getaddrinfo_common_().
1419
1420
    - If nodename!=NULL and servname is numeric, then we set
1421
      servname=NULL when calling getaddrinfo, and post-process the
1422
      result to set the ports on it.
1423
1424
   We test for this bug at runtime, since otherwise we can't have the
1425
   same binary run on multiple BSD versions.
1426
1427
   - Some versions of Solaris believe that it's nice to leave to protocol
1428
     field set to 0.  We test for this so we can apply an appropriate
1429
     workaround.
1430
*/
1431
static struct evutil_addrinfo *ai_find_protocol(struct evutil_addrinfo *ai)
1432
2
{
1433
2
  while (ai) {
1434
2
    if (ai->ai_protocol)
1435
2
      return ai;
1436
0
    ai = ai->ai_next;
1437
0
  }
1438
0
  return NULL;
1439
2
}
1440
static void
1441
test_for_getaddrinfo_hacks(void)
1442
1
{
1443
1
  int r, r2;
1444
1
  struct evutil_addrinfo *ai=NULL, *ai2=NULL, *ai3=NULL;
1445
1
  struct evutil_addrinfo hints;
1446
1447
1
  memset(&hints,0,sizeof(hints));
1448
1
  hints.ai_family = PF_UNSPEC;
1449
1
  hints.ai_flags =
1450
1
#ifdef AI_NUMERICHOST
1451
1
      AI_NUMERICHOST |
1452
1
#endif
1453
1
#ifdef AI_NUMERICSERV
1454
1
      AI_NUMERICSERV |
1455
1
#endif
1456
1
      0;
1457
1
  r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
1458
1
  getaddrinfo("1.2.3.4", NULL, &hints, &ai3);
1459
1
  hints.ai_socktype = SOCK_STREAM;
1460
1
  r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
1461
1
  if (r2 == 0 && r != 0) {
1462
0
    need_numeric_port_hack_=1;
1463
0
  }
1464
1
  if (!ai_find_protocol(ai2) || !ai_find_protocol(ai3)) {
1465
0
    need_socktype_protocol_hack_=1;
1466
0
  }
1467
1468
1
  if (ai)
1469
1
    freeaddrinfo(ai);
1470
1
  if (ai2)
1471
1
    freeaddrinfo(ai2);
1472
1
  if (ai3)
1473
1
    freeaddrinfo(ai3);
1474
1
  tested_for_getaddrinfo_hacks=1;
1475
1
}
1476
1477
static inline int
1478
need_numeric_port_hack(void)
1479
1.32k
{
1480
1.32k
  if (!tested_for_getaddrinfo_hacks)
1481
1
    test_for_getaddrinfo_hacks();
1482
1.32k
  return need_numeric_port_hack_;
1483
1.32k
}
1484
1485
static inline int
1486
need_socktype_protocol_hack(void)
1487
2.64k
{
1488
2.64k
  if (!tested_for_getaddrinfo_hacks)
1489
0
    test_for_getaddrinfo_hacks();
1490
2.64k
  return need_socktype_protocol_hack_;
1491
2.64k
}
1492
1493
static void
1494
apply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
1495
0
{
1496
  /* Now we run through the list and set the ports on all of the
1497
   * results where ports would make sense. */
1498
0
  for ( ; *ai; ai = &(*ai)->ai_next) {
1499
0
    struct sockaddr *sa = (*ai)->ai_addr;
1500
0
    if (sa && sa->sa_family == AF_INET) {
1501
0
      struct sockaddr_in *sin = (struct sockaddr_in*)sa;
1502
0
      sin->sin_port = htons(port);
1503
0
    } else if (sa && sa->sa_family == AF_INET6) {
1504
0
      struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
1505
0
      sin6->sin6_port = htons(port);
1506
0
    } else {
1507
      /* A numeric port makes no sense here; remove this one
1508
       * from the list. */
1509
0
      struct evutil_addrinfo *victim = *ai;
1510
0
      *ai = victim->ai_next;
1511
0
      victim->ai_next = NULL;
1512
0
      freeaddrinfo(victim);
1513
0
    }
1514
0
  }
1515
0
}
1516
1517
static int
1518
apply_socktype_protocol_hack(struct evutil_addrinfo *ai)
1519
0
{
1520
0
  struct evutil_addrinfo *ai_new;
1521
0
  for (; ai; ai = ai->ai_next) {
1522
0
    evutil_getaddrinfo_infer_protocols(ai);
1523
0
    if (ai->ai_socktype || ai->ai_protocol)
1524
0
      continue;
1525
0
    ai_new = mm_malloc(sizeof(*ai_new));
1526
0
    if (!ai_new)
1527
0
      return -1;
1528
0
    memcpy(ai_new, ai, sizeof(*ai_new));
1529
0
    ai->ai_socktype = SOCK_STREAM;
1530
0
    ai->ai_protocol = IPPROTO_TCP;
1531
0
    ai_new->ai_socktype = SOCK_DGRAM;
1532
0
    ai_new->ai_protocol = IPPROTO_UDP;
1533
0
    ai_new->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
1534
0
    if (ai_new->ai_canonname != NULL) {
1535
0
      ai_new->ai_canonname = mm_strdup(ai_new->ai_canonname);
1536
0
      if (ai_new->ai_canonname == NULL) {
1537
0
        mm_free(ai_new);
1538
0
        return -1;
1539
0
      }
1540
0
    }
1541
1542
0
    ai_new->ai_next = ai->ai_next;
1543
0
    ai->ai_next = ai_new;
1544
0
  }
1545
0
  return 0;
1546
0
}
1547
#endif
1548
1549
int
1550
evutil_getaddrinfo(const char *nodename, const char *servname,
1551
    const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
1552
1.32k
{
1553
1.32k
#ifdef USE_NATIVE_GETADDRINFO
1554
1.32k
  struct evutil_addrinfo hints;
1555
1.32k
  int portnum=-1, need_np_hack, err;
1556
1557
1.32k
  if (hints_in) {
1558
0
    memcpy(&hints, hints_in, sizeof(hints));
1559
1.32k
  } else {
1560
1.32k
    memset(&hints, 0, sizeof(hints));
1561
1.32k
    hints.ai_family = PF_UNSPEC;
1562
1.32k
  }
1563
1564
#ifndef AI_ADDRCONFIG
1565
  /* Not every system has AI_ADDRCONFIG, so fake it. */
1566
  if (hints.ai_family == PF_UNSPEC &&
1567
      (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
1568
    evutil_adjust_hints_for_addrconfig_(&hints);
1569
  }
1570
#endif
1571
1572
#ifndef AI_NUMERICSERV
1573
  /* Not every system has AI_NUMERICSERV, so fake it. */
1574
  if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
1575
    if (servname && parse_numeric_servname(servname)<0)
1576
      return EVUTIL_EAI_NONAME;
1577
  }
1578
#endif
1579
1580
  /* Enough operating systems handle enough common non-resolve
1581
   * cases here weirdly enough that we are better off just
1582
   * overriding them.  For example:
1583
   *
1584
   * - Windows doesn't like to infer the protocol from the
1585
   *   socket type, or fill in socket or protocol types much at
1586
   *   all.  It also seems to do its own broken implicit
1587
   *   always-on version of AI_ADDRCONFIG that keeps it from
1588
   *   ever resolving even a literal IPv6 address when
1589
   *   ai_addrtype is PF_UNSPEC.
1590
   */
1591
#ifdef _WIN32
1592
  {
1593
    int tmp_port;
1594
    err = evutil_getaddrinfo_common_(nodename,servname,&hints,
1595
        res, &tmp_port);
1596
    if (err == 0 ||
1597
        err == EVUTIL_EAI_MEMORY ||
1598
        err == EVUTIL_EAI_NONAME)
1599
      return err;
1600
    /* If we make it here, the system getaddrinfo can
1601
     * have a crack at it. */
1602
  }
1603
#endif
1604
1605
  /* See documentation for need_numeric_port_hack above.*/
1606
1.32k
  need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
1607
1.32k
      && ((portnum=parse_numeric_servname(servname)) >= 0);
1608
1.32k
  if (need_np_hack) {
1609
0
    if (!nodename)
1610
0
      return evutil_getaddrinfo_common_(
1611
0
        NULL,servname,&hints, res, &portnum);
1612
0
    servname = NULL;
1613
0
  }
1614
1615
1.32k
  if (need_socktype_protocol_hack()) {
1616
0
    evutil_getaddrinfo_infer_protocols(&hints);
1617
0
  }
1618
1619
  /* Make sure that we didn't actually steal any AI_FLAGS values that
1620
   * the system is using.  (This is a constant expression, and should ge
1621
   * optimized out.)
1622
   *
1623
   * XXXX Turn this into a compile-time failure rather than a run-time
1624
   * failure.
1625
   */
1626
1.32k
  EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
1627
1628
  /* Clear any flags that only libevent understands. */
1629
1.32k
  hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
1630
1631
1.32k
  err = getaddrinfo(nodename, servname, &hints, res);
1632
1.32k
  if (need_np_hack)
1633
0
    apply_numeric_port_hack(portnum, res);
1634
1635
1.32k
  if (need_socktype_protocol_hack()) {
1636
0
    if (apply_socktype_protocol_hack(*res) < 0) {
1637
0
      evutil_freeaddrinfo(*res);
1638
0
      *res = NULL;
1639
0
      return EVUTIL_EAI_MEMORY;
1640
0
    }
1641
0
  }
1642
1.32k
  return err;
1643
#else
1644
  int port=0, err;
1645
  struct hostent *ent = NULL;
1646
  struct evutil_addrinfo hints;
1647
1648
  if (hints_in) {
1649
    memcpy(&hints, hints_in, sizeof(hints));
1650
  } else {
1651
    memset(&hints, 0, sizeof(hints));
1652
    hints.ai_family = PF_UNSPEC;
1653
  }
1654
1655
  evutil_adjust_hints_for_addrconfig_(&hints);
1656
1657
  err = evutil_getaddrinfo_common_(nodename, servname, &hints, res, &port);
1658
  if (err != EVUTIL_EAI_NEED_RESOLVE) {
1659
    /* We either succeeded or failed.  No need to continue */
1660
    return err;
1661
  }
1662
1663
  err = 0;
1664
  /* Use any of the various gethostbyname_r variants as available. */
1665
  {
1666
#ifdef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG
1667
    /* This one is what glibc provides. */
1668
    char buf[2048];
1669
    struct hostent hostent;
1670
    int r;
1671
    r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
1672
        &err);
1673
#elif defined(EVENT__HAVE_GETHOSTBYNAME_R_5_ARG)
1674
    char buf[2048];
1675
    struct hostent hostent;
1676
    ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
1677
        &err);
1678
#elif defined(EVENT__HAVE_GETHOSTBYNAME_R_3_ARG)
1679
    struct hostent_data data;
1680
    struct hostent hostent;
1681
    memset(&data, 0, sizeof(data));
1682
    err = gethostbyname_r(nodename, &hostent, &data);
1683
    ent = err ? NULL : &hostent;
1684
#else
1685
    /* fall back to gethostbyname. */
1686
    /* XXXX This needs a lock everywhere but Windows. */
1687
    ent = gethostbyname(nodename);
1688
#ifdef _WIN32
1689
    err = WSAGetLastError();
1690
#else
1691
    err = h_errno;
1692
#endif
1693
#endif
1694
1695
    /* Now we have either ent or err set. */
1696
    if (!ent) {
1697
      /* XXX is this right for windows ? */
1698
      switch (err) {
1699
      case TRY_AGAIN:
1700
        return EVUTIL_EAI_AGAIN;
1701
      case NO_RECOVERY:
1702
      default:
1703
        return EVUTIL_EAI_FAIL;
1704
      case HOST_NOT_FOUND:
1705
        return EVUTIL_EAI_NONAME;
1706
      case NO_ADDRESS:
1707
#if NO_DATA != NO_ADDRESS
1708
      case NO_DATA:
1709
#endif
1710
        return EVUTIL_EAI_NODATA;
1711
      }
1712
    }
1713
1714
    if (ent->h_addrtype != hints.ai_family &&
1715
        hints.ai_family != PF_UNSPEC) {
1716
      /* This wasn't the type we were hoping for.  Too bad
1717
       * we never had a chance to ask gethostbyname for what
1718
       * we wanted. */
1719
      return EVUTIL_EAI_NONAME;
1720
    }
1721
1722
    /* Make sure we got _some_ answers. */
1723
    if (ent->h_length == 0)
1724
      return EVUTIL_EAI_NODATA;
1725
1726
    /* If we got an address type we don't know how to make a
1727
       sockaddr for, give up. */
1728
    if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
1729
      return EVUTIL_EAI_FAMILY;
1730
1731
    *res = addrinfo_from_hostent(ent, port, &hints);
1732
    if (! *res)
1733
      return EVUTIL_EAI_MEMORY;
1734
  }
1735
1736
  return 0;
1737
#endif
1738
1.32k
}
1739
1740
void
1741
evutil_freeaddrinfo(struct evutil_addrinfo *ai)
1742
202
{
1743
202
#ifdef EVENT__HAVE_GETADDRINFO
1744
202
  struct evutil_addrinfo *ai_prev = NULL;
1745
202
  struct evutil_addrinfo *ai_temp = ai;
1746
  /* Linked list may be the result of a native getaddrinfo() call plus
1747
   * locally allocated nodes, Before releasing it using freeaddrinfo(),
1748
   * these custom structs need to be freed separately.
1749
   */
1750
777
  while (ai_temp) {
1751
575
    struct evutil_addrinfo *next = ai_temp->ai_next;
1752
575
    if (ai_temp->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED) {
1753
      /* Remove this node from the linked list */
1754
254
      if (ai_temp->ai_canonname)
1755
0
        mm_free(ai_temp->ai_canonname);
1756
254
      mm_free(ai_temp);
1757
254
      if (ai_prev == NULL) {
1758
254
        ai = next;
1759
254
      } else {
1760
0
        ai_prev->ai_next = next;
1761
0
      }
1762
1763
321
    } else {
1764
321
      ai_prev = ai_temp;
1765
321
    }
1766
575
    ai_temp = next;
1767
575
  }
1768
202
  if (ai != NULL)
1769
107
    freeaddrinfo(ai);
1770
#else
1771
  while (ai) {
1772
    struct evutil_addrinfo *next = ai->ai_next;
1773
    if (ai->ai_canonname)
1774
      mm_free(ai->ai_canonname);
1775
    mm_free(ai);
1776
    ai = next;
1777
  }
1778
#endif
1779
202
}
1780
1781
struct evutil_addrinfo *
1782
evutil_dup_addrinfo_(struct evutil_addrinfo *ai)
1783
0
{
1784
0
  struct evutil_addrinfo *first = NULL;
1785
0
  struct evutil_addrinfo *prev = NULL;
1786
0
  for (; ai; ai = ai->ai_next) {
1787
0
    int len = sizeof(struct evutil_addrinfo) + ai->ai_addrlen;
1788
0
    struct evutil_addrinfo *n = mm_calloc(1, len);
1789
0
    memcpy(n, ai, len);
1790
0
    if (ai->ai_canonname) {
1791
0
      n->ai_canonname = mm_strdup(ai->ai_canonname);
1792
0
    }
1793
0
    n->ai_addr = (struct sockaddr*)(((char*)n) + sizeof(struct evutil_addrinfo));
1794
0
    if (!first) {
1795
0
      first = n;
1796
0
    } else {
1797
0
      prev->ai_next = n;
1798
0
    }
1799
0
    prev = n;
1800
0
  }
1801
0
  return first;
1802
0
}
1803
1804
static evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
1805
static evdns_getaddrinfo_cancel_fn evdns_getaddrinfo_cancel_impl = NULL;
1806
1807
void
1808
evutil_set_evdns_getaddrinfo_fn_(evdns_getaddrinfo_fn fn)
1809
0
{
1810
0
  if (!evdns_getaddrinfo_impl)
1811
0
    evdns_getaddrinfo_impl = fn;
1812
0
}
1813
void
1814
evutil_set_evdns_getaddrinfo_cancel_fn_(evdns_getaddrinfo_cancel_fn fn)
1815
0
{
1816
0
  if (!evdns_getaddrinfo_cancel_impl)
1817
0
    evdns_getaddrinfo_cancel_impl = fn;
1818
0
}
1819
1820
static const char *evutil_custom_resolvconf_filename = NULL;
1821
1822
void
1823
evutil_set_resolvconf_filename_(const char *filename)
1824
0
{
1825
0
  evutil_custom_resolvconf_filename = filename;
1826
0
}
1827
1828
const char *
1829
evutil_resolvconf_filename_(void)
1830
0
{
1831
0
  if (evutil_custom_resolvconf_filename)
1832
0
    return evutil_custom_resolvconf_filename;
1833
1834
0
  return "/etc/resolv.conf";
1835
0
}
1836
1837
/* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
1838
 * otherwise do a blocking resolve and pass the result to the callback in the
1839
 * way that evdns_getaddrinfo would.
1840
 */
1841
struct evdns_getaddrinfo_request *evutil_getaddrinfo_async_(
1842
    struct evdns_base *dns_base,
1843
    const char *nodename, const char *servname,
1844
    const struct evutil_addrinfo *hints_in,
1845
    void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
1846
0
{
1847
0
  if (dns_base && evdns_getaddrinfo_impl) {
1848
0
    return evdns_getaddrinfo_impl(
1849
0
      dns_base, nodename, servname, hints_in, cb, arg);
1850
0
  } else {
1851
0
    struct evutil_addrinfo *ai=NULL;
1852
0
    int err;
1853
0
    err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
1854
0
    cb(err, ai, arg);
1855
0
    return NULL;
1856
0
  }
1857
0
}
1858
1859
void evutil_getaddrinfo_cancel_async_(struct evdns_getaddrinfo_request *data)
1860
0
{
1861
0
  if (evdns_getaddrinfo_cancel_impl && data) {
1862
0
    evdns_getaddrinfo_cancel_impl(data);
1863
0
  }
1864
0
}
1865
1866
const char *
1867
evutil_gai_strerror(int err)
1868
0
{
1869
  /* As a sneaky side-benefit, this case statement will get most
1870
   * compilers to tell us if any of the error codes we defined
1871
   * conflict with the platform's native error codes. */
1872
0
  switch (err) {
1873
0
  case EVUTIL_EAI_CANCEL:
1874
0
    return "Request canceled";
1875
0
  case 0:
1876
0
    return "No error";
1877
1878
0
  case EVUTIL_EAI_ADDRFAMILY:
1879
0
    return "address family for nodename not supported";
1880
0
  case EVUTIL_EAI_AGAIN:
1881
0
    return "temporary failure in name resolution";
1882
0
  case EVUTIL_EAI_BADFLAGS:
1883
0
    return "invalid value for ai_flags";
1884
0
  case EVUTIL_EAI_FAIL:
1885
0
    return "non-recoverable failure in name resolution";
1886
0
  case EVUTIL_EAI_FAMILY:
1887
0
    return "ai_family not supported";
1888
0
  case EVUTIL_EAI_MEMORY:
1889
0
    return "memory allocation failure";
1890
0
  case EVUTIL_EAI_NODATA:
1891
0
    return "no address associated with nodename";
1892
0
  case EVUTIL_EAI_NONAME:
1893
0
    return "nodename nor servname provided, or not known";
1894
0
  case EVUTIL_EAI_SERVICE:
1895
0
    return "servname not supported for ai_socktype";
1896
0
  case EVUTIL_EAI_SOCKTYPE:
1897
0
    return "ai_socktype not supported";
1898
0
  case EVUTIL_EAI_SYSTEM:
1899
0
    return "system error";
1900
0
  default:
1901
#if defined(USE_NATIVE_GETADDRINFO) && defined(_WIN32)
1902
    return gai_strerrorA(err);
1903
#elif defined(USE_NATIVE_GETADDRINFO)
1904
    return gai_strerror(err);
1905
#else
1906
    return "Unknown error code";
1907
#endif
1908
0
  }
1909
0
}
1910
1911
#ifdef _WIN32
1912
/* destructively remove a trailing line terminator from s */
1913
static void
1914
chomp (char *s)
1915
{
1916
  size_t len;
1917
  if (s && (len = strlen (s)) > 0 && s[len - 1] == '\n') {
1918
    s[--len] = 0;
1919
    if (len > 0 && s[len - 1] == '\r')
1920
      s[--len] = 0;
1921
  }
1922
}
1923
1924
/* FormatMessage returns allocated strings, but evutil_socket_error_to_string
1925
 * is supposed to return a string which is good indefinitely without having
1926
 * to be freed.  To make this work without leaking memory, we cache the
1927
 * string the first time FormatMessage is called on a particular error
1928
 * code, and then return the cached string on subsequent calls with the
1929
 * same code.  The strings aren't freed until libevent_global_shutdown
1930
 * (or never).  We use a linked list to cache the errors, because we
1931
 * only expect there to be a few dozen, and that should be fast enough.
1932
 */
1933
1934
struct cached_sock_errs_entry {
1935
  HT_ENTRY(cached_sock_errs_entry) node;
1936
  DWORD code;
1937
  char *msg; /* allocated with LocalAlloc; free with LocalFree */
1938
};
1939
1940
static inline unsigned
1941
hash_cached_sock_errs(const struct cached_sock_errs_entry *e)
1942
{
1943
  /* Use Murmur3's 32-bit finalizer as an integer hash function */
1944
  DWORD h = e->code;
1945
  h ^= h >> 16;
1946
  h *= 0x85ebca6b;
1947
  h ^= h >> 13;
1948
  h *= 0xc2b2ae35;
1949
  h ^= h >> 16;
1950
  return h;
1951
}
1952
1953
static inline int
1954
eq_cached_sock_errs(const struct cached_sock_errs_entry *a,
1955
        const struct cached_sock_errs_entry *b)
1956
{
1957
  return a->code == b->code;
1958
}
1959
1960
#ifndef EVENT__DISABLE_THREAD_SUPPORT
1961
static void *windows_socket_errors_lock_ = NULL;
1962
#endif
1963
1964
static HT_HEAD(cached_sock_errs_map, cached_sock_errs_entry)
1965
     windows_socket_errors = HT_INITIALIZER();
1966
1967
HT_PROTOTYPE(cached_sock_errs_map,
1968
       cached_sock_errs_entry,
1969
       node,
1970
       hash_cached_sock_errs,
1971
       eq_cached_sock_errs);
1972
1973
HT_GENERATE(cached_sock_errs_map,
1974
      cached_sock_errs_entry,
1975
      node,
1976
      hash_cached_sock_errs,
1977
      eq_cached_sock_errs,
1978
      0.5,
1979
      mm_malloc,
1980
      mm_realloc,
1981
      mm_free);
1982
1983
/** Equivalent to strerror, but for windows socket errors. */
1984
const char *
1985
evutil_socket_error_to_string(int errcode)
1986
{
1987
  struct cached_sock_errs_entry *errs, *newerr, find;
1988
  char *msg = NULL;
1989
1990
  EVLOCK_LOCK(windows_socket_errors_lock_, 0);
1991
1992
  find.code = errcode;
1993
  errs = HT_FIND(cached_sock_errs_map, &windows_socket_errors, &find);
1994
  if (errs) {
1995
    msg = errs->msg;
1996
    goto done;
1997
  }
1998
1999
  if (0 != FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM |
2000
             FORMAT_MESSAGE_IGNORE_INSERTS |
2001
             FORMAT_MESSAGE_ALLOCATE_BUFFER,
2002
             NULL, errcode, 0, (char *)&msg, 0, NULL))
2003
    chomp (msg);  /* because message has trailing newline */
2004
  else {
2005
    size_t len = 50;
2006
    /* use LocalAlloc because FormatMessage does */
2007
    msg = LocalAlloc(LMEM_FIXED, len);
2008
    if (!msg) {
2009
      msg = (char *)"LocalAlloc failed during Winsock error";
2010
      goto done;
2011
    }
2012
    evutil_snprintf(msg, len, "winsock error 0x%08x", errcode);
2013
  }
2014
2015
  newerr = (struct cached_sock_errs_entry *)
2016
    mm_malloc(sizeof (struct cached_sock_errs_entry));
2017
2018
  if (!newerr) {
2019
    LocalFree(msg);
2020
    msg = (char *)"malloc failed during Winsock error";
2021
    goto done;
2022
  }
2023
2024
  newerr->code = errcode;
2025
  newerr->msg = msg;
2026
  HT_INSERT(cached_sock_errs_map, &windows_socket_errors, newerr);
2027
2028
 done:
2029
  EVLOCK_UNLOCK(windows_socket_errors_lock_, 0);
2030
2031
  return msg;
2032
}
2033
2034
#ifndef EVENT__DISABLE_THREAD_SUPPORT
2035
int
2036
evutil_global_setup_locks_(const int enable_locks)
2037
{
2038
  EVTHREAD_SETUP_GLOBAL_LOCK(windows_socket_errors_lock_, 0);
2039
  return 0;
2040
}
2041
#endif
2042
2043
static void
2044
evutil_free_sock_err_globals(void)
2045
{
2046
  struct cached_sock_errs_entry **errs, *tofree;
2047
2048
  for (errs = HT_START(cached_sock_errs_map, &windows_socket_errors)
2049
         ; errs; ) {
2050
    tofree = *errs;
2051
    errs = HT_NEXT_RMV(cached_sock_errs_map,
2052
           &windows_socket_errors,
2053
           errs);
2054
    LocalFree(tofree->msg);
2055
    mm_free(tofree);
2056
  }
2057
2058
  HT_CLEAR(cached_sock_errs_map, &windows_socket_errors);
2059
2060
#ifndef EVENT__DISABLE_THREAD_SUPPORT
2061
  if (windows_socket_errors_lock_ != NULL) {
2062
    EVTHREAD_FREE_LOCK(windows_socket_errors_lock_, 0);
2063
    windows_socket_errors_lock_ = NULL;
2064
  }
2065
#endif
2066
}
2067
2068
#else
2069
2070
#ifndef EVENT__DISABLE_THREAD_SUPPORT
2071
int
2072
evutil_global_setup_locks_(const int enable_locks)
2073
0
{
2074
0
  return 0;
2075
0
}
2076
#endif
2077
2078
static void
2079
evutil_free_sock_err_globals(void)
2080
0
{
2081
0
}
2082
2083
#endif
2084
2085
int
2086
evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
2087
803
{
2088
803
  int r;
2089
803
  va_list ap;
2090
803
  va_start(ap, format);
2091
803
  r = evutil_vsnprintf(buf, buflen, format, ap);
2092
803
  va_end(ap);
2093
803
  return r;
2094
803
}
2095
2096
int
2097
evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
2098
803
{
2099
803
  int r;
2100
803
  if (!buflen)
2101
0
    return 0;
2102
#if defined(_MSC_VER) || defined(_WIN32)
2103
  r = _vsnprintf(buf, buflen, format, ap);
2104
  if (r < 0)
2105
    r = _vscprintf(format, ap);
2106
#elif defined(sgi)
2107
  /* Make sure we always use the correct vsnprintf on IRIX */
2108
  extern int      _xpg5_vsnprintf(char * __restrict,
2109
    __SGI_LIBC_NAMESPACE_QUALIFIER size_t,
2110
    const char * __restrict, /* va_list */ char *);
2111
2112
  r = _xpg5_vsnprintf(buf, buflen, format, ap);
2113
#else
2114
803
  r = vsnprintf(buf, buflen, format, ap);
2115
803
#endif
2116
803
  buf[buflen-1] = '\0';
2117
803
  return r;
2118
803
}
2119
2120
#define USE_INTERNAL_NTOP
2121
#define USE_INTERNAL_PTON
2122
2123
const char *
2124
evutil_inet_ntop(int af, const void *src, char *dst, size_t len)
2125
246
{
2126
#if defined(EVENT__HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
2127
  return inet_ntop(af, src, dst, len);
2128
#else
2129
246
  if (af == AF_INET) {
2130
54
    const struct in_addr *in = src;
2131
54
    const ev_uint32_t a = ntohl(in->s_addr);
2132
54
    int r;
2133
54
    r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
2134
54
        (int)(ev_uint8_t)((a>>24)&0xff),
2135
54
        (int)(ev_uint8_t)((a>>16)&0xff),
2136
54
        (int)(ev_uint8_t)((a>>8 )&0xff),
2137
54
        (int)(ev_uint8_t)((a    )&0xff));
2138
54
    if (r<0||(size_t)r>=len)
2139
0
      return NULL;
2140
54
    else
2141
54
      return dst;
2142
54
#ifdef AF_INET6
2143
192
  } else if (af == AF_INET6) {
2144
192
    const struct in6_addr *addr = src;
2145
192
    char buf[64], *cp;
2146
192
    int longestGapLen = 0, longestGapPos = -1, i,
2147
192
      curGapPos = -1, curGapLen = 0;
2148
192
    ev_uint16_t words[8];
2149
1.72k
    for (i = 0; i < 8; ++i) {
2150
1.53k
      words[i] =
2151
1.53k
          (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
2152
1.53k
    }
2153
192
    if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
2154
192
        words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
2155
86
      (words[5] == 0xffff))) {
2156
      /* This is an IPv4 address. */
2157
29
      if (words[5] == 0) {
2158
28
        evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
2159
28
            addr->s6_addr[12], addr->s6_addr[13],
2160
28
            addr->s6_addr[14], addr->s6_addr[15]);
2161
28
      } else {
2162
1
        evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
2163
1
            addr->s6_addr[12], addr->s6_addr[13],
2164
1
            addr->s6_addr[14], addr->s6_addr[15]);
2165
1
      }
2166
29
      if (strlen(buf) > len)
2167
0
        return NULL;
2168
29
      strlcpy(dst, buf, len);
2169
29
      return dst;
2170
29
    }
2171
163
    i = 0;
2172
745
    while (i < 8) {
2173
582
      if (words[i] == 0) {
2174
250
        curGapPos = i++;
2175
250
        curGapLen = 1;
2176
972
        while (i<8 && words[i] == 0) {
2177
722
          ++i; ++curGapLen;
2178
722
        }
2179
250
        if (curGapLen > longestGapLen) {
2180
216
          longestGapPos = curGapPos;
2181
216
          longestGapLen = curGapLen;
2182
216
        }
2183
332
      } else {
2184
332
        ++i;
2185
332
      }
2186
582
    }
2187
163
    if (longestGapLen<=1)
2188
9
      longestGapPos = -1;
2189
2190
163
    cp = buf;
2191
791
    for (i = 0; i < 8; ++i) {
2192
628
      if (words[i] == 0 && longestGapPos == i) {
2193
154
        if (i == 0)
2194
76
          *cp++ = ':';
2195
154
        *cp++ = ':';
2196
984
        while (i < 8 && words[i] == 0)
2197
830
          ++i;
2198
154
        --i; /* to compensate for loop increment. */
2199
474
      } else {
2200
474
        evutil_snprintf(cp,
2201
474
                sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
2202
474
        cp += strlen(cp);
2203
474
        if (i != 7)
2204
387
          *cp++ = ':';
2205
474
      }
2206
628
    }
2207
163
    *cp = '\0';
2208
163
    if (strlen(buf) > len)
2209
0
      return NULL;
2210
163
    strlcpy(dst, buf, len);
2211
163
    return dst;
2212
163
#endif
2213
163
  } else {
2214
0
    return NULL;
2215
0
  }
2216
246
#endif
2217
246
}
2218
2219
int
2220
evutil_inet_pton_scope(int af, const char *src, void *dst, unsigned *indexp)
2221
1.62k
{
2222
1.62k
  int r;
2223
1.62k
  unsigned if_index;
2224
1.62k
  char *check, *cp, *tmp_src;
2225
2226
1.62k
  *indexp = 0; /* Reasonable default */
2227
2228
  /* Bail out if not IPv6 */
2229
1.62k
  if (af != AF_INET6)
2230
0
    return evutil_inet_pton(af, src, dst);
2231
2232
1.62k
  cp = strchr(src, '%');
2233
2234
  /* Bail out if no zone ID */
2235
1.62k
  if (cp == NULL)
2236
1.58k
    return evutil_inet_pton(af, src, dst);
2237
2238
34
  if_index = if_nametoindex(cp + 1);
2239
34
  if (if_index == 0) {
2240
    /* Could be numeric */
2241
31
    if_index = strtoul(cp + 1, &check, 10);
2242
31
    if (check[0] != '\0')
2243
23
      return 0;
2244
31
  }
2245
11
  *indexp = if_index;
2246
11
  if (!(tmp_src = mm_strdup(src))) {
2247
0
    return -1;
2248
0
  }
2249
11
  cp = strchr(tmp_src, '%');
2250
  // The check had been already done above against original src
2251
11
  *cp = '\0';
2252
11
  r = evutil_inet_pton(af, tmp_src, dst);
2253
11
  mm_free(tmp_src);
2254
11
  return r;
2255
11
}
2256
2257
int
2258
evutil_inet_pton(int af, const char *src, void *dst)
2259
3.81k
{
2260
#if defined(EVENT__HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
2261
  return inet_pton(af, src, dst);
2262
#else
2263
3.81k
  if (af == AF_INET) {
2264
2.21k
    unsigned a,b,c,d;
2265
2.21k
    char more;
2266
2.21k
    struct in_addr *addr = dst;
2267
2.21k
    if (sscanf(src, "%u.%u.%u.%u%c", &a,&b,&c,&d,&more) != 4)
2268
1.74k
      return 0;
2269
472
    if (a > 255) return 0;
2270
362
    if (b > 255) return 0;
2271
276
    if (c > 255) return 0;
2272
190
    if (d > 255) return 0;
2273
106
    addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
2274
106
    return 1;
2275
190
#ifdef AF_INET6
2276
1.59k
  } else if (af == AF_INET6) {
2277
1.59k
    struct in6_addr *out = dst;
2278
1.59k
    ev_uint16_t words[8];
2279
1.59k
    int gapPos = -1, i, setWords=0;
2280
1.59k
    const char *dot = strchr(src, '.');
2281
1.59k
    const char *eow; /* end of words. */
2282
1.59k
    if (dot == src)
2283
6
      return 0;
2284
1.59k
    else if (!dot)
2285
1.27k
      eow = src+strlen(src);
2286
318
    else {
2287
318
      unsigned byte1,byte2,byte3,byte4;
2288
318
      char more;
2289
1.48k
      for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT_(*eow); --eow)
2290
1.16k
        ;
2291
318
      ++eow;
2292
2293
      /* We use "scanf" because some platform inet_aton()s are too lax
2294
       * about IPv4 addresses of the form "1.2.3" */
2295
318
      if (sscanf(eow, "%u.%u.%u.%u%c",
2296
318
             &byte1,&byte2,&byte3,&byte4,&more) != 4)
2297
47
        return 0;
2298
2299
271
      if (byte1 > 255 ||
2300
271
          byte2 > 255 ||
2301
271
          byte3 > 255 ||
2302
271
          byte4 > 255)
2303
205
        return 0;
2304
2305
66
      words[6] = (byte1<<8) | byte2;
2306
66
      words[7] = (byte3<<8) | byte4;
2307
66
      setWords += 2;
2308
66
    }
2309
2310
1.34k
    i = 0;
2311
2.28k
    while (src < eow) {
2312
1.28k
      if (i > 7)
2313
5
        return 0;
2314
1.28k
      if (EVUTIL_ISXDIGIT_(*src)) {
2315
815
        char *next;
2316
815
        long r = strtol(src, &next, 16);
2317
815
        if (next > 4+src)
2318
38
          return 0;
2319
777
        if (next == src)
2320
0
          return 0;
2321
777
        if (r<0 || r>65536)
2322
0
          return 0;
2323
2324
777
        words[i++] = (ev_uint16_t)r;
2325
777
        setWords++;
2326
777
        src = next;
2327
777
        if (*src != ':' && src != eow)
2328
62
          return 0;
2329
715
        ++src;
2330
715
      } else if (*src == ':' && i > 0 && gapPos==-1) {
2331
97
        gapPos = i;
2332
97
        ++src;
2333
368
      } else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
2334
127
        gapPos = i;
2335
127
        src += 2;
2336
241
      } else {
2337
241
        return 0;
2338
241
      }
2339
1.28k
    }
2340
2341
995
    if (setWords > 8 ||
2342
995
      (setWords == 8 && gapPos != -1) ||
2343
995
      (setWords < 8 && gapPos == -1))
2344
792
      return 0;
2345
2346
203
    if (gapPos >= 0) {
2347
197
      int nToMove = setWords - (dot ? 2 : 0) - gapPos;
2348
197
      int gapLen = 8 - setWords;
2349
      /* assert(nToMove >= 0); */
2350
197
      if (nToMove < 0)
2351
0
        return -1; /* should be impossible */
2352
197
      memmove(&words[gapPos+gapLen], &words[gapPos],
2353
197
          sizeof(ev_uint16_t)*nToMove);
2354
197
      memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
2355
197
    }
2356
1.82k
    for (i = 0; i < 8; ++i) {
2357
1.62k
      out->s6_addr[2*i  ] = words[i] >> 8;
2358
1.62k
      out->s6_addr[2*i+1] = words[i] & 0xff;
2359
1.62k
    }
2360
2361
203
    return 1;
2362
203
#endif
2363
203
  } else {
2364
0
    return -1;
2365
0
  }
2366
3.81k
#endif
2367
3.81k
}
2368
2369
int
2370
evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
2371
1.32k
{
2372
1.32k
  int port;
2373
1.32k
  unsigned int if_index;
2374
1.32k
  char buf[128];
2375
1.32k
  const char *cp, *addr_part, *port_part;
2376
1.32k
  int is_ipv6;
2377
  /* recognized formats are:
2378
   * [ipv6]:port
2379
   * ipv6
2380
   * [ipv6]
2381
   * ipv4:port
2382
   * ipv4
2383
   */
2384
2385
1.32k
  cp = strchr(ip_as_string, ':');
2386
1.32k
  if (*ip_as_string == '[') {
2387
55
    size_t len;
2388
55
    if (!(cp = strchr(ip_as_string, ']'))) {
2389
10
      return -1;
2390
10
    }
2391
45
    len = ( cp-(ip_as_string + 1) );
2392
45
    if (len > sizeof(buf)-1) {
2393
17
      return -1;
2394
17
    }
2395
28
    memcpy(buf, ip_as_string+1, len);
2396
28
    buf[len] = '\0';
2397
28
    addr_part = buf;
2398
28
    if (cp[1] == ':')
2399
2
      port_part = cp+2;
2400
26
    else
2401
26
      port_part = NULL;
2402
28
    is_ipv6 = 1;
2403
1.26k
  } else if (cp && strchr(cp+1, ':')) {
2404
273
    is_ipv6 = 1;
2405
273
    addr_part = ip_as_string;
2406
273
    port_part = NULL;
2407
994
  } else if (cp) {
2408
126
    is_ipv6 = 0;
2409
126
    if (cp - ip_as_string > (int)sizeof(buf)-1) {
2410
19
      return -1;
2411
19
    }
2412
107
    memcpy(buf, ip_as_string, cp-ip_as_string);
2413
107
    buf[cp-ip_as_string] = '\0';
2414
107
    addr_part = buf;
2415
107
    port_part = cp+1;
2416
868
  } else {
2417
868
    addr_part = ip_as_string;
2418
868
    port_part = NULL;
2419
868
    is_ipv6 = 0;
2420
868
  }
2421
2422
1.27k
  if (port_part == NULL) {
2423
1.16k
    port = 0;
2424
1.16k
  } else {
2425
109
    port = atoi(port_part);
2426
109
    if (port <= 0 || port > 65535) {
2427
73
      return -1;
2428
73
    }
2429
109
  }
2430
2431
1.20k
  if (!addr_part)
2432
0
    return -1; /* Should be impossible. */
2433
1.20k
#ifdef AF_INET6
2434
1.20k
  if (is_ipv6)
2435
300
  {
2436
300
    struct sockaddr_in6 sin6;
2437
300
    memset(&sin6, 0, sizeof(sin6));
2438
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
2439
    sin6.sin6_len = sizeof(sin6);
2440
#endif
2441
300
    sin6.sin6_family = AF_INET6;
2442
300
    sin6.sin6_port = htons(port);
2443
300
    if (1 != evutil_inet_pton_scope(
2444
300
      AF_INET6, addr_part, &sin6.sin6_addr, &if_index)) {
2445
108
      return -1;
2446
108
    }
2447
192
    if ((int)sizeof(sin6) > *outlen)
2448
0
      return -1;
2449
192
    sin6.sin6_scope_id = if_index;
2450
192
    memcpy(out, &sin6, sizeof(sin6));
2451
192
    *outlen = sizeof(sin6);
2452
192
    return 0;
2453
192
  }
2454
903
  else
2455
903
#endif
2456
903
  {
2457
903
    struct sockaddr_in sin;
2458
903
    memset(&sin, 0, sizeof(sin));
2459
#ifdef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
2460
    sin.sin_len = sizeof(sin);
2461
#endif
2462
903
    sin.sin_family = AF_INET;
2463
903
    sin.sin_port = htons(port);
2464
903
    if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
2465
849
      return -1;
2466
54
    if ((int)sizeof(sin) > *outlen)
2467
0
      return -1;
2468
54
    memcpy(out, &sin, sizeof(sin));
2469
54
    *outlen = sizeof(sin);
2470
54
    return 0;
2471
54
  }
2472
1.20k
}
2473
2474
const char *
2475
evutil_format_sockaddr_port_(const struct sockaddr *sa, char *out, size_t outlen)
2476
246
{
2477
246
  char b[128];
2478
246
  const char *res=NULL;
2479
246
  int port;
2480
246
  if (sa->sa_family == AF_INET) {
2481
54
    const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
2482
54
    res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
2483
54
    port = ntohs(sin->sin_port);
2484
54
    if (res) {
2485
54
      evutil_snprintf(out, outlen, "%s:%d", b, port);
2486
54
      return out;
2487
54
    }
2488
192
  } else if (sa->sa_family == AF_INET6) {
2489
192
    const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
2490
192
    res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
2491
192
    port = ntohs(sin6->sin6_port);
2492
192
    if (res) {
2493
192
      evutil_snprintf(out, outlen, "[%s]:%d", b, port);
2494
192
      return out;
2495
192
    }
2496
192
  }
2497
2498
0
  evutil_snprintf(out, outlen, "<addr with socktype %d>",
2499
0
      (int)sa->sa_family);
2500
0
  return out;
2501
246
}
2502
2503
int
2504
evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
2505
    int include_port)
2506
0
{
2507
0
  int r;
2508
0
  if (0 != (r = (sa1->sa_family - sa2->sa_family)))
2509
0
    return r;
2510
2511
0
  if (sa1->sa_family == AF_INET) {
2512
0
    const struct sockaddr_in *sin1, *sin2;
2513
0
    sin1 = (const struct sockaddr_in *)sa1;
2514
0
    sin2 = (const struct sockaddr_in *)sa2;
2515
0
    if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
2516
0
      return -1;
2517
0
    else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
2518
0
      return 1;
2519
0
    else if (include_port &&
2520
0
        (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
2521
0
      return r;
2522
0
    else
2523
0
      return 0;
2524
0
  }
2525
0
#ifdef AF_INET6
2526
0
  else if (sa1->sa_family == AF_INET6) {
2527
0
    const struct sockaddr_in6 *sin1, *sin2;
2528
0
    sin1 = (const struct sockaddr_in6 *)sa1;
2529
0
    sin2 = (const struct sockaddr_in6 *)sa2;
2530
0
    if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
2531
0
      return r;
2532
0
    else if (include_port &&
2533
0
        (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
2534
0
      return r;
2535
0
    else
2536
0
      return 0;
2537
0
  }
2538
0
#endif
2539
0
  return 1;
2540
0
}
2541
2542
/* Tables to implement ctypes-replacement EVUTIL_IS*() functions.  Each table
2543
 * has 256 bits to look up whether a character is in some set or not.  This
2544
 * fails on non-ASCII platforms, but so does every other place where we
2545
 * take a char and write it onto the network.
2546
 **/
2547
static const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
2548
  { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
2549
static const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
2550
  { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
2551
static const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
2552
static const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
2553
  { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
2554
static const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
2555
static const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
2556
  { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
2557
static const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
2558
static const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
2559
/* Upper-casing and lowercasing tables to map characters to upper/lowercase
2560
 * equivalents. */
2561
static const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
2562
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2563
  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2564
  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2565
  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2566
  64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2567
  80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
2568
  96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
2569
  80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
2570
  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2571
  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2572
  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2573
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2574
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2575
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2576
  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2577
  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2578
};
2579
static const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
2580
  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2581
  16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2582
  32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2583
  48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2584
  64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2585
  112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
2586
  96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2587
  112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
2588
  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2589
  144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2590
  160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2591
  176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2592
  192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2593
  208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2594
  224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2595
  240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2596
};
2597
2598
#define IMPL_CTYPE_FN(name)           \
2599
2.52k
  int EVUTIL_##name##_(char c) {         \
2600
2.52k
    ev_uint8_t u = c;         \
2601
2.52k
    return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1U << (u & 31))); \
2602
2.52k
  }
Unexecuted instantiation: EVUTIL_ISALPHA_
Unexecuted instantiation: EVUTIL_ISALNUM_
Unexecuted instantiation: EVUTIL_ISSPACE_
EVUTIL_ISDIGIT_
Line
Count
Source
2599
1.24k
  int EVUTIL_##name##_(char c) {         \
2600
1.24k
    ev_uint8_t u = c;         \
2601
1.24k
    return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1U << (u & 31))); \
2602
1.24k
  }
EVUTIL_ISXDIGIT_
Line
Count
Source
2599
1.28k
  int EVUTIL_##name##_(char c) {         \
2600
1.28k
    ev_uint8_t u = c;         \
2601
1.28k
    return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1U << (u & 31))); \
2602
1.28k
  }
Unexecuted instantiation: EVUTIL_ISPRINT_
Unexecuted instantiation: EVUTIL_ISLOWER_
Unexecuted instantiation: EVUTIL_ISUPPER_
2603
IMPL_CTYPE_FN(ISALPHA)
2604
IMPL_CTYPE_FN(ISALNUM)
2605
IMPL_CTYPE_FN(ISSPACE)
2606
IMPL_CTYPE_FN(ISDIGIT)
2607
IMPL_CTYPE_FN(ISXDIGIT)
2608
IMPL_CTYPE_FN(ISPRINT)
2609
IMPL_CTYPE_FN(ISLOWER)
2610
IMPL_CTYPE_FN(ISUPPER)
2611
2612
char EVUTIL_TOLOWER_(char c)
2613
0
{
2614
0
  return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
2615
0
}
2616
char EVUTIL_TOUPPER_(char c)
2617
0
{
2618
0
  return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
2619
0
}
2620
int
2621
evutil_ascii_strcasecmp(const char *s1, const char *s2)
2622
0
{
2623
0
  char c1, c2;
2624
0
  while (1) {
2625
0
    c1 = EVUTIL_TOLOWER_(*s1++);
2626
0
    c2 = EVUTIL_TOLOWER_(*s2++);
2627
0
    if (c1 < c2)
2628
0
      return -1;
2629
0
    else if (c1 > c2)
2630
0
      return 1;
2631
0
    else if (c1 == 0)
2632
0
      return 0;
2633
0
  }
2634
0
}
2635
int evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
2636
0
{
2637
0
  char c1, c2;
2638
0
  while (n--) {
2639
0
    c1 = EVUTIL_TOLOWER_(*s1++);
2640
0
    c2 = EVUTIL_TOLOWER_(*s2++);
2641
0
    if (c1 < c2)
2642
0
      return -1;
2643
0
    else if (c1 > c2)
2644
0
      return 1;
2645
0
    else if (c1 == 0)
2646
0
      return 0;
2647
0
  }
2648
0
  return 0;
2649
0
}
2650
2651
const char* evutil_ascii_strcasestr(const char* s, const char *find)
2652
0
{
2653
0
  char c, sc;
2654
0
  size_t len;
2655
2656
0
  if ((c = *find++) != 0) {
2657
0
    c = EVUTIL_TOLOWER_(c);
2658
0
    len = strlen(find);
2659
0
    do {
2660
0
      do {
2661
0
        if ((sc = *s++) == 0)
2662
0
          return (NULL);
2663
0
      } while ((char)EVUTIL_TOLOWER_(sc) != c);
2664
0
    } while (evutil_ascii_strncasecmp(s, find, len) != 0);
2665
0
    s--;
2666
0
  }
2667
0
  return s;
2668
0
}
2669
2670
void
2671
evutil_rtrim_lws_(char *str)
2672
0
{
2673
0
  char *cp;
2674
2675
0
  if (str == NULL)
2676
0
    return;
2677
2678
0
  if ((cp = strchr(str, '\0')) == NULL || (cp == str))
2679
0
    return;
2680
2681
0
  --cp;
2682
2683
0
  while (*cp == ' ' || *cp == '\t') {
2684
0
    *cp = '\0';
2685
0
    if (cp == str)
2686
0
      break;
2687
0
    --cp;
2688
0
  }
2689
0
}
2690
2691
static int
2692
evutil_issetugid(void)
2693
0
{
2694
#ifdef EVENT__HAVE_ISSETUGID
2695
  return issetugid();
2696
#else
2697
2698
0
#ifdef EVENT__HAVE_GETEUID
2699
0
  if (getuid() != geteuid())
2700
0
    return 1;
2701
0
#endif
2702
0
#ifdef EVENT__HAVE_GETEGID
2703
0
  if (getgid() != getegid())
2704
0
    return 1;
2705
0
#endif
2706
0
  return 0;
2707
0
#endif
2708
0
}
2709
2710
const char *
2711
evutil_getenv_(const char *varname)
2712
0
{
2713
0
  if (evutil_issetugid())
2714
0
    return NULL;
2715
2716
0
  return getenv(varname);
2717
0
}
2718
2719
ev_uint32_t
2720
evutil_weakrand_seed_(struct evutil_weakrand_state *state, ev_uint32_t seed)
2721
0
{
2722
0
  if (seed == 0) {
2723
0
    struct timeval tv;
2724
0
    evutil_gettimeofday(&tv, NULL);
2725
0
    seed = (ev_uint32_t)tv.tv_sec + (ev_uint32_t)tv.tv_usec;
2726
#ifdef _WIN32
2727
    seed += (ev_uint32_t) _getpid();
2728
#else
2729
0
    seed += (ev_uint32_t) getpid();
2730
0
#endif
2731
0
  }
2732
0
  state->seed = seed;
2733
0
  return seed;
2734
0
}
2735
2736
ev_int32_t
2737
evutil_weakrand_(struct evutil_weakrand_state *state)
2738
0
{
2739
  /* This RNG implementation is a linear congruential generator, with
2740
   * modulus 2^31, multiplier 1103515245, and addend 12345.  It's also
2741
   * used by OpenBSD, and by Glibc's TYPE_0 RNG.
2742
   *
2743
   * The linear congruential generator is not an industrial-strength
2744
   * RNG!  It's fast, but it can have higher-order patterns.  Notably,
2745
   * the low bits tend to have periodicity.
2746
   */
2747
0
  state->seed = ((state->seed) * 1103515245 + 12345) & 0x7fffffff;
2748
0
  return (ev_int32_t)(state->seed);
2749
0
}
2750
2751
ev_int32_t
2752
evutil_weakrand_range_(struct evutil_weakrand_state *state, ev_int32_t top)
2753
0
{
2754
0
  ev_int32_t divisor, result;
2755
2756
  /* We can't just do weakrand() % top, since the low bits of the LCG
2757
   * are less random than the high ones.  (Specifically, since the LCG
2758
   * modulus is 2^N, every 2^m for m<N will divide the modulus, and so
2759
   * therefore the low m bits of the LCG will have period 2^m.) */
2760
0
  divisor = EVUTIL_WEAKRAND_MAX / top;
2761
0
  do {
2762
0
    result = evutil_weakrand_(state) / divisor;
2763
0
  } while (result >= top);
2764
0
  return result;
2765
0
}
2766
2767
/**
2768
 * Volatile pointer to memset: we use this to keep the compiler from
2769
 * eliminating our call to memset.
2770
 */
2771
void * (*volatile evutil_memset_volatile_)(void *, int, size_t) = memset;
2772
2773
void
2774
evutil_memclear_(void *mem, size_t len)
2775
0
{
2776
0
  evutil_memset_volatile_(mem, 0, len);
2777
0
}
2778
2779
int
2780
evutil_sockaddr_is_loopback_(const struct sockaddr *addr)
2781
0
{
2782
0
  static const char LOOPBACK_S6[16] =
2783
0
      "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
2784
0
  if (addr->sa_family == AF_INET) {
2785
0
    struct sockaddr_in *sin = (struct sockaddr_in *)addr;
2786
0
    return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
2787
0
  } else if (addr->sa_family == AF_INET6) {
2788
0
    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
2789
0
    return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
2790
0
  }
2791
0
  return 0;
2792
0
}
2793
2794
int
2795
evutil_hex_char_to_int_(char c)
2796
0
{
2797
0
  switch(c)
2798
0
  {
2799
0
    case '0': return 0;
2800
0
    case '1': return 1;
2801
0
    case '2': return 2;
2802
0
    case '3': return 3;
2803
0
    case '4': return 4;
2804
0
    case '5': return 5;
2805
0
    case '6': return 6;
2806
0
    case '7': return 7;
2807
0
    case '8': return 8;
2808
0
    case '9': return 9;
2809
0
    case 'A': case 'a': return 10;
2810
0
    case 'B': case 'b': return 11;
2811
0
    case 'C': case 'c': return 12;
2812
0
    case 'D': case 'd': return 13;
2813
0
    case 'E': case 'e': return 14;
2814
0
    case 'F': case 'f': return 15;
2815
0
  }
2816
0
  return -1;
2817
0
}
2818
2819
#ifdef _WIN32
2820
HMODULE
2821
evutil_load_windows_system_library_(const TCHAR *library_name)
2822
{
2823
  TCHAR path[MAX_PATH];
2824
  unsigned n;
2825
  n = GetSystemDirectory(path, MAX_PATH);
2826
  if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
2827
    return 0;
2828
  _tcscat(path, TEXT("\\"));
2829
  _tcscat(path, library_name);
2830
  return LoadLibrary(path);
2831
}
2832
#endif
2833
2834
/* Internal wrapper around 'socket' to provide Linux-style support for
2835
 * syscall-saving methods where available.
2836
 *
2837
 * In addition to regular socket behavior, you can use a bitwise or to set the
2838
 * flags EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'type' argument,
2839
 * to make the socket nonblocking or close-on-exec with as few syscalls as
2840
 * possible.
2841
 */
2842
evutil_socket_t
2843
evutil_socket_(int domain, int type, int protocol)
2844
0
{
2845
0
  evutil_socket_t r;
2846
0
#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
2847
0
  r = socket(domain, type, protocol);
2848
0
  if (r >= 0)
2849
0
    return r;
2850
0
  else if ((type & (SOCK_NONBLOCK|SOCK_CLOEXEC)) == 0)
2851
0
    return -1;
2852
0
#endif
2853
0
#define SOCKET_TYPE_MASK (~(EVUTIL_SOCK_NONBLOCK|EVUTIL_SOCK_CLOEXEC))
2854
0
  r = socket(domain, type & SOCKET_TYPE_MASK, protocol);
2855
0
  if (r < 0)
2856
0
    return -1;
2857
0
  if (type & EVUTIL_SOCK_NONBLOCK) {
2858
0
    if (evutil_fast_socket_nonblocking(r) < 0) {
2859
0
      evutil_closesocket(r);
2860
0
      return -1;
2861
0
    }
2862
0
  }
2863
0
  if (type & EVUTIL_SOCK_CLOEXEC) {
2864
0
    if (evutil_fast_socket_closeonexec(r) < 0) {
2865
0
      evutil_closesocket(r);
2866
0
      return -1;
2867
0
    }
2868
0
  }
2869
0
  return r;
2870
0
}
2871
2872
int
2873
evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
2874
0
{
2875
0
  int ret = 0;
2876
0
  int sock_type = type;
2877
0
  (void) sock_type;
2878
  /* SOCK_NONBLOCK and SOCK_CLOEXEC are UNIX-specific. Therefore, the predefined and
2879
   * platform-independent macros EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC are used
2880
   * in type argument as combination while SOCK_NONBLOCK and SOCK_CLOEXEC are used for
2881
   * distinguishing platforms.
2882
   */
2883
#ifndef SOCK_NONBLOCK
2884
  type &= ~EVUTIL_SOCK_NONBLOCK;
2885
#endif
2886
#ifndef SOCK_CLOEXEC
2887
  type &= ~EVUTIL_SOCK_CLOEXEC;
2888
#endif
2889
#if defined(_WIN32)
2890
  ret = evutil_win_socketpair(family, type, protocol, fd);
2891
#elif defined(EVENT__HAVE_SOCKETPAIR)
2892
  ret = socketpair(family, type, protocol, fd);
2893
#else
2894
  ret = evutil_ersatz_socketpair_(family, type, protocol, fd);
2895
#endif
2896
0
  if (ret)
2897
0
    return ret;
2898
#ifndef SOCK_NONBLOCK
2899
  if (sock_type & EVUTIL_SOCK_NONBLOCK) {
2900
    if ((ret = evutil_fast_socket_nonblocking(fd[0]))) {
2901
      evutil_closesocket(fd[0]);
2902
      evutil_closesocket(fd[1]);
2903
      return ret;
2904
    }
2905
    if ((ret = evutil_fast_socket_nonblocking(fd[1]))) {
2906
      evutil_closesocket(fd[0]);
2907
      evutil_closesocket(fd[1]);
2908
      return ret;
2909
    }
2910
  }
2911
#endif
2912
#ifndef SOCK_CLOEXEC
2913
  if (sock_type & EVUTIL_SOCK_CLOEXEC) {
2914
    if ((ret = evutil_fast_socket_closeonexec(fd[0]))) {
2915
      evutil_closesocket(fd[0]);
2916
      evutil_closesocket(fd[1]);
2917
      return ret;
2918
    }
2919
    if ((ret = evutil_fast_socket_closeonexec(fd[1]))) {
2920
      evutil_closesocket(fd[0]);
2921
      evutil_closesocket(fd[1]);
2922
      return ret;
2923
    }
2924
  }
2925
#endif
2926
0
  return ret;
2927
0
}
2928
2929
int
2930
evutil_ersatz_socketpair_(int family, int type, int protocol,
2931
    evutil_socket_t fd[2])
2932
0
{
2933
  /* This code is originally from Tor.  Used with permission. */
2934
2935
  /* This socketpair does not work when localhost is down. So
2936
   * it's really not the same thing at all. But it's close enough
2937
   * for now, and really, when localhost is down sometimes, we
2938
   * have other problems too.
2939
   */
2940
0
#undef ERR
2941
#ifdef _WIN32
2942
#define ERR(e) WSA##e
2943
#else
2944
0
#define ERR(e) e
2945
0
#endif
2946
0
  evutil_socket_t listener = -1;
2947
0
  evutil_socket_t connector = -1;
2948
0
  evutil_socket_t acceptor = -1;
2949
0
  struct sockaddr_in listen_addr;
2950
0
  struct sockaddr_in connect_addr;
2951
0
  ev_socklen_t size;
2952
0
  int saved_errno = -1;
2953
0
  int family_test;
2954
2955
0
  family_test = family != AF_INET;
2956
0
#ifdef AF_UNIX
2957
0
  family_test = family_test && (family != AF_UNIX);
2958
0
#endif
2959
0
  if (protocol || family_test) {
2960
0
    EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
2961
0
    return -1;
2962
0
  }
2963
2964
0
  if (!fd) {
2965
0
    EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
2966
0
    return -1;
2967
0
  }
2968
2969
0
  listener = socket(AF_INET, type, 0);
2970
0
  if (listener < 0)
2971
0
    return -1;
2972
0
  memset(&listen_addr, 0, sizeof(listen_addr));
2973
0
  listen_addr.sin_family = AF_INET;
2974
0
  listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
2975
0
  listen_addr.sin_port = 0; /* kernel chooses port.  */
2976
0
  if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
2977
0
    == -1)
2978
0
    goto tidy_up_and_fail;
2979
0
  if (listen(listener, 1) == -1)
2980
0
    goto tidy_up_and_fail;
2981
2982
0
  connector = socket(AF_INET, type, 0);
2983
0
  if (connector < 0)
2984
0
    goto tidy_up_and_fail;
2985
2986
0
  memset(&connect_addr, 0, sizeof(connect_addr));
2987
2988
  /* We want to find out the port number to connect to.  */
2989
0
  size = sizeof(connect_addr);
2990
0
  if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
2991
0
    goto tidy_up_and_fail;
2992
0
  if (size != sizeof(connect_addr))
2993
0
    goto abort_tidy_up_and_fail;
2994
0
  if (connect(connector, (struct sockaddr *) &connect_addr,
2995
0
        sizeof(connect_addr)) == -1) {
2996
    /* It's OK for a non-blocking socket to get an EINPROGRESS from connect(). */
2997
0
    int err = evutil_socket_geterror(connector);
2998
0
    if (!(EVUTIL_ERR_CONNECT_RETRIABLE(err) && type & EVUTIL_SOCK_NONBLOCK))
2999
0
      goto tidy_up_and_fail;
3000
0
  }
3001
3002
0
  size = sizeof(listen_addr);
3003
0
  do {
3004
0
    acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
3005
0
  } while(acceptor < 0 && EVUTIL_ERR_ACCEPT_RETRIABLE(errno) && type & EVUTIL_SOCK_NONBLOCK);
3006
0
  if (acceptor < 0)
3007
0
    goto tidy_up_and_fail;
3008
0
  if (size != sizeof(listen_addr))
3009
0
    goto abort_tidy_up_and_fail;
3010
  /* Now check we are talking to ourself by matching port and host on the
3011
     two sockets.  */
3012
0
  if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
3013
0
    goto tidy_up_and_fail;
3014
0
  if (size != sizeof (connect_addr)
3015
0
    || listen_addr.sin_family != connect_addr.sin_family
3016
0
    || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
3017
0
    || listen_addr.sin_port != connect_addr.sin_port)
3018
0
    goto abort_tidy_up_and_fail;
3019
0
  evutil_closesocket(listener);
3020
0
  fd[0] = connector;
3021
0
  fd[1] = acceptor;
3022
3023
0
  return 0;
3024
3025
0
 abort_tidy_up_and_fail:
3026
0
  saved_errno = ERR(ECONNABORTED);
3027
0
 tidy_up_and_fail:
3028
0
  if (saved_errno < 0)
3029
0
    saved_errno = EVUTIL_SOCKET_ERROR();
3030
0
  if (listener != -1)
3031
0
    evutil_closesocket(listener);
3032
0
  if (connector != -1)
3033
0
    evutil_closesocket(connector);
3034
0
  if (acceptor != -1)
3035
0
    evutil_closesocket(acceptor);
3036
3037
0
  EVUTIL_SET_SOCKET_ERROR(saved_errno);
3038
0
  return -1;
3039
0
#undef ERR
3040
0
}
3041
3042
/* Internal wrapper around 'accept' or 'accept4' to provide Linux-style
3043
 * support for syscall-saving methods where available.
3044
 *
3045
 * In addition to regular accept behavior, you can set one or more of flags
3046
 * EVUTIL_SOCK_NONBLOCK and EVUTIL_SOCK_CLOEXEC in the 'flags' argument, to
3047
 * make the socket nonblocking or close-on-exec with as few syscalls as
3048
 * possible.
3049
 */
3050
evutil_socket_t
3051
evutil_accept4_(evutil_socket_t sockfd, struct sockaddr *addr,
3052
    ev_socklen_t *addrlen, int flags)
3053
0
{
3054
0
  evutil_socket_t result;
3055
0
#if defined(EVENT__HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
3056
0
  result = accept4(sockfd, addr, addrlen, flags);
3057
0
  if (result >= 0 || (errno != EINVAL && errno != ENOSYS)) {
3058
    /* A nonnegative result means that we succeeded, so return.
3059
     * Failing with EINVAL means that an option wasn't supported,
3060
     * and failing with ENOSYS means that the syscall wasn't
3061
     * there: in those cases we want to fall back.  Otherwise, we
3062
     * got a real error, and we should return. */
3063
0
    return result;
3064
0
  }
3065
0
#endif
3066
0
  result = accept(sockfd, addr, addrlen);
3067
0
  if (result < 0)
3068
0
    return result;
3069
3070
0
  if (flags & EVUTIL_SOCK_CLOEXEC) {
3071
0
    if (evutil_fast_socket_closeonexec(result) < 0) {
3072
0
      evutil_closesocket(result);
3073
0
      return -1;
3074
0
    }
3075
0
  }
3076
0
  if (flags & EVUTIL_SOCK_NONBLOCK) {
3077
0
    if (evutil_fast_socket_nonblocking(result) < 0) {
3078
0
      evutil_closesocket(result);
3079
0
      return -1;
3080
0
    }
3081
0
  }
3082
0
  return result;
3083
0
}
3084
3085
/* Internal function: Set fd[0] and fd[1] to a pair of fds such that writes on
3086
 * fd[1] get read from fd[0].  Make both fds nonblocking and close-on-exec.
3087
 * Return 0 on success, -1 on failure.
3088
 */
3089
int
3090
evutil_make_internal_pipe_(evutil_socket_t fd[2])
3091
0
{
3092
  /*
3093
    Making the second socket nonblocking is a bit subtle, given that we
3094
    ignore any EAGAIN returns when writing to it, and you don't usually
3095
    do that for a nonblocking socket. But if the kernel gives us EAGAIN,
3096
    then there's no need to add any more data to the buffer, since
3097
    the main thread is already either about to wake up and drain it,
3098
    or woken up and in the process of draining it.
3099
  */
3100
3101
0
#if defined(EVENT__HAVE_PIPE2)
3102
0
  if (pipe2(fd, O_NONBLOCK|O_CLOEXEC) == 0)
3103
0
    return 0;
3104
0
#endif
3105
0
#if defined(EVENT__HAVE_PIPE)
3106
0
  if (pipe(fd) == 0) {
3107
0
    if (evutil_fast_socket_nonblocking(fd[0]) < 0 ||
3108
0
        evutil_fast_socket_nonblocking(fd[1]) < 0 ||
3109
0
        evutil_fast_socket_closeonexec(fd[0]) < 0 ||
3110
0
        evutil_fast_socket_closeonexec(fd[1]) < 0) {
3111
0
      close(fd[0]);
3112
0
      close(fd[1]);
3113
0
      fd[0] = fd[1] = -1;
3114
0
      return -1;
3115
0
    }
3116
0
    return 0;
3117
0
  } else {
3118
0
    event_warn("%s: pipe", __func__);
3119
0
  }
3120
0
#endif
3121
3122
#if defined(_WIN32) && !defined(EVENT__HAVE_AFUNIX_H)
3123
#define LOCAL_SOCKETPAIR_AF AF_INET
3124
#else
3125
0
#define LOCAL_SOCKETPAIR_AF AF_UNIX
3126
0
#endif
3127
0
  if (evutil_socketpair(LOCAL_SOCKETPAIR_AF, SOCK_STREAM|EVUTIL_SOCK_CLOEXEC|EVUTIL_SOCK_NONBLOCK, 0, fd)) {
3128
0
    fd[0] = fd[1] = -1;
3129
0
    return -1;
3130
0
  }
3131
0
  return 0;
3132
0
}
3133
3134
/* Wrapper around eventfd on systems that provide it.  Unlike the system
3135
 * eventfd, it always supports EVUTIL_EFD_CLOEXEC and EVUTIL_EFD_NONBLOCK as
3136
 * flags.  Returns -1 on error or if eventfd is not supported.
3137
 */
3138
evutil_socket_t
3139
evutil_eventfd_(unsigned initval, int flags)
3140
0
{
3141
0
#if defined(EVENT__HAVE_EVENTFD) && defined(EVENT__HAVE_SYS_EVENTFD_H)
3142
0
  int r;
3143
0
#if defined(EFD_CLOEXEC) && defined(EFD_NONBLOCK)
3144
0
  r = eventfd(initval, flags);
3145
0
  if (r >= 0 || flags == 0)
3146
0
    return r;
3147
0
#endif
3148
0
  r = eventfd(initval, 0);
3149
0
  if (r < 0)
3150
0
    return r;
3151
0
  if (flags & EVUTIL_EFD_CLOEXEC) {
3152
0
    if (evutil_fast_socket_closeonexec(r) < 0) {
3153
0
      evutil_closesocket(r);
3154
0
      return -1;
3155
0
    }
3156
0
  }
3157
0
  if (flags & EVUTIL_EFD_NONBLOCK) {
3158
0
    if (evutil_fast_socket_nonblocking(r) < 0) {
3159
0
      evutil_closesocket(r);
3160
0
      return -1;
3161
0
    }
3162
0
  }
3163
0
  return r;
3164
#else
3165
  return -1;
3166
#endif
3167
0
}
3168
3169
void
3170
evutil_free_globals_(void)
3171
0
{
3172
0
  evutil_free_secure_rng_globals_();
3173
0
  evutil_free_sock_err_globals();
3174
0
}
3175
3176
#if (defined(EVENT__SOLARIS_11_4) && !EVENT__SOLARIS_11_4) || \
3177
    (defined(__DragonFly__) && __DragonFly_version < 500702) || \
3178
    (defined(_WIN32) && !defined(TCP_KEEPIDLE))
3179
/* DragonFlyBSD <500702, Solaris <11.4, and Windows <10.0.16299
3180
 * require millisecond units for TCP keepalive options. */
3181
#define EVENT_KEEPALIVE_FACTOR(x) (x *= 1000)
3182
#else
3183
#define EVENT_KEEPALIVE_FACTOR(x)
3184
#endif
3185
int
3186
evutil_set_tcp_keepalive(evutil_socket_t fd, int on, int timeout)
3187
0
{
3188
0
  int idle;
3189
0
  int intvl;
3190
0
  int cnt;
3191
3192
  /* Prevent compiler from complaining unused variables warnings. */
3193
0
  (void) idle;
3194
0
  (void) intvl;
3195
0
  (void) cnt;
3196
3197
0
  if (timeout <= 0)
3198
0
    return 0;
3199
3200
#ifdef _WIN32
3201
  if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const char*)&on, sizeof(on)))
3202
#else
3203
0
  if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
3204
0
#endif
3205
0
    return -1;
3206
0
  if (!on)
3207
0
    return 0;
3208
3209
#ifdef _WIN32
3210
  idle = timeout;
3211
  intvl = idle/3;
3212
  if (intvl == 0)
3213
    intvl = 1;
3214
3215
  EVENT_KEEPALIVE_FACTOR(idle);
3216
  EVENT_KEEPALIVE_FACTOR(intvl);
3217
3218
  /* The three options TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT are not available until
3219
   * Windows 10 version 1709, but let's gamble here.
3220
   */
3221
#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT)
3222
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, (const char*)&idle, sizeof(idle)))
3223
    return -1;
3224
3225
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, (const char*)&intvl, sizeof(intvl)))
3226
    return -1;
3227
3228
  cnt = 3;
3229
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, (const char*)&cnt, sizeof(cnt)))
3230
    return -1;
3231
3232
  /* For those versions prior to Windows 10 version 1709, we fall back to SIO_KEEPALIVE_VALS.
3233
   * The SIO_KEEPALIVE_VALS IOCTL is supported on Windows 2000 and later versions of the operating system. */
3234
#elif defined(SIO_KEEPALIVE_VALS)
3235
  struct tcp_keepalive keepalive;
3236
  keepalive.onoff = on;
3237
  keepalive.keepalivetime = idle;
3238
  keepalive.keepaliveinterval = intvl;
3239
  /* On Windows Vista and later, the number of keep-alive probes (data retransmissions)
3240
   * is set to 10 and cannot be changed.
3241
   * On Windows Server 2003, Windows XP, and Windows 2000, the default setting for
3242
   * number of keep-alive probes is 5 and cannot be changed programmatically.
3243
   */
3244
  DWORD dummy;
3245
  if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, (LPVOID) &keepalive, sizeof(keepalive), NULL, 0, &dummy, NULL, NULL))
3246
    return -1;
3247
#endif
3248
3249
#else /* !_WIN32 */
3250
3251
#ifdef __sun
3252
  /* The implementation of TCP keep-alive on Solaris/SmartOS is a bit unusual
3253
   * compared to other Unix-like systems.
3254
   * Thus, we need to specialize it on Solaris.
3255
   *
3256
   * There are two keep-alive mechanisms on Solaris:
3257
   * - By default, the first keep-alive probe is sent out after a TCP connection is idle for two hours.
3258
   * If the peer does not respond to the probe within eight minutes, the TCP connection is aborted.
3259
   * You can alter the interval for sending out the first probe using the socket option TCP_KEEPALIVE_THRESHOLD
3260
   * in milliseconds or TCP_KEEPIDLE in seconds.
3261
   * The system default is controlled by the TCP ndd parameter tcp_keepalive_interval. The minimum value is ten seconds.
3262
   * The maximum is ten days, while the default is two hours. If you receive no response to the probe,
3263
   * you can use the TCP_KEEPALIVE_ABORT_THRESHOLD socket option to change the time threshold for aborting a TCP connection.
3264
   * The option value is an unsigned integer in milliseconds. The value zero indicates that TCP should never time out and
3265
   * abort the connection when probing. The system default is controlled by the TCP ndd parameter tcp_keepalive_abort_interval.
3266
   * The default is eight minutes.
3267
   *
3268
   * - The second implementation is activated if socket option TCP_KEEPINTVL and/or TCP_KEEPCNT are set.
3269
   * The time between each consequent probes is set by TCP_KEEPINTVL in seconds.
3270
   * The minimum value is ten seconds. The maximum is ten days, while the default is two hours.
3271
   * The TCP connection will be aborted after certain amount of probes, which is set by TCP_KEEPCNT, without receiving response.
3272
   */
3273
3274
  idle = timeout;
3275
  /* Kernel expects at least 10 seconds. */
3276
  if (idle < 10)
3277
    idle = 10;
3278
  /* Kernel expects at most 10 days. */
3279
  if (idle > 10*24*60*60)
3280
    idle = 10*24*60*60;
3281
3282
  EVENT_KEEPALIVE_FACTOR(idle);
3283
3284
  /* `TCP_KEEPIDLE`, `TCP_KEEPINTVL`, and `TCP_KEEPCNT` were not available on Solaris
3285
   * until version 11.4, but let's gamble here.
3286
   */
3287
#if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT)
3288
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)))
3289
    return -1;
3290
3291
  intvl = idle/3;
3292
  /* Kernel expects at least 10 seconds. */
3293
  if (intvl < 10)
3294
    intvl = 10;
3295
  EVENT_KEEPALIVE_FACTOR(intvl);
3296
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
3297
    return -1;
3298
3299
  cnt = 3;
3300
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
3301
    return -1;
3302
#else
3303
  /* Fall back to the first implementation of tcp-alive mechanism for older Solaris,
3304
   * simulate the tcp-alive mechanism on other platforms via `TCP_KEEPALIVE_THRESHOLD` + `TCP_KEEPALIVE_ABORT_THRESHOLD`.
3305
   */
3306
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, &idle, sizeof(idle)))
3307
    return -1;
3308
3309
  /* Note that the consequent probes will not be sent at equal intervals on Solaris,
3310
   * but will be sent using the exponential backoff algorithm.
3311
   */
3312
  int time_to_abort = idle;
3313
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, &time_to_abort, sizeof(time_to_abort)))
3314
    return -1;
3315
#endif
3316
3317
#else /* !__sun */
3318
3319
0
  idle = timeout;
3320
0
  EVENT_KEEPALIVE_FACTOR(idle);
3321
0
#ifdef TCP_KEEPIDLE
3322
0
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)))
3323
0
    return -1;
3324
#elif defined(TCP_KEEPALIVE)
3325
  /* Darwin/macOS uses TCP_KEEPALIVE in place of TCP_KEEPIDLE. */
3326
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &idle, sizeof(idle)))
3327
    return -1;
3328
#endif
3329
3330
0
#ifdef TCP_KEEPINTVL
3331
  /* Set the interval between individual keep-alive probes as timeout / 3
3332
   * and the maximum number of keepalive probes as 3 to make it double timeout
3333
   * before aborting a dead connection.
3334
   */
3335
0
  intvl = timeout/3;
3336
0
  if (intvl == 0)
3337
0
    intvl = 1;
3338
0
  EVENT_KEEPALIVE_FACTOR(intvl);
3339
0
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
3340
0
    return -1;
3341
0
#endif
3342
3343
0
#ifdef TCP_KEEPCNT
3344
  /* Set the maximum number of keepalive probes as 3 to collaborate with
3345
   * TCP_KEEPINTVL, see the previous comment.
3346
   */
3347
0
  cnt = 3;
3348
0
  if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
3349
0
    return -1;
3350
0
#endif
3351
3352
0
#endif /* !__sun */
3353
3354
0
#endif /* !_WIN32 */
3355
3356
0
  return 0;
3357
0
}
3358
3359
const char * evutil_strsignal(int sig)
3360
0
{
3361
#if !defined(EVENT__HAVE_STRSIGNAL)
3362
  static char buf[10];
3363
  evutil_snprintf(buf, 10, "%d", sig);
3364
  return buf;
3365
#else
3366
0
  return strsignal(sig);
3367
0
#endif
3368
0
}