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