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