Coverage Report

Created: 2025-06-10 13:21

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