evutil.c revision 1.1.1.3 1 1.1 plunky /* $NetBSD: evutil.c,v 1.1.1.3 2015/01/29 06:38:06 spz Exp $ */
2 1.1 plunky /*
3 1.1.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.1.1.2 christos
28 1.1.1.2 christos #include "event2/event-config.h"
29 1.1.1.2 christos #include <sys/cdefs.h>
30 1.1.1.2 christos __RCSID("$NetBSD: evutil.c,v 1.1.1.3 2015/01/29 06:38:06 spz Exp $");
31 1.1.1.2 christos
32 1.1.1.2 christos #define _GNU_SOURCE
33 1.1 plunky
34 1.1 plunky #ifdef WIN32
35 1.1 plunky #include <winsock2.h>
36 1.1.1.2 christos #include <ws2tcpip.h>
37 1.1 plunky #define WIN32_LEAN_AND_MEAN
38 1.1 plunky #include <windows.h>
39 1.1 plunky #undef WIN32_LEAN_AND_MEAN
40 1.1.1.2 christos #include <io.h>
41 1.1.1.2 christos #include <tchar.h>
42 1.1 plunky #endif
43 1.1 plunky
44 1.1 plunky #include <sys/types.h>
45 1.1.1.2 christos #ifdef _EVENT_HAVE_SYS_SOCKET_H
46 1.1 plunky #include <sys/socket.h>
47 1.1 plunky #endif
48 1.1.1.2 christos #ifdef _EVENT_HAVE_UNISTD_H
49 1.1 plunky #include <unistd.h>
50 1.1 plunky #endif
51 1.1.1.2 christos #ifdef _EVENT_HAVE_FCNTL_H
52 1.1 plunky #include <fcntl.h>
53 1.1 plunky #endif
54 1.1.1.2 christos #ifdef _EVENT_HAVE_STDLIB_H
55 1.1 plunky #include <stdlib.h>
56 1.1 plunky #endif
57 1.1 plunky #include <errno.h>
58 1.1.1.2 christos #include <limits.h>
59 1.1.1.2 christos #include <stdio.h>
60 1.1.1.2 christos #include <string.h>
61 1.1.1.2 christos #ifdef _EVENT_HAVE_NETINET_IN_H
62 1.1.1.2 christos #include <netinet/in.h>
63 1.1.1.2 christos #endif
64 1.1.1.2 christos #ifdef _EVENT_HAVE_NETINET_IN6_H
65 1.1.1.2 christos #include <netinet/in6.h>
66 1.1.1.2 christos #endif
67 1.1.1.2 christos #ifdef _EVENT_HAVE_ARPA_INET_H
68 1.1.1.2 christos #include <arpa/inet.h>
69 1.1.1.2 christos #endif
70 1.1.1.2 christos
71 1.1.1.2 christos #ifndef _EVENT_HAVE_GETTIMEOFDAY
72 1.1 plunky #include <sys/timeb.h>
73 1.1.1.2 christos #include <time.h>
74 1.1 plunky #endif
75 1.1.1.2 christos #include <sys/stat.h>
76 1.1.1.2 christos
77 1.1.1.2 christos #include "event2/util.h"
78 1.1.1.2 christos #include "util-internal.h"
79 1.1.1.2 christos #include "log-internal.h"
80 1.1.1.2 christos #include "mm-internal.h"
81 1.1.1.2 christos
82 1.1.1.2 christos #include "strlcpy-internal.h"
83 1.1.1.2 christos #include "ipv6-internal.h"
84 1.1 plunky
85 1.1.1.2 christos #ifdef WIN32
86 1.1.1.2 christos #define open _open
87 1.1.1.2 christos #define read _read
88 1.1.1.2 christos #define close _close
89 1.1.1.2 christos #define fstat _fstati64
90 1.1.1.2 christos #define stat _stati64
91 1.1.1.2 christos #define mode_t int
92 1.1.1.2 christos #endif
93 1.1 plunky
94 1.1 plunky int
95 1.1.1.2 christos evutil_open_closeonexec(const char *pathname, int flags, unsigned mode)
96 1.1.1.2 christos {
97 1.1.1.2 christos int fd;
98 1.1.1.2 christos
99 1.1.1.2 christos #ifdef O_CLOEXEC
100 1.1.1.2 christos flags |= O_CLOEXEC;
101 1.1.1.2 christos #endif
102 1.1.1.2 christos
103 1.1.1.2 christos if (flags & O_CREAT)
104 1.1.1.2 christos fd = open(pathname, flags, (mode_t)mode);
105 1.1.1.2 christos else
106 1.1.1.2 christos fd = open(pathname, flags);
107 1.1.1.2 christos if (fd < 0)
108 1.1.1.2 christos return -1;
109 1.1.1.2 christos
110 1.1.1.2 christos #if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
111 1.1.1.2 christos if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0)
112 1.1.1.2 christos return -1;
113 1.1.1.2 christos #endif
114 1.1.1.2 christos
115 1.1.1.2 christos return fd;
116 1.1.1.2 christos }
117 1.1.1.2 christos
118 1.1.1.2 christos /**
119 1.1.1.2 christos Read the contents of 'filename' into a newly allocated NUL-terminated
120 1.1.1.2 christos string. Set *content_out to hold this string, and *len_out to hold its
121 1.1.1.2 christos length (not including the appended NUL). If 'is_binary', open the file in
122 1.1.1.2 christos binary mode.
123 1.1.1.2 christos
124 1.1.1.2 christos Returns 0 on success, -1 if the open fails, and -2 for all other failures.
125 1.1.1.2 christos
126 1.1.1.2 christos Used internally only; may go away in a future version.
127 1.1.1.2 christos */
128 1.1.1.2 christos int
129 1.1.1.2 christos evutil_read_file(const char *filename, char **content_out, size_t *len_out,
130 1.1.1.2 christos int is_binary)
131 1.1.1.2 christos {
132 1.1.1.2 christos int fd, r;
133 1.1.1.2 christos struct stat st;
134 1.1.1.2 christos char *mem;
135 1.1.1.2 christos size_t read_so_far=0;
136 1.1.1.2 christos int mode = O_RDONLY;
137 1.1.1.2 christos
138 1.1.1.2 christos EVUTIL_ASSERT(content_out);
139 1.1.1.2 christos EVUTIL_ASSERT(len_out);
140 1.1.1.2 christos *content_out = NULL;
141 1.1.1.2 christos *len_out = 0;
142 1.1.1.2 christos
143 1.1.1.2 christos #ifdef O_BINARY
144 1.1.1.2 christos if (is_binary)
145 1.1.1.2 christos mode |= O_BINARY;
146 1.1.1.2 christos #endif
147 1.1.1.2 christos
148 1.1.1.2 christos fd = evutil_open_closeonexec(filename, mode, 0);
149 1.1.1.2 christos if (fd < 0)
150 1.1.1.2 christos return -1;
151 1.1.1.2 christos if (fstat(fd, &st) || st.st_size < 0 ||
152 1.1.1.2 christos st.st_size > EV_SSIZE_MAX-1 ) {
153 1.1.1.2 christos close(fd);
154 1.1.1.2 christos return -2;
155 1.1.1.2 christos }
156 1.1.1.2 christos mem = mm_malloc((size_t)st.st_size + 1);
157 1.1.1.2 christos if (!mem) {
158 1.1.1.2 christos close(fd);
159 1.1.1.2 christos return -2;
160 1.1.1.2 christos }
161 1.1.1.2 christos read_so_far = 0;
162 1.1.1.2 christos #ifdef WIN32
163 1.1.1.2 christos #define N_TO_READ(x) ((x) > INT_MAX) ? INT_MAX : ((int)(x))
164 1.1.1.2 christos #else
165 1.1.1.2 christos #define N_TO_READ(x) (x)
166 1.1.1.2 christos #endif
167 1.1.1.2 christos while ((r = read(fd, mem+read_so_far, N_TO_READ(st.st_size - read_so_far))) > 0) {
168 1.1.1.2 christos read_so_far += r;
169 1.1.1.2 christos if (read_so_far >= (size_t)st.st_size)
170 1.1.1.2 christos break;
171 1.1.1.2 christos EVUTIL_ASSERT(read_so_far < (size_t)st.st_size);
172 1.1.1.2 christos }
173 1.1.1.2 christos close(fd);
174 1.1.1.2 christos if (r < 0) {
175 1.1.1.2 christos mm_free(mem);
176 1.1.1.2 christos return -2;
177 1.1.1.2 christos }
178 1.1.1.2 christos mem[read_so_far] = 0;
179 1.1.1.2 christos
180 1.1.1.2 christos *len_out = read_so_far;
181 1.1.1.2 christos *content_out = mem;
182 1.1.1.2 christos return 0;
183 1.1.1.2 christos }
184 1.1.1.2 christos
185 1.1.1.2 christos int
186 1.1.1.2 christos evutil_socketpair(int family, int type, int protocol, evutil_socket_t fd[2])
187 1.1 plunky {
188 1.1 plunky #ifndef WIN32
189 1.1 plunky return socketpair(family, type, protocol, fd);
190 1.1 plunky #else
191 1.1.1.2 christos return evutil_ersatz_socketpair(family, type, protocol, fd);
192 1.1.1.2 christos #endif
193 1.1.1.2 christos }
194 1.1.1.2 christos
195 1.1.1.2 christos int
196 1.1.1.2 christos evutil_ersatz_socketpair(int family, int type, int protocol,
197 1.1.1.2 christos evutil_socket_t fd[2])
198 1.1.1.2 christos {
199 1.1 plunky /* This code is originally from Tor. Used with permission. */
200 1.1 plunky
201 1.1 plunky /* This socketpair does not work when localhost is down. So
202 1.1 plunky * it's really not the same thing at all. But it's close enough
203 1.1 plunky * for now, and really, when localhost is down sometimes, we
204 1.1 plunky * have other problems too.
205 1.1 plunky */
206 1.1.1.2 christos #ifdef WIN32
207 1.1.1.2 christos #define ERR(e) WSA##e
208 1.1.1.2 christos #else
209 1.1.1.2 christos #define ERR(e) e
210 1.1.1.2 christos #endif
211 1.1.1.2 christos evutil_socket_t listener = -1;
212 1.1.1.2 christos evutil_socket_t connector = -1;
213 1.1.1.2 christos evutil_socket_t acceptor = -1;
214 1.1 plunky struct sockaddr_in listen_addr;
215 1.1 plunky struct sockaddr_in connect_addr;
216 1.1.1.2 christos ev_socklen_t size;
217 1.1 plunky int saved_errno = -1;
218 1.1 plunky
219 1.1 plunky if (protocol
220 1.1.1.2 christos || (family != AF_INET
221 1.1 plunky #ifdef AF_UNIX
222 1.1.1.2 christos && family != AF_UNIX
223 1.1 plunky #endif
224 1.1.1.2 christos )) {
225 1.1.1.2 christos EVUTIL_SET_SOCKET_ERROR(ERR(EAFNOSUPPORT));
226 1.1 plunky return -1;
227 1.1 plunky }
228 1.1 plunky if (!fd) {
229 1.1.1.2 christos EVUTIL_SET_SOCKET_ERROR(ERR(EINVAL));
230 1.1 plunky return -1;
231 1.1 plunky }
232 1.1 plunky
233 1.1 plunky listener = socket(AF_INET, type, 0);
234 1.1 plunky if (listener < 0)
235 1.1 plunky return -1;
236 1.1 plunky memset(&listen_addr, 0, sizeof(listen_addr));
237 1.1 plunky listen_addr.sin_family = AF_INET;
238 1.1 plunky listen_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
239 1.1 plunky listen_addr.sin_port = 0; /* kernel chooses port. */
240 1.1 plunky if (bind(listener, (struct sockaddr *) &listen_addr, sizeof (listen_addr))
241 1.1 plunky == -1)
242 1.1 plunky goto tidy_up_and_fail;
243 1.1 plunky if (listen(listener, 1) == -1)
244 1.1 plunky goto tidy_up_and_fail;
245 1.1 plunky
246 1.1 plunky connector = socket(AF_INET, type, 0);
247 1.1 plunky if (connector < 0)
248 1.1 plunky goto tidy_up_and_fail;
249 1.1 plunky /* We want to find out the port number to connect to. */
250 1.1 plunky size = sizeof(connect_addr);
251 1.1 plunky if (getsockname(listener, (struct sockaddr *) &connect_addr, &size) == -1)
252 1.1 plunky goto tidy_up_and_fail;
253 1.1 plunky if (size != sizeof (connect_addr))
254 1.1 plunky goto abort_tidy_up_and_fail;
255 1.1 plunky if (connect(connector, (struct sockaddr *) &connect_addr,
256 1.1 plunky sizeof(connect_addr)) == -1)
257 1.1 plunky goto tidy_up_and_fail;
258 1.1 plunky
259 1.1 plunky size = sizeof(listen_addr);
260 1.1 plunky acceptor = accept(listener, (struct sockaddr *) &listen_addr, &size);
261 1.1 plunky if (acceptor < 0)
262 1.1 plunky goto tidy_up_and_fail;
263 1.1 plunky if (size != sizeof(listen_addr))
264 1.1 plunky goto abort_tidy_up_and_fail;
265 1.1 plunky /* Now check we are talking to ourself by matching port and host on the
266 1.1 plunky two sockets. */
267 1.1 plunky if (getsockname(connector, (struct sockaddr *) &connect_addr, &size) == -1)
268 1.1 plunky goto tidy_up_and_fail;
269 1.1 plunky if (size != sizeof (connect_addr)
270 1.1 plunky || listen_addr.sin_family != connect_addr.sin_family
271 1.1 plunky || listen_addr.sin_addr.s_addr != connect_addr.sin_addr.s_addr
272 1.1 plunky || listen_addr.sin_port != connect_addr.sin_port)
273 1.1 plunky goto abort_tidy_up_and_fail;
274 1.1.1.3 spz evutil_closesocket(listener);
275 1.1 plunky fd[0] = connector;
276 1.1 plunky fd[1] = acceptor;
277 1.1 plunky
278 1.1 plunky return 0;
279 1.1 plunky
280 1.1 plunky abort_tidy_up_and_fail:
281 1.1.1.2 christos saved_errno = ERR(ECONNABORTED);
282 1.1 plunky tidy_up_and_fail:
283 1.1 plunky if (saved_errno < 0)
284 1.1.1.2 christos saved_errno = EVUTIL_SOCKET_ERROR();
285 1.1 plunky if (listener != -1)
286 1.1.1.2 christos evutil_closesocket(listener);
287 1.1 plunky if (connector != -1)
288 1.1.1.2 christos evutil_closesocket(connector);
289 1.1 plunky if (acceptor != -1)
290 1.1.1.2 christos evutil_closesocket(acceptor);
291 1.1 plunky
292 1.1 plunky EVUTIL_SET_SOCKET_ERROR(saved_errno);
293 1.1 plunky return -1;
294 1.1.1.2 christos #undef ERR
295 1.1 plunky }
296 1.1 plunky
297 1.1 plunky int
298 1.1.1.2 christos evutil_make_socket_nonblocking(evutil_socket_t fd)
299 1.1 plunky {
300 1.1 plunky #ifdef WIN32
301 1.1 plunky {
302 1.1.1.2 christos u_long nonblocking = 1;
303 1.1.1.2 christos if (ioctlsocket(fd, FIONBIO, &nonblocking) == SOCKET_ERROR) {
304 1.1.1.2 christos event_sock_warn(fd, "fcntl(%d, F_GETFL)", (int)fd);
305 1.1.1.2 christos return -1;
306 1.1.1.2 christos }
307 1.1 plunky }
308 1.1 plunky #else
309 1.1.1.2 christos {
310 1.1.1.2 christos int flags;
311 1.1.1.2 christos if ((flags = fcntl(fd, F_GETFL, NULL)) < 0) {
312 1.1.1.2 christos event_warn("fcntl(%d, F_GETFL)", fd);
313 1.1.1.2 christos return -1;
314 1.1.1.2 christos }
315 1.1.1.2 christos if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
316 1.1.1.2 christos event_warn("fcntl(%d, F_SETFL)", fd);
317 1.1.1.2 christos return -1;
318 1.1.1.2 christos }
319 1.1.1.2 christos }
320 1.1.1.2 christos #endif
321 1.1.1.2 christos return 0;
322 1.1.1.2 christos }
323 1.1.1.2 christos
324 1.1.1.2 christos int
325 1.1.1.2 christos evutil_make_listen_socket_reuseable(evutil_socket_t sock)
326 1.1.1.2 christos {
327 1.1.1.2 christos #ifndef WIN32
328 1.1.1.2 christos int one = 1;
329 1.1.1.2 christos /* REUSEADDR on Unix means, "don't hang on to this address after the
330 1.1.1.2 christos * listener is closed." On Windows, though, it means "don't keep other
331 1.1.1.2 christos * processes from binding to this address while we're using it. */
332 1.1.1.2 christos return setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &one,
333 1.1.1.2 christos (ev_socklen_t)sizeof(one));
334 1.1.1.2 christos #else
335 1.1.1.2 christos return 0;
336 1.1.1.2 christos #endif
337 1.1.1.2 christos }
338 1.1.1.2 christos
339 1.1.1.2 christos int
340 1.1.1.2 christos evutil_make_socket_closeonexec(evutil_socket_t fd)
341 1.1.1.2 christos {
342 1.1.1.2 christos #if !defined(WIN32) && defined(_EVENT_HAVE_SETFD)
343 1.1.1.2 christos int flags;
344 1.1.1.2 christos if ((flags = fcntl(fd, F_GETFD, NULL)) < 0) {
345 1.1.1.2 christos event_warn("fcntl(%d, F_GETFD)", fd);
346 1.1 plunky return -1;
347 1.1.1.2 christos }
348 1.1.1.2 christos if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
349 1.1.1.2 christos event_warn("fcntl(%d, F_SETFD)", fd);
350 1.1.1.2 christos return -1;
351 1.1.1.2 christos }
352 1.1 plunky #endif
353 1.1 plunky return 0;
354 1.1 plunky }
355 1.1 plunky
356 1.1.1.2 christos int
357 1.1.1.2 christos evutil_closesocket(evutil_socket_t sock)
358 1.1.1.2 christos {
359 1.1.1.2 christos #ifndef WIN32
360 1.1.1.2 christos return close(sock);
361 1.1.1.2 christos #else
362 1.1.1.2 christos return closesocket(sock);
363 1.1.1.2 christos #endif
364 1.1.1.2 christos }
365 1.1.1.2 christos
366 1.1 plunky ev_int64_t
367 1.1 plunky evutil_strtoll(const char *s, char **endptr, int base)
368 1.1 plunky {
369 1.1.1.2 christos #ifdef _EVENT_HAVE_STRTOLL
370 1.1 plunky return (ev_int64_t)strtoll(s, endptr, base);
371 1.1.1.2 christos #elif _EVENT_SIZEOF_LONG == 8
372 1.1 plunky return (ev_int64_t)strtol(s, endptr, base);
373 1.1 plunky #elif defined(WIN32) && defined(_MSC_VER) && _MSC_VER < 1300
374 1.1 plunky /* XXXX on old versions of MS APIs, we only support base
375 1.1 plunky * 10. */
376 1.1 plunky ev_int64_t r;
377 1.1 plunky if (base != 10)
378 1.1 plunky return 0;
379 1.1 plunky r = (ev_int64_t) _atoi64(s);
380 1.1 plunky while (isspace(*s))
381 1.1 plunky ++s;
382 1.1.1.2 christos if (*s == '-')
383 1.1.1.2 christos ++s;
384 1.1 plunky while (isdigit(*s))
385 1.1 plunky ++s;
386 1.1 plunky if (endptr)
387 1.1 plunky *endptr = (char*) s;
388 1.1 plunky return r;
389 1.1 plunky #elif defined(WIN32)
390 1.1 plunky return (ev_int64_t) _strtoi64(s, endptr, base);
391 1.1.1.2 christos #elif defined(_EVENT_SIZEOF_LONG_LONG) && _EVENT_SIZEOF_LONG_LONG == 8
392 1.1.1.2 christos long long r;
393 1.1.1.2 christos int n;
394 1.1.1.2 christos if (base != 10 && base != 16)
395 1.1.1.2 christos return 0;
396 1.1.1.2 christos if (base == 10) {
397 1.1.1.2 christos n = sscanf(s, "%lld", &r);
398 1.1.1.2 christos } else {
399 1.1.1.2 christos unsigned long long ru=0;
400 1.1.1.2 christos n = sscanf(s, "%llx", &ru);
401 1.1.1.2 christos if (ru > EV_INT64_MAX)
402 1.1.1.2 christos return 0;
403 1.1.1.2 christos r = (long long) ru;
404 1.1.1.2 christos }
405 1.1.1.2 christos if (n != 1)
406 1.1.1.2 christos return 0;
407 1.1.1.2 christos while (EVUTIL_ISSPACE(*s))
408 1.1.1.2 christos ++s;
409 1.1.1.2 christos if (*s == '-')
410 1.1.1.2 christos ++s;
411 1.1.1.2 christos if (base == 10) {
412 1.1.1.2 christos while (EVUTIL_ISDIGIT(*s))
413 1.1.1.2 christos ++s;
414 1.1.1.2 christos } else {
415 1.1.1.2 christos while (EVUTIL_ISXDIGIT(*s))
416 1.1.1.2 christos ++s;
417 1.1.1.2 christos }
418 1.1.1.2 christos if (endptr)
419 1.1.1.2 christos *endptr = (char*) s;
420 1.1.1.2 christos return r;
421 1.1 plunky #else
422 1.1 plunky #error "I don't know how to parse 64-bit integers."
423 1.1 plunky #endif
424 1.1 plunky }
425 1.1 plunky
426 1.1 plunky #ifndef _EVENT_HAVE_GETTIMEOFDAY
427 1.1.1.2 christos /* No gettimeofday; this muse be windows. */
428 1.1 plunky int
429 1.1 plunky evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
430 1.1 plunky {
431 1.1 plunky struct _timeb tb;
432 1.1 plunky
433 1.1.1.2 christos if (tv == NULL)
434 1.1 plunky return -1;
435 1.1 plunky
436 1.1.1.2 christos /* XXXX
437 1.1.1.2 christos * _ftime is not the greatest interface here; GetSystemTimeAsFileTime
438 1.1.1.2 christos * would give us better resolution, whereas something cobbled together
439 1.1.1.2 christos * with GetTickCount could maybe give us monotonic behavior.
440 1.1.1.2 christos *
441 1.1.1.2 christos * Either way, I think this value might be skewed to ignore the
442 1.1.1.2 christos * timezone, and just return local time. That's not so good.
443 1.1.1.2 christos */
444 1.1 plunky _ftime(&tb);
445 1.1 plunky tv->tv_sec = (long) tb.time;
446 1.1 plunky tv->tv_usec = ((int) tb.millitm) * 1000;
447 1.1 plunky return 0;
448 1.1 plunky }
449 1.1 plunky #endif
450 1.1 plunky
451 1.1.1.2 christos #ifdef WIN32
452 1.1.1.2 christos int
453 1.1.1.2 christos evutil_socket_geterror(evutil_socket_t sock)
454 1.1.1.2 christos {
455 1.1.1.2 christos int optval, optvallen=sizeof(optval);
456 1.1.1.2 christos int err = WSAGetLastError();
457 1.1.1.2 christos if (err == WSAEWOULDBLOCK && sock >= 0) {
458 1.1.1.2 christos if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval,
459 1.1.1.2 christos &optvallen))
460 1.1.1.2 christos return err;
461 1.1.1.2 christos if (optval)
462 1.1.1.2 christos return optval;
463 1.1.1.2 christos }
464 1.1.1.2 christos return err;
465 1.1.1.2 christos }
466 1.1.1.2 christos #endif
467 1.1.1.2 christos
468 1.1.1.2 christos /* XXX we should use an enum here. */
469 1.1.1.2 christos /* 2 for connection refused, 1 for connected, 0 for not yet, -1 for error. */
470 1.1.1.2 christos int
471 1.1.1.2 christos evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen)
472 1.1.1.2 christos {
473 1.1.1.2 christos int made_fd = 0;
474 1.1.1.2 christos
475 1.1.1.2 christos if (*fd_ptr < 0) {
476 1.1.1.2 christos if ((*fd_ptr = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
477 1.1.1.2 christos goto err;
478 1.1.1.2 christos made_fd = 1;
479 1.1.1.2 christos if (evutil_make_socket_nonblocking(*fd_ptr) < 0) {
480 1.1.1.2 christos goto err;
481 1.1.1.2 christos }
482 1.1.1.2 christos }
483 1.1.1.2 christos
484 1.1.1.2 christos if (connect(*fd_ptr, sa, socklen) < 0) {
485 1.1.1.2 christos int e = evutil_socket_geterror(*fd_ptr);
486 1.1.1.2 christos if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
487 1.1.1.2 christos return 0;
488 1.1.1.2 christos if (EVUTIL_ERR_CONNECT_REFUSED(e))
489 1.1.1.2 christos return 2;
490 1.1.1.2 christos goto err;
491 1.1.1.2 christos } else {
492 1.1.1.2 christos return 1;
493 1.1.1.2 christos }
494 1.1.1.2 christos
495 1.1.1.2 christos err:
496 1.1.1.2 christos if (made_fd) {
497 1.1.1.2 christos evutil_closesocket(*fd_ptr);
498 1.1.1.2 christos *fd_ptr = -1;
499 1.1.1.2 christos }
500 1.1.1.2 christos return -1;
501 1.1.1.2 christos }
502 1.1.1.2 christos
503 1.1.1.2 christos /* Check whether a socket on which we called connect() is done
504 1.1.1.2 christos connecting. Return 1 for connected, 0 for not yet, -1 for error. In the
505 1.1.1.2 christos error case, set the current socket errno to the error that happened during
506 1.1.1.2 christos the connect operation. */
507 1.1.1.2 christos int
508 1.1.1.2 christos evutil_socket_finished_connecting(evutil_socket_t fd)
509 1.1.1.2 christos {
510 1.1.1.2 christos int e;
511 1.1.1.2 christos ev_socklen_t elen = sizeof(e);
512 1.1.1.2 christos
513 1.1.1.2 christos if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
514 1.1.1.2 christos return -1;
515 1.1.1.2 christos
516 1.1.1.2 christos if (e) {
517 1.1.1.2 christos if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
518 1.1.1.2 christos return 0;
519 1.1.1.2 christos EVUTIL_SET_SOCKET_ERROR(e);
520 1.1.1.2 christos return -1;
521 1.1.1.2 christos }
522 1.1.1.2 christos
523 1.1.1.2 christos return 1;
524 1.1.1.2 christos }
525 1.1.1.2 christos
526 1.1.1.2 christos #if (EVUTIL_AI_PASSIVE|EVUTIL_AI_CANONNAME|EVUTIL_AI_NUMERICHOST| \
527 1.1.1.2 christos EVUTIL_AI_NUMERICSERV|EVUTIL_AI_V4MAPPED|EVUTIL_AI_ALL| \
528 1.1.1.2 christos EVUTIL_AI_ADDRCONFIG) != \
529 1.1.1.2 christos (EVUTIL_AI_PASSIVE^EVUTIL_AI_CANONNAME^EVUTIL_AI_NUMERICHOST^ \
530 1.1.1.2 christos EVUTIL_AI_NUMERICSERV^EVUTIL_AI_V4MAPPED^EVUTIL_AI_ALL^ \
531 1.1.1.2 christos EVUTIL_AI_ADDRCONFIG)
532 1.1.1.2 christos #error "Some of our EVUTIL_AI_* flags seem to overlap with system AI_* flags"
533 1.1.1.2 christos #endif
534 1.1.1.2 christos
535 1.1.1.2 christos /* We sometimes need to know whether we have an ipv4 address and whether we
536 1.1.1.2 christos have an ipv6 address. If 'have_checked_interfaces', then we've already done
537 1.1.1.2 christos the test. If 'had_ipv4_address', then it turns out we had an ipv4 address.
538 1.1.1.2 christos If 'had_ipv6_address', then it turns out we had an ipv6 address. These are
539 1.1.1.2 christos set by evutil_check_interfaces. */
540 1.1.1.2 christos static int have_checked_interfaces, had_ipv4_address, had_ipv6_address;
541 1.1.1.2 christos
542 1.1.1.2 christos /* Macro: True iff the IPv4 address 'addr', in host order, is in 127.0.0.0/8
543 1.1.1.2 christos */
544 1.1.1.2 christos #define EVUTIL_V4ADDR_IS_LOCALHOST(addr) (((addr)>>24) == 127)
545 1.1.1.2 christos
546 1.1.1.2 christos /* Macro: True iff the IPv4 address 'addr', in host order, is a class D
547 1.1.1.2 christos * (multiclass) address.
548 1.1.1.2 christos */
549 1.1.1.2 christos #define EVUTIL_V4ADDR_IS_CLASSD(addr) ((((addr)>>24) & 0xf0) == 0xe0)
550 1.1.1.2 christos
551 1.1.1.2 christos /* Test whether we have an ipv4 interface and an ipv6 interface. Return 0 if
552 1.1.1.2 christos * the test seemed successful. */
553 1.1.1.2 christos static int
554 1.1.1.2 christos evutil_check_interfaces(int force_recheck)
555 1.1.1.2 christos {
556 1.1.1.2 christos const char ZEROES[] = "\x00\x00\x00\x00\x00\x00\x00\x00"
557 1.1.1.2 christos "\x00\x00\x00\x00\x00\x00\x00\x00";
558 1.1.1.2 christos evutil_socket_t fd = -1;
559 1.1.1.2 christos struct sockaddr_in sin, sin_out;
560 1.1.1.2 christos struct sockaddr_in6 sin6, sin6_out;
561 1.1.1.2 christos ev_socklen_t sin_out_len = sizeof(sin_out);
562 1.1.1.2 christos ev_socklen_t sin6_out_len = sizeof(sin6_out);
563 1.1.1.2 christos int r;
564 1.1.1.2 christos char buf[128];
565 1.1.1.2 christos if (have_checked_interfaces && !force_recheck)
566 1.1.1.2 christos return 0;
567 1.1.1.2 christos
568 1.1.1.2 christos /* To check whether we have an interface open for a given protocol, we
569 1.1.1.2 christos * try to make a UDP 'connection' to a remote host on the internet.
570 1.1.1.2 christos * We don't actually use it, so the address doesn't matter, but we
571 1.1.1.2 christos * want to pick one that keep us from using a host- or link-local
572 1.1.1.2 christos * interface. */
573 1.1.1.2 christos memset(&sin, 0, sizeof(sin));
574 1.1.1.2 christos sin.sin_family = AF_INET;
575 1.1.1.2 christos sin.sin_port = htons(53);
576 1.1.1.2 christos r = evutil_inet_pton(AF_INET, "18.244.0.188", &sin.sin_addr);
577 1.1.1.2 christos EVUTIL_ASSERT(r);
578 1.1.1.2 christos
579 1.1.1.2 christos memset(&sin6, 0, sizeof(sin6));
580 1.1.1.2 christos sin6.sin6_family = AF_INET6;
581 1.1.1.2 christos sin6.sin6_port = htons(53);
582 1.1.1.2 christos r = evutil_inet_pton(AF_INET6, "2001:4860:b002::68", &sin6.sin6_addr);
583 1.1.1.2 christos EVUTIL_ASSERT(r);
584 1.1.1.2 christos
585 1.1.1.2 christos memset(&sin_out, 0, sizeof(sin_out));
586 1.1.1.2 christos memset(&sin6_out, 0, sizeof(sin6_out));
587 1.1.1.2 christos
588 1.1.1.2 christos /* XXX some errnos mean 'no address'; some mean 'not enough sockets'. */
589 1.1.1.2 christos if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
590 1.1.1.2 christos connect(fd, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
591 1.1.1.2 christos getsockname(fd, (struct sockaddr*)&sin_out, &sin_out_len) == 0) {
592 1.1.1.2 christos /* We might have an IPv4 interface. */
593 1.1.1.2 christos ev_uint32_t addr = ntohl(sin_out.sin_addr.s_addr);
594 1.1.1.2 christos if (addr == 0 ||
595 1.1.1.2 christos EVUTIL_V4ADDR_IS_LOCALHOST(addr) ||
596 1.1.1.2 christos EVUTIL_V4ADDR_IS_CLASSD(addr)) {
597 1.1.1.2 christos evutil_inet_ntop(AF_INET, &sin_out.sin_addr,
598 1.1.1.2 christos buf, sizeof(buf));
599 1.1.1.2 christos /* This is a reserved, ipv4compat, ipv4map, loopback,
600 1.1.1.2 christos * link-local or unspecified address. The host should
601 1.1.1.2 christos * never have given it to us; it could never connect
602 1.1.1.2 christos * to sin. */
603 1.1.1.2 christos event_warnx("Got a strange local ipv4 address %s",buf);
604 1.1.1.2 christos } else {
605 1.1.1.2 christos event_debug(("Detected an IPv4 interface"));
606 1.1.1.2 christos had_ipv4_address = 1;
607 1.1.1.2 christos }
608 1.1.1.2 christos }
609 1.1.1.2 christos if (fd >= 0)
610 1.1.1.2 christos evutil_closesocket(fd);
611 1.1.1.2 christos
612 1.1.1.2 christos if ((fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) >= 0 &&
613 1.1.1.2 christos connect(fd, (struct sockaddr*)&sin6, sizeof(sin6)) == 0 &&
614 1.1.1.2 christos getsockname(fd, (struct sockaddr*)&sin6_out, &sin6_out_len) == 0) {
615 1.1.1.2 christos /* We might have an IPv6 interface. */
616 1.1.1.2 christos const unsigned char *addr =
617 1.1.1.2 christos (unsigned char*)sin6_out.sin6_addr.s6_addr;
618 1.1.1.2 christos if (!memcmp(addr, ZEROES, 8) ||
619 1.1.1.2 christos (addr[0] == 0xfe && (addr[1] & 0xc0) == 0x80)) {
620 1.1.1.2 christos /* This is a reserved, ipv4compat, ipv4map, loopback,
621 1.1.1.2 christos * link-local or unspecified address. The host should
622 1.1.1.2 christos * never have given it to us; it could never connect
623 1.1.1.2 christos * to sin6. */
624 1.1.1.2 christos evutil_inet_ntop(AF_INET6, &sin6_out.sin6_addr,
625 1.1.1.2 christos buf, sizeof(buf));
626 1.1.1.2 christos event_warnx("Got a strange local ipv6 address %s",buf);
627 1.1.1.2 christos } else {
628 1.1.1.2 christos event_debug(("Detected an IPv4 interface"));
629 1.1.1.2 christos had_ipv6_address = 1;
630 1.1.1.2 christos }
631 1.1.1.2 christos }
632 1.1.1.2 christos
633 1.1.1.2 christos if (fd >= 0)
634 1.1.1.2 christos evutil_closesocket(fd);
635 1.1.1.2 christos
636 1.1.1.2 christos return 0;
637 1.1.1.2 christos }
638 1.1.1.2 christos
639 1.1.1.2 christos /* Internal addrinfo flag. This one is set when we allocate the addrinfo from
640 1.1.1.2 christos * inside libevent. Otherwise, the built-in getaddrinfo() function allocated
641 1.1.1.2 christos * it, and we should trust what they said.
642 1.1.1.2 christos **/
643 1.1.1.2 christos #define EVUTIL_AI_LIBEVENT_ALLOCATED 0x80000000
644 1.1.1.2 christos
645 1.1.1.2 christos /* Helper: construct a new addrinfo containing the socket address in
646 1.1.1.2 christos * 'sa', which must be a sockaddr_in or a sockaddr_in6. Take the
647 1.1.1.2 christos * socktype and protocol info from hints. If they weren't set, then
648 1.1.1.2 christos * allocate both a TCP and a UDP addrinfo.
649 1.1.1.2 christos */
650 1.1.1.2 christos struct evutil_addrinfo *
651 1.1.1.2 christos evutil_new_addrinfo(struct sockaddr *sa, ev_socklen_t socklen,
652 1.1.1.2 christos const struct evutil_addrinfo *hints)
653 1.1.1.2 christos {
654 1.1.1.2 christos struct evutil_addrinfo *res;
655 1.1.1.2 christos EVUTIL_ASSERT(hints);
656 1.1.1.2 christos
657 1.1.1.2 christos if (hints->ai_socktype == 0 && hints->ai_protocol == 0) {
658 1.1.1.2 christos /* Indecisive user! Give them a UDP and a TCP. */
659 1.1.1.2 christos struct evutil_addrinfo *r1, *r2;
660 1.1.1.2 christos struct evutil_addrinfo tmp;
661 1.1.1.2 christos memcpy(&tmp, hints, sizeof(tmp));
662 1.1.1.2 christos tmp.ai_socktype = SOCK_STREAM; tmp.ai_protocol = IPPROTO_TCP;
663 1.1.1.2 christos r1 = evutil_new_addrinfo(sa, socklen, &tmp);
664 1.1.1.2 christos if (!r1)
665 1.1.1.2 christos return NULL;
666 1.1.1.2 christos tmp.ai_socktype = SOCK_DGRAM; tmp.ai_protocol = IPPROTO_UDP;
667 1.1.1.2 christos r2 = evutil_new_addrinfo(sa, socklen, &tmp);
668 1.1.1.2 christos if (!r2) {
669 1.1.1.2 christos evutil_freeaddrinfo(r1);
670 1.1.1.2 christos return NULL;
671 1.1.1.2 christos }
672 1.1.1.2 christos r1->ai_next = r2;
673 1.1.1.2 christos return r1;
674 1.1.1.2 christos }
675 1.1.1.2 christos
676 1.1.1.2 christos /* We're going to allocate extra space to hold the sockaddr. */
677 1.1.1.2 christos res = mm_calloc(1,sizeof(struct evutil_addrinfo)+socklen);
678 1.1.1.2 christos if (!res)
679 1.1.1.2 christos return NULL;
680 1.1.1.2 christos res->ai_addr = (struct sockaddr*)
681 1.1.1.2 christos (((char*)res) + sizeof(struct evutil_addrinfo));
682 1.1.1.2 christos memcpy(res->ai_addr, sa, socklen);
683 1.1.1.2 christos res->ai_addrlen = socklen;
684 1.1.1.2 christos res->ai_family = sa->sa_family; /* Same or not? XXX */
685 1.1.1.2 christos res->ai_flags = EVUTIL_AI_LIBEVENT_ALLOCATED;
686 1.1.1.2 christos res->ai_socktype = hints->ai_socktype;
687 1.1.1.2 christos res->ai_protocol = hints->ai_protocol;
688 1.1.1.2 christos
689 1.1.1.2 christos return res;
690 1.1.1.2 christos }
691 1.1.1.2 christos
692 1.1.1.2 christos /* Append the addrinfo 'append' to the end of 'first', and return the start of
693 1.1.1.2 christos * the list. Either element can be NULL, in which case we return the element
694 1.1.1.2 christos * that is not NULL. */
695 1.1.1.2 christos struct evutil_addrinfo *
696 1.1.1.2 christos evutil_addrinfo_append(struct evutil_addrinfo *first,
697 1.1.1.2 christos struct evutil_addrinfo *append)
698 1.1.1.2 christos {
699 1.1.1.2 christos struct evutil_addrinfo *ai = first;
700 1.1.1.2 christos if (!ai)
701 1.1.1.2 christos return append;
702 1.1.1.2 christos while (ai->ai_next)
703 1.1.1.2 christos ai = ai->ai_next;
704 1.1.1.2 christos ai->ai_next = append;
705 1.1.1.2 christos
706 1.1.1.2 christos return first;
707 1.1.1.2 christos }
708 1.1.1.2 christos
709 1.1.1.2 christos static int
710 1.1.1.2 christos parse_numeric_servname(const char *servname)
711 1.1.1.2 christos {
712 1.1.1.2 christos int n;
713 1.1.1.2 christos char *endptr=NULL;
714 1.1.1.2 christos n = (int) strtol(servname, &endptr, 10);
715 1.1.1.2 christos if (n>=0 && n <= 65535 && servname[0] && endptr && !endptr[0])
716 1.1.1.2 christos return n;
717 1.1.1.2 christos else
718 1.1.1.2 christos return -1;
719 1.1.1.2 christos }
720 1.1.1.2 christos
721 1.1.1.2 christos /** Parse a service name in 'servname', which can be a decimal port.
722 1.1.1.2 christos * Return the port number, or -1 on error.
723 1.1.1.2 christos */
724 1.1.1.2 christos static int
725 1.1.1.2 christos evutil_parse_servname(const char *servname, const char *protocol,
726 1.1.1.2 christos const struct evutil_addrinfo *hints)
727 1.1.1.2 christos {
728 1.1.1.2 christos int n = parse_numeric_servname(servname);
729 1.1.1.2 christos if (n>=0)
730 1.1.1.2 christos return n;
731 1.1.1.2 christos #if defined(_EVENT_HAVE_GETSERVBYNAME) || defined(WIN32)
732 1.1.1.2 christos if (!(hints->ai_flags & EVUTIL_AI_NUMERICSERV)) {
733 1.1.1.2 christos struct servent *ent = getservbyname(servname, protocol);
734 1.1.1.2 christos if (ent) {
735 1.1.1.2 christos return ntohs(ent->s_port);
736 1.1.1.2 christos }
737 1.1.1.2 christos }
738 1.1.1.2 christos #endif
739 1.1.1.2 christos return -1;
740 1.1.1.2 christos }
741 1.1.1.2 christos
742 1.1.1.2 christos /* Return a string corresponding to a protocol number that we can pass to
743 1.1.1.2 christos * getservyname. */
744 1.1.1.2 christos static const char *
745 1.1.1.2 christos evutil_unparse_protoname(int proto)
746 1.1.1.2 christos {
747 1.1.1.2 christos switch (proto) {
748 1.1.1.2 christos case 0:
749 1.1.1.2 christos return NULL;
750 1.1.1.2 christos case IPPROTO_TCP:
751 1.1.1.2 christos return "tcp";
752 1.1.1.2 christos case IPPROTO_UDP:
753 1.1.1.2 christos return "udp";
754 1.1.1.2 christos #ifdef IPPROTO_SCTP
755 1.1.1.2 christos case IPPROTO_SCTP:
756 1.1.1.2 christos return "sctp";
757 1.1.1.2 christos #endif
758 1.1.1.2 christos default:
759 1.1.1.2 christos #ifdef _EVENT_HAVE_GETPROTOBYNUMBER
760 1.1.1.2 christos {
761 1.1.1.2 christos struct protoent *ent = getprotobynumber(proto);
762 1.1.1.2 christos if (ent)
763 1.1.1.2 christos return ent->p_name;
764 1.1.1.2 christos }
765 1.1.1.2 christos #endif
766 1.1.1.2 christos return NULL;
767 1.1.1.2 christos }
768 1.1.1.2 christos }
769 1.1.1.2 christos
770 1.1.1.2 christos static void
771 1.1.1.2 christos evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints)
772 1.1.1.2 christos {
773 1.1.1.2 christos /* If we can guess the protocol from the socktype, do so. */
774 1.1.1.2 christos if (!hints->ai_protocol && hints->ai_socktype) {
775 1.1.1.2 christos if (hints->ai_socktype == SOCK_DGRAM)
776 1.1.1.2 christos hints->ai_protocol = IPPROTO_UDP;
777 1.1.1.2 christos else if (hints->ai_socktype == SOCK_STREAM)
778 1.1.1.2 christos hints->ai_protocol = IPPROTO_TCP;
779 1.1.1.2 christos }
780 1.1.1.2 christos
781 1.1.1.2 christos /* Set the socktype if it isn't set. */
782 1.1.1.2 christos if (!hints->ai_socktype && hints->ai_protocol) {
783 1.1.1.2 christos if (hints->ai_protocol == IPPROTO_UDP)
784 1.1.1.2 christos hints->ai_socktype = SOCK_DGRAM;
785 1.1.1.2 christos else if (hints->ai_protocol == IPPROTO_TCP)
786 1.1.1.2 christos hints->ai_socktype = SOCK_STREAM;
787 1.1.1.2 christos #ifdef IPPROTO_SCTP
788 1.1.1.2 christos else if (hints->ai_protocol == IPPROTO_SCTP)
789 1.1.1.2 christos hints->ai_socktype = SOCK_STREAM;
790 1.1.1.2 christos #endif
791 1.1.1.2 christos }
792 1.1.1.2 christos }
793 1.1.1.2 christos
794 1.1.1.2 christos #if AF_UNSPEC != PF_UNSPEC
795 1.1.1.2 christos #error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC"
796 1.1.1.2 christos #endif
797 1.1.1.2 christos
798 1.1.1.2 christos /** Implements the part of looking up hosts by name that's common to both
799 1.1.1.2 christos * the blocking and nonblocking resolver:
800 1.1.1.2 christos * - Adjust 'hints' to have a reasonable socktype and protocol.
801 1.1.1.2 christos * - Look up the port based on 'servname', and store it in *portnum,
802 1.1.1.2 christos * - Handle the nodename==NULL case
803 1.1.1.2 christos * - Handle some invalid arguments cases.
804 1.1.1.2 christos * - Handle the cases where nodename is an IPv4 or IPv6 address.
805 1.1.1.2 christos *
806 1.1.1.2 christos * If we need the resolver to look up the hostname, we return
807 1.1.1.2 christos * EVUTIL_EAI_NEED_RESOLVE. Otherwise, we can completely implement
808 1.1.1.2 christos * getaddrinfo: we return 0 or an appropriate EVUTIL_EAI_* error, and
809 1.1.1.2 christos * set *res as getaddrinfo would.
810 1.1.1.2 christos */
811 1.1.1.2 christos int
812 1.1.1.2 christos evutil_getaddrinfo_common(const char *nodename, const char *servname,
813 1.1.1.2 christos struct evutil_addrinfo *hints, struct evutil_addrinfo **res, int *portnum)
814 1.1.1.2 christos {
815 1.1.1.2 christos int port = 0;
816 1.1.1.2 christos const char *pname;
817 1.1.1.2 christos
818 1.1.1.2 christos if (nodename == NULL && servname == NULL)
819 1.1.1.2 christos return EVUTIL_EAI_NONAME;
820 1.1.1.2 christos
821 1.1.1.2 christos /* We only understand 3 families */
822 1.1.1.2 christos if (hints->ai_family != PF_UNSPEC && hints->ai_family != PF_INET &&
823 1.1.1.2 christos hints->ai_family != PF_INET6)
824 1.1.1.2 christos return EVUTIL_EAI_FAMILY;
825 1.1.1.2 christos
826 1.1.1.2 christos evutil_getaddrinfo_infer_protocols(hints);
827 1.1.1.2 christos
828 1.1.1.2 christos /* Look up the port number and protocol, if possible. */
829 1.1.1.2 christos pname = evutil_unparse_protoname(hints->ai_protocol);
830 1.1.1.2 christos if (servname) {
831 1.1.1.2 christos /* XXXX We could look at the protocol we got back from
832 1.1.1.2 christos * getservbyname, but it doesn't seem too useful. */
833 1.1.1.2 christos port = evutil_parse_servname(servname, pname, hints);
834 1.1.1.2 christos if (port < 0) {
835 1.1.1.2 christos return EVUTIL_EAI_NONAME;
836 1.1.1.2 christos }
837 1.1.1.2 christos }
838 1.1.1.2 christos
839 1.1.1.2 christos /* If we have no node name, then we're supposed to bind to 'any' and
840 1.1.1.2 christos * connect to localhost. */
841 1.1.1.2 christos if (nodename == NULL) {
842 1.1.1.2 christos struct evutil_addrinfo *res4=NULL, *res6=NULL;
843 1.1.1.2 christos if (hints->ai_family != PF_INET) { /* INET6 or UNSPEC. */
844 1.1.1.2 christos struct sockaddr_in6 sin6;
845 1.1.1.2 christos memset(&sin6, 0, sizeof(sin6));
846 1.1.1.2 christos sin6.sin6_family = AF_INET6;
847 1.1.1.2 christos sin6.sin6_port = htons(port);
848 1.1.1.2 christos if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
849 1.1.1.2 christos /* Bind to :: */
850 1.1.1.2 christos } else {
851 1.1.1.2 christos /* connect to ::1 */
852 1.1.1.2 christos sin6.sin6_addr.s6_addr[15] = 1;
853 1.1.1.2 christos }
854 1.1.1.2 christos res6 = evutil_new_addrinfo((struct sockaddr*)&sin6,
855 1.1.1.2 christos sizeof(sin6), hints);
856 1.1.1.2 christos if (!res6)
857 1.1.1.2 christos return EVUTIL_EAI_MEMORY;
858 1.1.1.2 christos }
859 1.1.1.2 christos
860 1.1.1.2 christos if (hints->ai_family != PF_INET6) { /* INET or UNSPEC */
861 1.1.1.2 christos struct sockaddr_in sin;
862 1.1.1.2 christos memset(&sin, 0, sizeof(sin));
863 1.1.1.2 christos sin.sin_family = AF_INET;
864 1.1.1.2 christos sin.sin_port = htons(port);
865 1.1.1.2 christos if (hints->ai_flags & EVUTIL_AI_PASSIVE) {
866 1.1.1.2 christos /* Bind to 0.0.0.0 */
867 1.1.1.2 christos } else {
868 1.1.1.2 christos /* connect to 127.0.0.1 */
869 1.1.1.2 christos sin.sin_addr.s_addr = htonl(0x7f000001);
870 1.1.1.2 christos }
871 1.1.1.2 christos res4 = evutil_new_addrinfo((struct sockaddr*)&sin,
872 1.1.1.2 christos sizeof(sin), hints);
873 1.1.1.2 christos if (!res4) {
874 1.1.1.2 christos if (res6)
875 1.1.1.2 christos evutil_freeaddrinfo(res6);
876 1.1.1.2 christos return EVUTIL_EAI_MEMORY;
877 1.1.1.2 christos }
878 1.1.1.2 christos }
879 1.1.1.2 christos *res = evutil_addrinfo_append(res4, res6);
880 1.1.1.2 christos return 0;
881 1.1.1.2 christos }
882 1.1.1.2 christos
883 1.1.1.2 christos /* If we can, we should try to parse the hostname without resolving
884 1.1.1.2 christos * it. */
885 1.1.1.2 christos /* Try ipv6. */
886 1.1.1.2 christos if (hints->ai_family == PF_INET6 || hints->ai_family == PF_UNSPEC) {
887 1.1.1.2 christos struct sockaddr_in6 sin6;
888 1.1.1.2 christos memset(&sin6, 0, sizeof(sin6));
889 1.1.1.2 christos if (1==evutil_inet_pton(AF_INET6, nodename, &sin6.sin6_addr)) {
890 1.1.1.2 christos /* Got an ipv6 address. */
891 1.1.1.2 christos sin6.sin6_family = AF_INET6;
892 1.1.1.2 christos sin6.sin6_port = htons(port);
893 1.1.1.2 christos *res = evutil_new_addrinfo((struct sockaddr*)&sin6,
894 1.1.1.2 christos sizeof(sin6), hints);
895 1.1.1.2 christos if (!*res)
896 1.1.1.2 christos return EVUTIL_EAI_MEMORY;
897 1.1.1.2 christos return 0;
898 1.1.1.2 christos }
899 1.1.1.2 christos }
900 1.1.1.2 christos
901 1.1.1.2 christos /* Try ipv4. */
902 1.1.1.2 christos if (hints->ai_family == PF_INET || hints->ai_family == PF_UNSPEC) {
903 1.1.1.2 christos struct sockaddr_in sin;
904 1.1.1.2 christos memset(&sin, 0, sizeof(sin));
905 1.1.1.2 christos if (1==evutil_inet_pton(AF_INET, nodename, &sin.sin_addr)) {
906 1.1.1.2 christos /* Got an ipv6 address. */
907 1.1.1.2 christos sin.sin_family = AF_INET;
908 1.1.1.2 christos sin.sin_port = htons(port);
909 1.1.1.2 christos *res = evutil_new_addrinfo((struct sockaddr*)&sin,
910 1.1.1.2 christos sizeof(sin), hints);
911 1.1.1.2 christos if (!*res)
912 1.1.1.2 christos return EVUTIL_EAI_MEMORY;
913 1.1.1.2 christos return 0;
914 1.1.1.2 christos }
915 1.1.1.2 christos }
916 1.1.1.2 christos
917 1.1.1.2 christos
918 1.1.1.2 christos /* If we have reached this point, we definitely need to do a DNS
919 1.1.1.2 christos * lookup. */
920 1.1.1.2 christos if ((hints->ai_flags & EVUTIL_AI_NUMERICHOST)) {
921 1.1.1.2 christos /* If we're not allowed to do one, then say so. */
922 1.1.1.2 christos return EVUTIL_EAI_NONAME;
923 1.1.1.2 christos }
924 1.1.1.2 christos *portnum = port;
925 1.1.1.2 christos return EVUTIL_EAI_NEED_RESOLVE;
926 1.1.1.2 christos }
927 1.1.1.2 christos
928 1.1.1.2 christos #ifdef _EVENT_HAVE_GETADDRINFO
929 1.1.1.2 christos #define USE_NATIVE_GETADDRINFO
930 1.1.1.2 christos #endif
931 1.1.1.2 christos
932 1.1.1.2 christos #ifdef USE_NATIVE_GETADDRINFO
933 1.1.1.2 christos /* A mask of all the flags that we declare, so we can clear them before calling
934 1.1.1.2 christos * the native getaddrinfo */
935 1.1.1.2 christos static const unsigned int ALL_NONNATIVE_AI_FLAGS =
936 1.1.1.2 christos #ifndef AI_PASSIVE
937 1.1.1.2 christos EVUTIL_AI_PASSIVE |
938 1.1.1.2 christos #endif
939 1.1.1.2 christos #ifndef AI_CANONNAME
940 1.1.1.2 christos EVUTIL_AI_CANONNAME |
941 1.1.1.2 christos #endif
942 1.1.1.2 christos #ifndef AI_NUMERICHOST
943 1.1.1.2 christos EVUTIL_AI_NUMERICHOST |
944 1.1.1.2 christos #endif
945 1.1.1.2 christos #ifndef AI_NUMERICSERV
946 1.1.1.2 christos EVUTIL_AI_NUMERICSERV |
947 1.1.1.2 christos #endif
948 1.1.1.2 christos #ifndef AI_ADDRCONFIG
949 1.1.1.2 christos EVUTIL_AI_ADDRCONFIG |
950 1.1.1.2 christos #endif
951 1.1.1.2 christos #ifndef AI_ALL
952 1.1.1.2 christos EVUTIL_AI_ALL |
953 1.1.1.2 christos #endif
954 1.1.1.2 christos #ifndef AI_V4MAPPED
955 1.1.1.2 christos EVUTIL_AI_V4MAPPED |
956 1.1.1.2 christos #endif
957 1.1.1.2 christos EVUTIL_AI_LIBEVENT_ALLOCATED;
958 1.1.1.2 christos
959 1.1.1.2 christos static const unsigned int ALL_NATIVE_AI_FLAGS =
960 1.1.1.2 christos #ifdef AI_PASSIVE
961 1.1.1.2 christos AI_PASSIVE |
962 1.1.1.2 christos #endif
963 1.1.1.2 christos #ifdef AI_CANONNAME
964 1.1.1.2 christos AI_CANONNAME |
965 1.1.1.2 christos #endif
966 1.1.1.2 christos #ifdef AI_NUMERICHOST
967 1.1.1.2 christos AI_NUMERICHOST |
968 1.1.1.2 christos #endif
969 1.1.1.2 christos #ifdef AI_NUMERICSERV
970 1.1.1.2 christos AI_NUMERICSERV |
971 1.1.1.2 christos #endif
972 1.1.1.2 christos #ifdef AI_ADDRCONFIG
973 1.1.1.2 christos AI_ADDRCONFIG |
974 1.1.1.2 christos #endif
975 1.1.1.2 christos #ifdef AI_ALL
976 1.1.1.2 christos AI_ALL |
977 1.1.1.2 christos #endif
978 1.1.1.2 christos #ifdef AI_V4MAPPED
979 1.1.1.2 christos AI_V4MAPPED |
980 1.1.1.2 christos #endif
981 1.1.1.2 christos 0;
982 1.1.1.2 christos #endif
983 1.1.1.2 christos
984 1.1.1.2 christos #ifndef USE_NATIVE_GETADDRINFO
985 1.1.1.2 christos /* Helper for systems with no getaddrinfo(): make one or more addrinfos out of
986 1.1.1.2 christos * a struct hostent.
987 1.1.1.2 christos */
988 1.1.1.2 christos static struct evutil_addrinfo *
989 1.1.1.2 christos addrinfo_from_hostent(const struct hostent *ent,
990 1.1.1.2 christos int port, const struct evutil_addrinfo *hints)
991 1.1.1.2 christos {
992 1.1.1.2 christos int i;
993 1.1.1.2 christos struct sockaddr_in sin;
994 1.1.1.2 christos struct sockaddr_in6 sin6;
995 1.1.1.2 christos struct sockaddr *sa;
996 1.1.1.2 christos int socklen;
997 1.1.1.2 christos struct evutil_addrinfo *res=NULL, *ai;
998 1.1.1.2 christos void *addrp;
999 1.1.1.2 christos
1000 1.1.1.2 christos if (ent->h_addrtype == PF_INET) {
1001 1.1.1.2 christos memset(&sin, 0, sizeof(sin));
1002 1.1.1.2 christos sin.sin_family = AF_INET;
1003 1.1.1.2 christos sin.sin_port = htons(port);
1004 1.1.1.2 christos sa = (struct sockaddr *)&sin;
1005 1.1.1.2 christos socklen = sizeof(struct sockaddr_in);
1006 1.1.1.2 christos addrp = &sin.sin_addr;
1007 1.1.1.2 christos if (ent->h_length != sizeof(sin.sin_addr)) {
1008 1.1.1.2 christos event_warnx("Weird h_length from gethostbyname");
1009 1.1.1.2 christos return NULL;
1010 1.1.1.2 christos }
1011 1.1.1.2 christos } else if (ent->h_addrtype == PF_INET6) {
1012 1.1.1.2 christos memset(&sin6, 0, sizeof(sin6));
1013 1.1.1.2 christos sin6.sin6_family = AF_INET6;
1014 1.1.1.2 christos sin6.sin6_port = htons(port);
1015 1.1.1.2 christos sa = (struct sockaddr *)&sin6;
1016 1.1.1.2 christos socklen = sizeof(struct sockaddr_in);
1017 1.1.1.2 christos addrp = &sin6.sin6_addr;
1018 1.1.1.2 christos if (ent->h_length != sizeof(sin6.sin6_addr)) {
1019 1.1.1.2 christos event_warnx("Weird h_length from gethostbyname");
1020 1.1.1.2 christos return NULL;
1021 1.1.1.2 christos }
1022 1.1.1.2 christos } else
1023 1.1.1.2 christos return NULL;
1024 1.1.1.2 christos
1025 1.1.1.2 christos for (i = 0; ent->h_addr_list[i]; ++i) {
1026 1.1.1.2 christos memcpy(addrp, ent->h_addr_list[i], ent->h_length);
1027 1.1.1.2 christos ai = evutil_new_addrinfo(sa, socklen, hints);
1028 1.1.1.2 christos if (!ai) {
1029 1.1.1.2 christos evutil_freeaddrinfo(res);
1030 1.1.1.2 christos return NULL;
1031 1.1.1.2 christos }
1032 1.1.1.2 christos res = evutil_addrinfo_append(res, ai);
1033 1.1.1.2 christos }
1034 1.1.1.2 christos
1035 1.1.1.2 christos if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) {
1036 1.1.1.2 christos res->ai_canonname = mm_strdup(ent->h_name);
1037 1.1.1.2 christos if (res->ai_canonname == NULL) {
1038 1.1.1.2 christos evutil_freeaddrinfo(res);
1039 1.1.1.2 christos return NULL;
1040 1.1.1.2 christos }
1041 1.1.1.2 christos }
1042 1.1.1.2 christos
1043 1.1.1.2 christos return res;
1044 1.1.1.2 christos }
1045 1.1.1.2 christos #endif
1046 1.1.1.2 christos
1047 1.1.1.2 christos /* If the EVUTIL_AI_ADDRCONFIG flag is set on hints->ai_flags, and
1048 1.1.1.2 christos * hints->ai_family is PF_UNSPEC, then revise the value of hints->ai_family so
1049 1.1.1.2 christos * that we'll only get addresses we could maybe connect to.
1050 1.1.1.2 christos */
1051 1.1.1.2 christos void
1052 1.1.1.2 christos evutil_adjust_hints_for_addrconfig(struct evutil_addrinfo *hints)
1053 1.1.1.2 christos {
1054 1.1.1.2 christos if (!(hints->ai_flags & EVUTIL_AI_ADDRCONFIG))
1055 1.1.1.2 christos return;
1056 1.1.1.2 christos if (hints->ai_family != PF_UNSPEC)
1057 1.1.1.2 christos return;
1058 1.1.1.2 christos if (!have_checked_interfaces)
1059 1.1.1.2 christos evutil_check_interfaces(0);
1060 1.1.1.2 christos if (had_ipv4_address && !had_ipv6_address) {
1061 1.1.1.2 christos hints->ai_family = PF_INET;
1062 1.1.1.2 christos } else if (!had_ipv4_address && had_ipv6_address) {
1063 1.1.1.2 christos hints->ai_family = PF_INET6;
1064 1.1.1.2 christos }
1065 1.1.1.2 christos }
1066 1.1.1.2 christos
1067 1.1.1.2 christos #ifdef USE_NATIVE_GETADDRINFO
1068 1.1.1.2 christos static int need_numeric_port_hack_=0;
1069 1.1.1.2 christos static int need_socktype_protocol_hack_=0;
1070 1.1.1.2 christos static int tested_for_getaddrinfo_hacks=0;
1071 1.1.1.2 christos
1072 1.1.1.2 christos /* Some older BSDs (like OpenBSD up to 4.6) used to believe that
1073 1.1.1.2 christos giving a numeric port without giving an ai_socktype was verboten.
1074 1.1.1.2 christos We test for this so we can apply an appropriate workaround. If it
1075 1.1.1.2 christos turns out that the bug is present, then:
1076 1.1.1.2 christos
1077 1.1.1.2 christos - If nodename==NULL and servname is numeric, we build an answer
1078 1.1.1.2 christos ourselves using evutil_getaddrinfo_common().
1079 1.1.1.2 christos
1080 1.1.1.2 christos - If nodename!=NULL and servname is numeric, then we set
1081 1.1.1.2 christos servname=NULL when calling getaddrinfo, and post-process the
1082 1.1.1.2 christos result to set the ports on it.
1083 1.1.1.2 christos
1084 1.1.1.2 christos We test for this bug at runtime, since otherwise we can't have the
1085 1.1.1.2 christos same binary run on multiple BSD versions.
1086 1.1.1.2 christos
1087 1.1.1.2 christos - Some versions of Solaris believe that it's nice to leave to protocol
1088 1.1.1.2 christos field set to 0. We test for this so we can apply an appropriate
1089 1.1.1.2 christos workaround.
1090 1.1.1.2 christos */
1091 1.1.1.2 christos static void
1092 1.1.1.2 christos test_for_getaddrinfo_hacks(void)
1093 1.1.1.2 christos {
1094 1.1.1.2 christos int r, r2;
1095 1.1.1.2 christos struct evutil_addrinfo *ai=NULL, *ai2=NULL;
1096 1.1.1.2 christos struct evutil_addrinfo hints;
1097 1.1.1.2 christos
1098 1.1.1.2 christos memset(&hints,0,sizeof(hints));
1099 1.1.1.2 christos hints.ai_family = PF_UNSPEC;
1100 1.1.1.2 christos hints.ai_flags =
1101 1.1.1.2 christos #ifdef AI_NUMERICHOST
1102 1.1.1.2 christos AI_NUMERICHOST |
1103 1.1.1.2 christos #endif
1104 1.1.1.2 christos #ifdef AI_NUMERICSERV
1105 1.1.1.2 christos AI_NUMERICSERV |
1106 1.1.1.2 christos #endif
1107 1.1.1.2 christos 0;
1108 1.1.1.2 christos r = getaddrinfo("1.2.3.4", "80", &hints, &ai);
1109 1.1.1.2 christos hints.ai_socktype = SOCK_STREAM;
1110 1.1.1.2 christos r2 = getaddrinfo("1.2.3.4", "80", &hints, &ai2);
1111 1.1.1.2 christos if (r2 == 0 && r != 0) {
1112 1.1.1.2 christos need_numeric_port_hack_=1;
1113 1.1.1.2 christos }
1114 1.1.1.2 christos if (ai2 && ai2->ai_protocol == 0) {
1115 1.1.1.2 christos need_socktype_protocol_hack_=1;
1116 1.1.1.2 christos }
1117 1.1.1.2 christos
1118 1.1.1.2 christos if (ai)
1119 1.1.1.2 christos freeaddrinfo(ai);
1120 1.1.1.2 christos if (ai2)
1121 1.1.1.2 christos freeaddrinfo(ai2);
1122 1.1.1.2 christos tested_for_getaddrinfo_hacks=1;
1123 1.1.1.2 christos }
1124 1.1.1.2 christos
1125 1.1.1.2 christos static inline int
1126 1.1.1.2 christos need_numeric_port_hack(void)
1127 1.1.1.2 christos {
1128 1.1.1.2 christos if (!tested_for_getaddrinfo_hacks)
1129 1.1.1.2 christos test_for_getaddrinfo_hacks();
1130 1.1.1.2 christos return need_numeric_port_hack_;
1131 1.1.1.2 christos }
1132 1.1.1.2 christos
1133 1.1.1.2 christos static inline int
1134 1.1.1.2 christos need_socktype_protocol_hack(void)
1135 1.1.1.2 christos {
1136 1.1.1.2 christos if (!tested_for_getaddrinfo_hacks)
1137 1.1.1.2 christos test_for_getaddrinfo_hacks();
1138 1.1.1.2 christos return need_socktype_protocol_hack_;
1139 1.1.1.2 christos }
1140 1.1.1.2 christos
1141 1.1.1.2 christos static void
1142 1.1.1.2 christos apply_numeric_port_hack(int port, struct evutil_addrinfo **ai)
1143 1.1.1.2 christos {
1144 1.1.1.2 christos /* Now we run through the list and set the ports on all of the
1145 1.1.1.2 christos * results where ports would make sense. */
1146 1.1.1.2 christos for ( ; *ai; ai = &(*ai)->ai_next) {
1147 1.1.1.2 christos struct sockaddr *sa = (*ai)->ai_addr;
1148 1.1.1.2 christos if (sa && sa->sa_family == AF_INET) {
1149 1.1.1.2 christos struct sockaddr_in *sin = (struct sockaddr_in*)sa;
1150 1.1.1.2 christos sin->sin_port = htons(port);
1151 1.1.1.2 christos } else if (sa && sa->sa_family == AF_INET6) {
1152 1.1.1.2 christos struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)sa;
1153 1.1.1.2 christos sin6->sin6_port = htons(port);
1154 1.1.1.2 christos } else {
1155 1.1.1.2 christos /* A numeric port makes no sense here; remove this one
1156 1.1.1.2 christos * from the list. */
1157 1.1.1.2 christos struct evutil_addrinfo *victim = *ai;
1158 1.1.1.2 christos *ai = victim->ai_next;
1159 1.1.1.2 christos victim->ai_next = NULL;
1160 1.1.1.2 christos freeaddrinfo(victim);
1161 1.1.1.2 christos }
1162 1.1.1.2 christos }
1163 1.1.1.2 christos }
1164 1.1.1.2 christos
1165 1.1.1.2 christos static int
1166 1.1.1.2 christos apply_socktype_protocol_hack(struct evutil_addrinfo *ai)
1167 1.1.1.2 christos {
1168 1.1.1.2 christos struct evutil_addrinfo *ai_new;
1169 1.1.1.2 christos for (; ai; ai = ai->ai_next) {
1170 1.1.1.2 christos evutil_getaddrinfo_infer_protocols(ai);
1171 1.1.1.2 christos if (ai->ai_socktype || ai->ai_protocol)
1172 1.1.1.2 christos continue;
1173 1.1.1.2 christos ai_new = mm_malloc(sizeof(*ai_new));
1174 1.1.1.2 christos if (!ai_new)
1175 1.1.1.2 christos return -1;
1176 1.1.1.2 christos memcpy(ai_new, ai, sizeof(*ai_new));
1177 1.1.1.2 christos ai->ai_socktype = SOCK_STREAM;
1178 1.1.1.2 christos ai->ai_protocol = IPPROTO_TCP;
1179 1.1.1.2 christos ai_new->ai_socktype = SOCK_DGRAM;
1180 1.1.1.2 christos ai_new->ai_protocol = IPPROTO_UDP;
1181 1.1.1.2 christos
1182 1.1.1.2 christos ai_new->ai_next = ai->ai_next;
1183 1.1.1.2 christos ai->ai_next = ai_new;
1184 1.1.1.2 christos }
1185 1.1.1.2 christos return 0;
1186 1.1.1.2 christos }
1187 1.1.1.2 christos #endif
1188 1.1.1.2 christos
1189 1.1.1.2 christos int
1190 1.1.1.2 christos evutil_getaddrinfo(const char *nodename, const char *servname,
1191 1.1.1.2 christos const struct evutil_addrinfo *hints_in, struct evutil_addrinfo **res)
1192 1.1.1.2 christos {
1193 1.1.1.2 christos #ifdef USE_NATIVE_GETADDRINFO
1194 1.1.1.2 christos struct evutil_addrinfo hints;
1195 1.1.1.2 christos int portnum=-1, need_np_hack, err;
1196 1.1.1.2 christos
1197 1.1.1.2 christos if (hints_in) {
1198 1.1.1.2 christos memcpy(&hints, hints_in, sizeof(hints));
1199 1.1.1.2 christos } else {
1200 1.1.1.2 christos memset(&hints, 0, sizeof(hints));
1201 1.1.1.2 christos hints.ai_family = PF_UNSPEC;
1202 1.1.1.2 christos }
1203 1.1.1.2 christos
1204 1.1.1.2 christos #ifndef AI_ADDRCONFIG
1205 1.1.1.2 christos /* Not every system has AI_ADDRCONFIG, so fake it. */
1206 1.1.1.2 christos if (hints.ai_family == PF_UNSPEC &&
1207 1.1.1.2 christos (hints.ai_flags & EVUTIL_AI_ADDRCONFIG)) {
1208 1.1.1.2 christos evutil_adjust_hints_for_addrconfig(&hints);
1209 1.1.1.2 christos }
1210 1.1.1.2 christos #endif
1211 1.1.1.2 christos
1212 1.1.1.2 christos #ifndef AI_NUMERICSERV
1213 1.1.1.2 christos /* Not every system has AI_NUMERICSERV, so fake it. */
1214 1.1.1.2 christos if (hints.ai_flags & EVUTIL_AI_NUMERICSERV) {
1215 1.1.1.2 christos if (servname && parse_numeric_servname(servname)<0)
1216 1.1.1.2 christos return EVUTIL_EAI_NONAME;
1217 1.1.1.2 christos }
1218 1.1.1.2 christos #endif
1219 1.1.1.2 christos
1220 1.1.1.2 christos /* Enough operating systems handle enough common non-resolve
1221 1.1.1.2 christos * cases here weirdly enough that we are better off just
1222 1.1.1.2 christos * overriding them. For example:
1223 1.1.1.2 christos *
1224 1.1.1.2 christos * - Windows doesn't like to infer the protocol from the
1225 1.1.1.2 christos * socket type, or fill in socket or protocol types much at
1226 1.1.1.2 christos * all. It also seems to do its own broken implicit
1227 1.1.1.2 christos * always-on version of AI_ADDRCONFIG that keeps it from
1228 1.1.1.2 christos * ever resolving even a literal IPv6 address when
1229 1.1.1.2 christos * ai_addrtype is PF_UNSPEC.
1230 1.1.1.2 christos */
1231 1.1.1.2 christos #ifdef WIN32
1232 1.1.1.2 christos {
1233 1.1.1.2 christos int tmp_port;
1234 1.1.1.2 christos err = evutil_getaddrinfo_common(nodename,servname,&hints,
1235 1.1.1.2 christos res, &tmp_port);
1236 1.1.1.2 christos if (err == 0 ||
1237 1.1.1.2 christos err == EVUTIL_EAI_MEMORY ||
1238 1.1.1.2 christos err == EVUTIL_EAI_NONAME)
1239 1.1.1.2 christos return err;
1240 1.1.1.2 christos /* If we make it here, the system getaddrinfo can
1241 1.1.1.2 christos * have a crack at it. */
1242 1.1.1.2 christos }
1243 1.1.1.2 christos #endif
1244 1.1.1.2 christos
1245 1.1.1.2 christos /* See documentation for need_numeric_port_hack above.*/
1246 1.1.1.2 christos need_np_hack = need_numeric_port_hack() && servname && !hints.ai_socktype
1247 1.1.1.2 christos && ((portnum=parse_numeric_servname(servname)) >= 0);
1248 1.1.1.2 christos if (need_np_hack) {
1249 1.1.1.2 christos if (!nodename)
1250 1.1.1.2 christos return evutil_getaddrinfo_common(
1251 1.1.1.2 christos NULL,servname,&hints, res, &portnum);
1252 1.1.1.2 christos servname = NULL;
1253 1.1.1.2 christos }
1254 1.1.1.2 christos
1255 1.1.1.2 christos if (need_socktype_protocol_hack()) {
1256 1.1.1.2 christos evutil_getaddrinfo_infer_protocols(&hints);
1257 1.1.1.2 christos }
1258 1.1.1.2 christos
1259 1.1.1.2 christos /* Make sure that we didn't actually steal any AI_FLAGS values that
1260 1.1.1.2 christos * the system is using. (This is a constant expression, and should ge
1261 1.1.1.2 christos * optimized out.)
1262 1.1.1.2 christos *
1263 1.1.1.2 christos * XXXX Turn this into a compile-time failure rather than a run-time
1264 1.1.1.2 christos * failure.
1265 1.1.1.2 christos */
1266 1.1.1.2 christos EVUTIL_ASSERT((ALL_NONNATIVE_AI_FLAGS & ALL_NATIVE_AI_FLAGS) == 0);
1267 1.1.1.2 christos
1268 1.1.1.2 christos /* Clear any flags that only libevent understands. */
1269 1.1.1.2 christos hints.ai_flags &= ~ALL_NONNATIVE_AI_FLAGS;
1270 1.1.1.2 christos
1271 1.1.1.2 christos err = getaddrinfo(nodename, servname, &hints, res);
1272 1.1.1.2 christos if (need_np_hack)
1273 1.1.1.2 christos apply_numeric_port_hack(portnum, res);
1274 1.1.1.2 christos
1275 1.1.1.2 christos if (need_socktype_protocol_hack()) {
1276 1.1.1.2 christos if (apply_socktype_protocol_hack(*res) < 0) {
1277 1.1.1.2 christos evutil_freeaddrinfo(*res);
1278 1.1.1.2 christos *res = NULL;
1279 1.1.1.2 christos return EVUTIL_EAI_MEMORY;
1280 1.1.1.2 christos }
1281 1.1.1.2 christos }
1282 1.1.1.2 christos return err;
1283 1.1.1.2 christos #else
1284 1.1.1.2 christos int port=0, err;
1285 1.1.1.2 christos struct hostent *ent = NULL;
1286 1.1.1.2 christos struct evutil_addrinfo hints;
1287 1.1.1.2 christos
1288 1.1.1.2 christos if (hints_in) {
1289 1.1.1.2 christos memcpy(&hints, hints_in, sizeof(hints));
1290 1.1.1.2 christos } else {
1291 1.1.1.2 christos memset(&hints, 0, sizeof(hints));
1292 1.1.1.2 christos hints.ai_family = PF_UNSPEC;
1293 1.1.1.2 christos }
1294 1.1.1.2 christos
1295 1.1.1.2 christos evutil_adjust_hints_for_addrconfig(&hints);
1296 1.1.1.2 christos
1297 1.1.1.2 christos err = evutil_getaddrinfo_common(nodename, servname, &hints, res, &port);
1298 1.1.1.2 christos if (err != EVUTIL_EAI_NEED_RESOLVE) {
1299 1.1.1.2 christos /* We either succeeded or failed. No need to continue */
1300 1.1.1.2 christos return err;
1301 1.1.1.2 christos }
1302 1.1.1.2 christos
1303 1.1.1.2 christos err = 0;
1304 1.1.1.2 christos /* Use any of the various gethostbyname_r variants as available. */
1305 1.1.1.2 christos {
1306 1.1.1.2 christos #ifdef _EVENT_HAVE_GETHOSTBYNAME_R_6_ARG
1307 1.1.1.2 christos /* This one is what glibc provides. */
1308 1.1.1.2 christos char buf[2048];
1309 1.1.1.2 christos struct hostent hostent;
1310 1.1.1.2 christos int r;
1311 1.1.1.2 christos r = gethostbyname_r(nodename, &hostent, buf, sizeof(buf), &ent,
1312 1.1.1.2 christos &err);
1313 1.1.1.2 christos #elif defined(_EVENT_HAVE_GETHOSTBYNAME_R_5_ARG)
1314 1.1.1.2 christos char buf[2048];
1315 1.1.1.2 christos struct hostent hostent;
1316 1.1.1.2 christos ent = gethostbyname_r(nodename, &hostent, buf, sizeof(buf),
1317 1.1.1.2 christos &err);
1318 1.1.1.2 christos #elif defined(_EVENT_HAVE_GETHOSTBYNAME_R_3_ARG)
1319 1.1.1.2 christos struct hostent_data data;
1320 1.1.1.2 christos struct hostent hostent;
1321 1.1.1.2 christos memset(&data, 0, sizeof(data));
1322 1.1.1.2 christos err = gethostbyname_r(nodename, &hostent, &data);
1323 1.1.1.2 christos ent = err ? NULL : &hostent;
1324 1.1.1.2 christos #else
1325 1.1.1.2 christos /* fall back to gethostbyname. */
1326 1.1.1.2 christos /* XXXX This needs a lock everywhere but Windows. */
1327 1.1.1.2 christos ent = gethostbyname(nodename);
1328 1.1.1.2 christos #ifdef WIN32
1329 1.1.1.2 christos err = WSAGetLastError();
1330 1.1.1.2 christos #else
1331 1.1.1.2 christos err = h_errno;
1332 1.1.1.2 christos #endif
1333 1.1.1.2 christos #endif
1334 1.1.1.2 christos
1335 1.1.1.2 christos /* Now we have either ent or err set. */
1336 1.1.1.2 christos if (!ent) {
1337 1.1.1.2 christos /* XXX is this right for windows ? */
1338 1.1.1.2 christos switch (err) {
1339 1.1.1.2 christos case TRY_AGAIN:
1340 1.1.1.2 christos return EVUTIL_EAI_AGAIN;
1341 1.1.1.2 christos case NO_RECOVERY:
1342 1.1.1.2 christos default:
1343 1.1.1.2 christos return EVUTIL_EAI_FAIL;
1344 1.1.1.2 christos case HOST_NOT_FOUND:
1345 1.1.1.2 christos return EVUTIL_EAI_NONAME;
1346 1.1.1.2 christos case NO_ADDRESS:
1347 1.1.1.2 christos #if NO_DATA != NO_ADDRESS
1348 1.1.1.2 christos case NO_DATA:
1349 1.1.1.2 christos #endif
1350 1.1.1.2 christos return EVUTIL_EAI_NODATA;
1351 1.1.1.2 christos }
1352 1.1.1.2 christos }
1353 1.1.1.2 christos
1354 1.1.1.2 christos if (ent->h_addrtype != hints.ai_family &&
1355 1.1.1.2 christos hints.ai_family != PF_UNSPEC) {
1356 1.1.1.2 christos /* This wasn't the type we were hoping for. Too bad
1357 1.1.1.2 christos * we never had a chance to ask gethostbyname for what
1358 1.1.1.2 christos * we wanted. */
1359 1.1.1.2 christos return EVUTIL_EAI_NONAME;
1360 1.1.1.2 christos }
1361 1.1.1.2 christos
1362 1.1.1.2 christos /* Make sure we got _some_ answers. */
1363 1.1.1.2 christos if (ent->h_length == 0)
1364 1.1.1.2 christos return EVUTIL_EAI_NODATA;
1365 1.1.1.2 christos
1366 1.1.1.2 christos /* If we got an address type we don't know how to make a
1367 1.1.1.2 christos sockaddr for, give up. */
1368 1.1.1.2 christos if (ent->h_addrtype != PF_INET && ent->h_addrtype != PF_INET6)
1369 1.1.1.2 christos return EVUTIL_EAI_FAMILY;
1370 1.1.1.2 christos
1371 1.1.1.2 christos *res = addrinfo_from_hostent(ent, port, &hints);
1372 1.1.1.2 christos if (! *res)
1373 1.1.1.2 christos return EVUTIL_EAI_MEMORY;
1374 1.1.1.2 christos }
1375 1.1.1.2 christos
1376 1.1.1.2 christos return 0;
1377 1.1.1.2 christos #endif
1378 1.1.1.2 christos }
1379 1.1.1.2 christos
1380 1.1.1.2 christos void
1381 1.1.1.2 christos evutil_freeaddrinfo(struct evutil_addrinfo *ai)
1382 1.1.1.2 christos {
1383 1.1.1.2 christos #ifdef _EVENT_HAVE_GETADDRINFO
1384 1.1.1.2 christos if (!(ai->ai_flags & EVUTIL_AI_LIBEVENT_ALLOCATED)) {
1385 1.1.1.2 christos freeaddrinfo(ai);
1386 1.1.1.2 christos return;
1387 1.1.1.2 christos }
1388 1.1.1.2 christos #endif
1389 1.1.1.2 christos while (ai) {
1390 1.1.1.2 christos struct evutil_addrinfo *next = ai->ai_next;
1391 1.1.1.2 christos if (ai->ai_canonname)
1392 1.1.1.2 christos mm_free(ai->ai_canonname);
1393 1.1.1.2 christos mm_free(ai);
1394 1.1.1.2 christos ai = next;
1395 1.1.1.2 christos }
1396 1.1.1.2 christos }
1397 1.1.1.2 christos
1398 1.1.1.2 christos static evdns_getaddrinfo_fn evdns_getaddrinfo_impl = NULL;
1399 1.1.1.2 christos
1400 1.1.1.2 christos void
1401 1.1.1.2 christos evutil_set_evdns_getaddrinfo_fn(evdns_getaddrinfo_fn fn)
1402 1.1.1.2 christos {
1403 1.1.1.2 christos if (!evdns_getaddrinfo_impl)
1404 1.1.1.2 christos evdns_getaddrinfo_impl = fn;
1405 1.1.1.2 christos }
1406 1.1.1.2 christos
1407 1.1.1.2 christos /* Internal helper function: act like evdns_getaddrinfo if dns_base is set;
1408 1.1.1.2 christos * otherwise do a blocking resolve and pass the result to the callback in the
1409 1.1.1.2 christos * way that evdns_getaddrinfo would.
1410 1.1.1.2 christos */
1411 1.1.1.2 christos int
1412 1.1.1.2 christos evutil_getaddrinfo_async(struct evdns_base *dns_base,
1413 1.1.1.2 christos const char *nodename, const char *servname,
1414 1.1.1.2 christos const struct evutil_addrinfo *hints_in,
1415 1.1.1.2 christos void (*cb)(int, struct evutil_addrinfo *, void *), void *arg)
1416 1.1.1.2 christos {
1417 1.1.1.2 christos if (dns_base && evdns_getaddrinfo_impl) {
1418 1.1.1.2 christos evdns_getaddrinfo_impl(
1419 1.1.1.2 christos dns_base, nodename, servname, hints_in, cb, arg);
1420 1.1.1.2 christos } else {
1421 1.1.1.2 christos struct evutil_addrinfo *ai=NULL;
1422 1.1.1.2 christos int err;
1423 1.1.1.2 christos err = evutil_getaddrinfo(nodename, servname, hints_in, &ai);
1424 1.1.1.2 christos cb(err, ai, arg);
1425 1.1.1.2 christos }
1426 1.1.1.2 christos return 0;
1427 1.1.1.2 christos }
1428 1.1.1.2 christos
1429 1.1.1.2 christos const char *
1430 1.1.1.2 christos evutil_gai_strerror(int err)
1431 1.1.1.2 christos {
1432 1.1.1.2 christos /* As a sneaky side-benefit, this case statement will get most
1433 1.1.1.2 christos * compilers to tell us if any of the error codes we defined
1434 1.1.1.2 christos * conflict with the platform's native error codes. */
1435 1.1.1.2 christos switch (err) {
1436 1.1.1.2 christos case EVUTIL_EAI_CANCEL:
1437 1.1.1.2 christos return "Request canceled";
1438 1.1.1.2 christos case 0:
1439 1.1.1.2 christos return "No error";
1440 1.1.1.2 christos
1441 1.1.1.2 christos case EVUTIL_EAI_ADDRFAMILY:
1442 1.1.1.2 christos return "address family for nodename not supported";
1443 1.1.1.2 christos case EVUTIL_EAI_AGAIN:
1444 1.1.1.2 christos return "temporary failure in name resolution";
1445 1.1.1.2 christos case EVUTIL_EAI_BADFLAGS:
1446 1.1.1.2 christos return "invalid value for ai_flags";
1447 1.1.1.2 christos case EVUTIL_EAI_FAIL:
1448 1.1.1.2 christos return "non-recoverable failure in name resolution";
1449 1.1.1.2 christos case EVUTIL_EAI_FAMILY:
1450 1.1.1.2 christos return "ai_family not supported";
1451 1.1.1.2 christos case EVUTIL_EAI_MEMORY:
1452 1.1.1.2 christos return "memory allocation failure";
1453 1.1.1.2 christos case EVUTIL_EAI_NODATA:
1454 1.1.1.2 christos return "no address associated with nodename";
1455 1.1.1.2 christos case EVUTIL_EAI_NONAME:
1456 1.1.1.2 christos return "nodename nor servname provided, or not known";
1457 1.1.1.2 christos case EVUTIL_EAI_SERVICE:
1458 1.1.1.2 christos return "servname not supported for ai_socktype";
1459 1.1.1.2 christos case EVUTIL_EAI_SOCKTYPE:
1460 1.1.1.2 christos return "ai_socktype not supported";
1461 1.1.1.2 christos case EVUTIL_EAI_SYSTEM:
1462 1.1.1.2 christos return "system error";
1463 1.1.1.2 christos default:
1464 1.1.1.2 christos #if defined(USE_NATIVE_GETADDRINFO) && defined(WIN32)
1465 1.1.1.2 christos return gai_strerrorA(err);
1466 1.1.1.2 christos #elif defined(USE_NATIVE_GETADDRINFO)
1467 1.1.1.2 christos return gai_strerror(err);
1468 1.1.1.2 christos #else
1469 1.1.1.2 christos return "Unknown error code";
1470 1.1.1.2 christos #endif
1471 1.1.1.2 christos }
1472 1.1.1.2 christos }
1473 1.1.1.2 christos
1474 1.1.1.2 christos #ifdef WIN32
1475 1.1.1.2 christos #define E(code, s) { code, (s " [" #code " ]") }
1476 1.1.1.2 christos static struct { int code; const char *msg; } windows_socket_errors[] = {
1477 1.1.1.2 christos E(WSAEINTR, "Interrupted function call"),
1478 1.1.1.2 christos E(WSAEACCES, "Permission denied"),
1479 1.1.1.2 christos E(WSAEFAULT, "Bad address"),
1480 1.1.1.2 christos E(WSAEINVAL, "Invalid argument"),
1481 1.1.1.2 christos E(WSAEMFILE, "Too many open files"),
1482 1.1.1.2 christos E(WSAEWOULDBLOCK, "Resource temporarily unavailable"),
1483 1.1.1.2 christos E(WSAEINPROGRESS, "Operation now in progress"),
1484 1.1.1.2 christos E(WSAEALREADY, "Operation already in progress"),
1485 1.1.1.2 christos E(WSAENOTSOCK, "Socket operation on nonsocket"),
1486 1.1.1.2 christos E(WSAEDESTADDRREQ, "Destination address required"),
1487 1.1.1.2 christos E(WSAEMSGSIZE, "Message too long"),
1488 1.1.1.2 christos E(WSAEPROTOTYPE, "Protocol wrong for socket"),
1489 1.1.1.2 christos E(WSAENOPROTOOPT, "Bad protocol option"),
1490 1.1.1.2 christos E(WSAEPROTONOSUPPORT, "Protocol not supported"),
1491 1.1.1.2 christos E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
1492 1.1.1.2 christos /* What's the difference between NOTSUPP and NOSUPPORT? :) */
1493 1.1.1.2 christos E(WSAEOPNOTSUPP, "Operation not supported"),
1494 1.1.1.2 christos E(WSAEPFNOSUPPORT, "Protocol family not supported"),
1495 1.1.1.2 christos E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
1496 1.1.1.2 christos E(WSAEADDRINUSE, "Address already in use"),
1497 1.1.1.2 christos E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
1498 1.1.1.2 christos E(WSAENETDOWN, "Network is down"),
1499 1.1.1.2 christos E(WSAENETUNREACH, "Network is unreachable"),
1500 1.1.1.2 christos E(WSAENETRESET, "Network dropped connection on reset"),
1501 1.1.1.2 christos E(WSAECONNABORTED, "Software caused connection abort"),
1502 1.1.1.2 christos E(WSAECONNRESET, "Connection reset by peer"),
1503 1.1.1.2 christos E(WSAENOBUFS, "No buffer space available"),
1504 1.1.1.2 christos E(WSAEISCONN, "Socket is already connected"),
1505 1.1.1.2 christos E(WSAENOTCONN, "Socket is not connected"),
1506 1.1.1.2 christos E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
1507 1.1.1.2 christos E(WSAETIMEDOUT, "Connection timed out"),
1508 1.1.1.2 christos E(WSAECONNREFUSED, "Connection refused"),
1509 1.1.1.2 christos E(WSAEHOSTDOWN, "Host is down"),
1510 1.1.1.2 christos E(WSAEHOSTUNREACH, "No route to host"),
1511 1.1.1.2 christos E(WSAEPROCLIM, "Too many processes"),
1512 1.1.1.2 christos
1513 1.1.1.2 christos /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
1514 1.1.1.2 christos E(WSASYSNOTREADY, "Network subsystem is unavailable"),
1515 1.1.1.2 christos E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
1516 1.1.1.2 christos E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
1517 1.1.1.2 christos E(WSAEDISCON, "Graceful shutdown now in progress"),
1518 1.1.1.2 christos #ifdef WSATYPE_NOT_FOUND
1519 1.1.1.2 christos E(WSATYPE_NOT_FOUND, "Class type not found"),
1520 1.1.1.2 christos #endif
1521 1.1.1.2 christos E(WSAHOST_NOT_FOUND, "Host not found"),
1522 1.1.1.2 christos E(WSATRY_AGAIN, "Nonauthoritative host not found"),
1523 1.1.1.2 christos E(WSANO_RECOVERY, "This is a nonrecoverable error"),
1524 1.1.1.2 christos E(WSANO_DATA, "Valid name, no data record of requested type)"),
1525 1.1.1.2 christos
1526 1.1.1.2 christos /* There are some more error codes whose numeric values are marked
1527 1.1.1.2 christos * <b>OS dependent</b>. They start with WSA_, apparently for the same
1528 1.1.1.2 christos * reason that practitioners of some craft traditions deliberately
1529 1.1.1.2 christos * introduce imperfections into their baskets and rugs "to allow the
1530 1.1.1.2 christos * evil spirits to escape." If we catch them, then our binaries
1531 1.1.1.2 christos * might not report consistent results across versions of Windows.
1532 1.1.1.2 christos * Thus, I'm going to let them all fall through.
1533 1.1.1.2 christos */
1534 1.1.1.2 christos { -1, NULL },
1535 1.1.1.2 christos };
1536 1.1.1.2 christos #undef E
1537 1.1.1.2 christos /** Equivalent to strerror, but for windows socket errors. */
1538 1.1.1.2 christos const char *
1539 1.1.1.2 christos evutil_socket_error_to_string(int errcode)
1540 1.1.1.2 christos {
1541 1.1.1.2 christos /* XXXX Is there really no built-in function to do this? */
1542 1.1.1.2 christos int i;
1543 1.1.1.2 christos for (i=0; windows_socket_errors[i].code >= 0; ++i) {
1544 1.1.1.2 christos if (errcode == windows_socket_errors[i].code)
1545 1.1.1.2 christos return windows_socket_errors[i].msg;
1546 1.1.1.2 christos }
1547 1.1.1.2 christos return strerror(errcode);
1548 1.1.1.2 christos }
1549 1.1.1.2 christos #endif
1550 1.1.1.2 christos
1551 1.1 plunky int
1552 1.1 plunky evutil_snprintf(char *buf, size_t buflen, const char *format, ...)
1553 1.1 plunky {
1554 1.1 plunky int r;
1555 1.1 plunky va_list ap;
1556 1.1 plunky va_start(ap, format);
1557 1.1 plunky r = evutil_vsnprintf(buf, buflen, format, ap);
1558 1.1 plunky va_end(ap);
1559 1.1 plunky return r;
1560 1.1 plunky }
1561 1.1 plunky
1562 1.1 plunky int
1563 1.1 plunky evutil_vsnprintf(char *buf, size_t buflen, const char *format, va_list ap)
1564 1.1 plunky {
1565 1.1.1.2 christos int r;
1566 1.1.1.2 christos if (!buflen)
1567 1.1.1.2 christos return 0;
1568 1.1.1.3 spz #if defined(_MSC_VER) || defined(WIN32)
1569 1.1.1.2 christos r = _vsnprintf(buf, buflen, format, ap);
1570 1.1.1.2 christos if (r < 0)
1571 1.1.1.2 christos r = _vscprintf(format, ap);
1572 1.1.1.2 christos #elif defined(sgi)
1573 1.1.1.2 christos /* Make sure we always use the correct vsnprintf on IRIX */
1574 1.1.1.2 christos extern int _xpg5_vsnprintf(char * __restrict,
1575 1.1.1.2 christos __SGI_LIBC_NAMESPACE_QUALIFIER size_t,
1576 1.1.1.2 christos const char * __restrict, /* va_list */ char *);
1577 1.1.1.2 christos
1578 1.1.1.2 christos r = _xpg5_vsnprintf(buf, buflen, format, ap);
1579 1.1 plunky #else
1580 1.1.1.2 christos r = vsnprintf(buf, buflen, format, ap);
1581 1.1.1.2 christos #endif
1582 1.1 plunky buf[buflen-1] = '\0';
1583 1.1 plunky return r;
1584 1.1.1.2 christos }
1585 1.1.1.2 christos
1586 1.1.1.2 christos #define USE_INTERNAL_NTOP
1587 1.1.1.2 christos #define USE_INTERNAL_PTON
1588 1.1.1.2 christos
1589 1.1.1.2 christos const char *
1590 1.1.1.2 christos evutil_inet_ntop(int af, const void *src, char *dst, size_t len)
1591 1.1.1.2 christos {
1592 1.1.1.2 christos #if defined(_EVENT_HAVE_INET_NTOP) && !defined(USE_INTERNAL_NTOP)
1593 1.1.1.2 christos return inet_ntop(af, src, dst, len);
1594 1.1.1.2 christos #else
1595 1.1.1.2 christos if (af == AF_INET) {
1596 1.1.1.2 christos const struct in_addr *in = src;
1597 1.1.1.2 christos const ev_uint32_t a = ntohl(in->s_addr);
1598 1.1.1.2 christos int r;
1599 1.1.1.2 christos r = evutil_snprintf(dst, len, "%d.%d.%d.%d",
1600 1.1.1.2 christos (int)(ev_uint8_t)((a>>24)&0xff),
1601 1.1.1.2 christos (int)(ev_uint8_t)((a>>16)&0xff),
1602 1.1.1.2 christos (int)(ev_uint8_t)((a>>8 )&0xff),
1603 1.1.1.2 christos (int)(ev_uint8_t)((a )&0xff));
1604 1.1.1.2 christos if (r<0||(size_t)r>=len)
1605 1.1.1.2 christos return NULL;
1606 1.1.1.2 christos else
1607 1.1.1.2 christos return dst;
1608 1.1.1.2 christos #ifdef AF_INET6
1609 1.1.1.2 christos } else if (af == AF_INET6) {
1610 1.1.1.2 christos const struct in6_addr *addr = src;
1611 1.1.1.2 christos char buf[64], *cp;
1612 1.1.1.2 christos int longestGapLen = 0, longestGapPos = -1, i,
1613 1.1.1.2 christos curGapPos = -1, curGapLen = 0;
1614 1.1.1.2 christos ev_uint16_t words[8];
1615 1.1.1.2 christos for (i = 0; i < 8; ++i) {
1616 1.1.1.2 christos words[i] =
1617 1.1.1.2 christos (((ev_uint16_t)addr->s6_addr[2*i])<<8) + addr->s6_addr[2*i+1];
1618 1.1.1.2 christos }
1619 1.1.1.2 christos if (words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 &&
1620 1.1.1.2 christos words[4] == 0 && ((words[5] == 0 && words[6] && words[7]) ||
1621 1.1.1.2 christos (words[5] == 0xffff))) {
1622 1.1.1.2 christos /* This is an IPv4 address. */
1623 1.1.1.2 christos if (words[5] == 0) {
1624 1.1.1.2 christos evutil_snprintf(buf, sizeof(buf), "::%d.%d.%d.%d",
1625 1.1.1.2 christos addr->s6_addr[12], addr->s6_addr[13],
1626 1.1.1.2 christos addr->s6_addr[14], addr->s6_addr[15]);
1627 1.1.1.2 christos } else {
1628 1.1.1.2 christos evutil_snprintf(buf, sizeof(buf), "::%x:%d.%d.%d.%d", words[5],
1629 1.1.1.2 christos addr->s6_addr[12], addr->s6_addr[13],
1630 1.1.1.2 christos addr->s6_addr[14], addr->s6_addr[15]);
1631 1.1.1.2 christos }
1632 1.1.1.2 christos if (strlen(buf) > len)
1633 1.1.1.2 christos return NULL;
1634 1.1.1.2 christos strlcpy(dst, buf, len);
1635 1.1.1.2 christos return dst;
1636 1.1.1.2 christos }
1637 1.1.1.2 christos i = 0;
1638 1.1.1.2 christos while (i < 8) {
1639 1.1.1.2 christos if (words[i] == 0) {
1640 1.1.1.2 christos curGapPos = i++;
1641 1.1.1.2 christos curGapLen = 1;
1642 1.1.1.2 christos while (i<8 && words[i] == 0) {
1643 1.1.1.2 christos ++i; ++curGapLen;
1644 1.1.1.2 christos }
1645 1.1.1.2 christos if (curGapLen > longestGapLen) {
1646 1.1.1.2 christos longestGapPos = curGapPos;
1647 1.1.1.2 christos longestGapLen = curGapLen;
1648 1.1.1.2 christos }
1649 1.1.1.2 christos } else {
1650 1.1.1.2 christos ++i;
1651 1.1.1.2 christos }
1652 1.1.1.2 christos }
1653 1.1.1.2 christos if (longestGapLen<=1)
1654 1.1.1.2 christos longestGapPos = -1;
1655 1.1.1.2 christos
1656 1.1.1.2 christos cp = buf;
1657 1.1.1.2 christos for (i = 0; i < 8; ++i) {
1658 1.1.1.2 christos if (words[i] == 0 && longestGapPos == i) {
1659 1.1.1.2 christos if (i == 0)
1660 1.1.1.2 christos *cp++ = ':';
1661 1.1.1.2 christos *cp++ = ':';
1662 1.1.1.2 christos while (i < 8 && words[i] == 0)
1663 1.1.1.2 christos ++i;
1664 1.1.1.2 christos --i; /* to compensate for loop increment. */
1665 1.1.1.2 christos } else {
1666 1.1.1.2 christos evutil_snprintf(cp,
1667 1.1.1.2 christos sizeof(buf)-(cp-buf), "%x", (unsigned)words[i]);
1668 1.1.1.2 christos cp += strlen(cp);
1669 1.1.1.2 christos if (i != 7)
1670 1.1.1.2 christos *cp++ = ':';
1671 1.1.1.2 christos }
1672 1.1.1.2 christos }
1673 1.1.1.2 christos *cp = '\0';
1674 1.1.1.2 christos if (strlen(buf) > len)
1675 1.1.1.2 christos return NULL;
1676 1.1.1.2 christos strlcpy(dst, buf, len);
1677 1.1.1.2 christos return dst;
1678 1.1.1.2 christos #endif
1679 1.1.1.2 christos } else {
1680 1.1.1.2 christos return NULL;
1681 1.1.1.2 christos }
1682 1.1.1.2 christos #endif
1683 1.1.1.2 christos }
1684 1.1.1.2 christos
1685 1.1.1.2 christos int
1686 1.1.1.2 christos evutil_inet_pton(int af, const char *src, void *dst)
1687 1.1.1.2 christos {
1688 1.1.1.2 christos #if defined(_EVENT_HAVE_INET_PTON) && !defined(USE_INTERNAL_PTON)
1689 1.1.1.2 christos return inet_pton(af, src, dst);
1690 1.1.1.2 christos #else
1691 1.1.1.2 christos if (af == AF_INET) {
1692 1.1.1.2 christos int a,b,c,d;
1693 1.1.1.2 christos char more;
1694 1.1.1.2 christos struct in_addr *addr = dst;
1695 1.1.1.2 christos if (sscanf(src, "%d.%d.%d.%d%c", &a,&b,&c,&d,&more) != 4)
1696 1.1.1.2 christos return 0;
1697 1.1.1.2 christos if (a < 0 || a > 255) return 0;
1698 1.1.1.2 christos if (b < 0 || b > 255) return 0;
1699 1.1.1.2 christos if (c < 0 || c > 255) return 0;
1700 1.1.1.2 christos if (d < 0 || d > 255) return 0;
1701 1.1.1.2 christos addr->s_addr = htonl((a<<24) | (b<<16) | (c<<8) | d);
1702 1.1.1.2 christos return 1;
1703 1.1.1.2 christos #ifdef AF_INET6
1704 1.1.1.2 christos } else if (af == AF_INET6) {
1705 1.1.1.2 christos struct in6_addr *out = dst;
1706 1.1.1.2 christos ev_uint16_t words[8];
1707 1.1.1.2 christos int gapPos = -1, i, setWords=0;
1708 1.1.1.2 christos const char *dot = strchr(src, '.');
1709 1.1.1.2 christos const char *eow; /* end of words. */
1710 1.1.1.2 christos if (dot == src)
1711 1.1.1.2 christos return 0;
1712 1.1.1.2 christos else if (!dot)
1713 1.1.1.2 christos eow = src+strlen(src);
1714 1.1.1.2 christos else {
1715 1.1.1.2 christos int byte1,byte2,byte3,byte4;
1716 1.1.1.2 christos char more;
1717 1.1.1.2 christos for (eow = dot-1; eow >= src && EVUTIL_ISDIGIT(*eow); --eow)
1718 1.1.1.2 christos ;
1719 1.1.1.2 christos ++eow;
1720 1.1.1.2 christos
1721 1.1.1.2 christos /* We use "scanf" because some platform inet_aton()s are too lax
1722 1.1.1.2 christos * about IPv4 addresses of the form "1.2.3" */
1723 1.1.1.2 christos if (sscanf(eow, "%d.%d.%d.%d%c",
1724 1.1.1.2 christos &byte1,&byte2,&byte3,&byte4,&more) != 4)
1725 1.1.1.2 christos return 0;
1726 1.1.1.2 christos
1727 1.1.1.2 christos if (byte1 > 255 || byte1 < 0 ||
1728 1.1.1.2 christos byte2 > 255 || byte2 < 0 ||
1729 1.1.1.2 christos byte3 > 255 || byte3 < 0 ||
1730 1.1.1.2 christos byte4 > 255 || byte4 < 0)
1731 1.1.1.2 christos return 0;
1732 1.1.1.2 christos
1733 1.1.1.2 christos words[6] = (byte1<<8) | byte2;
1734 1.1.1.2 christos words[7] = (byte3<<8) | byte4;
1735 1.1.1.2 christos setWords += 2;
1736 1.1.1.2 christos }
1737 1.1.1.2 christos
1738 1.1.1.2 christos i = 0;
1739 1.1.1.2 christos while (src < eow) {
1740 1.1.1.2 christos if (i > 7)
1741 1.1.1.2 christos return 0;
1742 1.1.1.2 christos if (EVUTIL_ISXDIGIT(*src)) {
1743 1.1.1.2 christos char *next;
1744 1.1.1.2 christos long r = strtol(src, &next, 16);
1745 1.1.1.2 christos if (next > 4+src)
1746 1.1.1.2 christos return 0;
1747 1.1.1.2 christos if (next == src)
1748 1.1.1.2 christos return 0;
1749 1.1.1.2 christos if (r<0 || r>65536)
1750 1.1.1.2 christos return 0;
1751 1.1.1.2 christos
1752 1.1.1.2 christos words[i++] = (ev_uint16_t)r;
1753 1.1.1.2 christos setWords++;
1754 1.1.1.2 christos src = next;
1755 1.1.1.2 christos if (*src != ':' && src != eow)
1756 1.1.1.2 christos return 0;
1757 1.1.1.2 christos ++src;
1758 1.1.1.2 christos } else if (*src == ':' && i > 0 && gapPos==-1) {
1759 1.1.1.2 christos gapPos = i;
1760 1.1.1.2 christos ++src;
1761 1.1.1.2 christos } else if (*src == ':' && i == 0 && src[1] == ':' && gapPos==-1) {
1762 1.1.1.2 christos gapPos = i;
1763 1.1.1.2 christos src += 2;
1764 1.1.1.2 christos } else {
1765 1.1.1.2 christos return 0;
1766 1.1.1.2 christos }
1767 1.1.1.2 christos }
1768 1.1.1.2 christos
1769 1.1.1.2 christos if (setWords > 8 ||
1770 1.1.1.2 christos (setWords == 8 && gapPos != -1) ||
1771 1.1.1.2 christos (setWords < 8 && gapPos == -1))
1772 1.1.1.2 christos return 0;
1773 1.1.1.2 christos
1774 1.1.1.2 christos if (gapPos >= 0) {
1775 1.1.1.2 christos int nToMove = setWords - (dot ? 2 : 0) - gapPos;
1776 1.1.1.2 christos int gapLen = 8 - setWords;
1777 1.1.1.2 christos /* assert(nToMove >= 0); */
1778 1.1.1.2 christos if (nToMove < 0)
1779 1.1.1.2 christos return -1; /* should be impossible */
1780 1.1.1.2 christos memmove(&words[gapPos+gapLen], &words[gapPos],
1781 1.1.1.2 christos sizeof(ev_uint16_t)*nToMove);
1782 1.1.1.2 christos memset(&words[gapPos], 0, sizeof(ev_uint16_t)*gapLen);
1783 1.1.1.2 christos }
1784 1.1.1.2 christos for (i = 0; i < 8; ++i) {
1785 1.1.1.2 christos out->s6_addr[2*i ] = words[i] >> 8;
1786 1.1.1.2 christos out->s6_addr[2*i+1] = words[i] & 0xff;
1787 1.1.1.2 christos }
1788 1.1.1.2 christos
1789 1.1.1.2 christos return 1;
1790 1.1.1.2 christos #endif
1791 1.1.1.2 christos } else {
1792 1.1.1.2 christos return -1;
1793 1.1.1.2 christos }
1794 1.1.1.2 christos #endif
1795 1.1.1.2 christos }
1796 1.1.1.2 christos
1797 1.1.1.2 christos int
1798 1.1.1.2 christos evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *outlen)
1799 1.1.1.2 christos {
1800 1.1.1.2 christos int port;
1801 1.1.1.2 christos char buf[128];
1802 1.1.1.2 christos const char *cp, *addr_part, *port_part;
1803 1.1.1.2 christos int is_ipv6;
1804 1.1.1.2 christos /* recognized formats are:
1805 1.1.1.2 christos * [ipv6]:port
1806 1.1.1.2 christos * ipv6
1807 1.1.1.2 christos * [ipv6]
1808 1.1.1.2 christos * ipv4:port
1809 1.1.1.2 christos * ipv4
1810 1.1.1.2 christos */
1811 1.1.1.2 christos
1812 1.1.1.2 christos cp = strchr(ip_as_string, ':');
1813 1.1.1.2 christos if (*ip_as_string == '[') {
1814 1.1.1.2 christos int len;
1815 1.1.1.2 christos if (!(cp = strchr(ip_as_string, ']'))) {
1816 1.1.1.2 christos return -1;
1817 1.1.1.2 christos }
1818 1.1.1.2 christos len = (int) ( cp-(ip_as_string + 1) );
1819 1.1.1.2 christos if (len > (int)sizeof(buf)-1) {
1820 1.1.1.2 christos return -1;
1821 1.1.1.2 christos }
1822 1.1.1.2 christos memcpy(buf, ip_as_string+1, len);
1823 1.1.1.2 christos buf[len] = '\0';
1824 1.1.1.2 christos addr_part = buf;
1825 1.1.1.2 christos if (cp[1] == ':')
1826 1.1.1.2 christos port_part = cp+2;
1827 1.1.1.2 christos else
1828 1.1.1.2 christos port_part = NULL;
1829 1.1.1.2 christos is_ipv6 = 1;
1830 1.1.1.2 christos } else if (cp && strchr(cp+1, ':')) {
1831 1.1.1.2 christos is_ipv6 = 1;
1832 1.1.1.2 christos addr_part = ip_as_string;
1833 1.1.1.2 christos port_part = NULL;
1834 1.1.1.2 christos } else if (cp) {
1835 1.1.1.2 christos is_ipv6 = 0;
1836 1.1.1.2 christos if (cp - ip_as_string > (int)sizeof(buf)-1) {
1837 1.1.1.2 christos return -1;
1838 1.1.1.2 christos }
1839 1.1.1.2 christos memcpy(buf, ip_as_string, cp-ip_as_string);
1840 1.1.1.2 christos buf[cp-ip_as_string] = '\0';
1841 1.1.1.2 christos addr_part = buf;
1842 1.1.1.2 christos port_part = cp+1;
1843 1.1.1.2 christos } else {
1844 1.1.1.2 christos addr_part = ip_as_string;
1845 1.1.1.2 christos port_part = NULL;
1846 1.1.1.2 christos is_ipv6 = 0;
1847 1.1.1.2 christos }
1848 1.1.1.2 christos
1849 1.1.1.2 christos if (port_part == NULL) {
1850 1.1.1.2 christos port = 0;
1851 1.1.1.2 christos } else {
1852 1.1.1.2 christos port = atoi(port_part);
1853 1.1.1.2 christos if (port <= 0 || port > 65535) {
1854 1.1.1.2 christos return -1;
1855 1.1.1.2 christos }
1856 1.1.1.2 christos }
1857 1.1.1.2 christos
1858 1.1.1.2 christos if (!addr_part)
1859 1.1.1.2 christos return -1; /* Should be impossible. */
1860 1.1.1.2 christos #ifdef AF_INET6
1861 1.1.1.2 christos if (is_ipv6)
1862 1.1.1.2 christos {
1863 1.1.1.2 christos struct sockaddr_in6 sin6;
1864 1.1.1.2 christos memset(&sin6, 0, sizeof(sin6));
1865 1.1.1.2 christos #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN
1866 1.1.1.2 christos sin6.sin6_len = sizeof(sin6);
1867 1.1.1.2 christos #endif
1868 1.1.1.2 christos sin6.sin6_family = AF_INET6;
1869 1.1.1.2 christos sin6.sin6_port = htons(port);
1870 1.1.1.2 christos if (1 != evutil_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr))
1871 1.1.1.2 christos return -1;
1872 1.1.1.2 christos if ((int)sizeof(sin6) > *outlen)
1873 1.1.1.2 christos return -1;
1874 1.1.1.2 christos memset(out, 0, *outlen);
1875 1.1.1.2 christos memcpy(out, &sin6, sizeof(sin6));
1876 1.1.1.2 christos *outlen = sizeof(sin6);
1877 1.1.1.2 christos return 0;
1878 1.1.1.2 christos }
1879 1.1.1.2 christos else
1880 1.1.1.2 christos #endif
1881 1.1.1.2 christos {
1882 1.1.1.2 christos struct sockaddr_in sin;
1883 1.1.1.2 christos memset(&sin, 0, sizeof(sin));
1884 1.1.1.2 christos #ifdef _EVENT_HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
1885 1.1.1.2 christos sin.sin_len = sizeof(sin);
1886 1.1.1.2 christos #endif
1887 1.1.1.2 christos sin.sin_family = AF_INET;
1888 1.1.1.2 christos sin.sin_port = htons(port);
1889 1.1.1.2 christos if (1 != evutil_inet_pton(AF_INET, addr_part, &sin.sin_addr))
1890 1.1.1.2 christos return -1;
1891 1.1.1.2 christos if ((int)sizeof(sin) > *outlen)
1892 1.1.1.2 christos return -1;
1893 1.1.1.2 christos memset(out, 0, *outlen);
1894 1.1.1.2 christos memcpy(out, &sin, sizeof(sin));
1895 1.1.1.2 christos *outlen = sizeof(sin);
1896 1.1.1.2 christos return 0;
1897 1.1.1.2 christos }
1898 1.1.1.2 christos }
1899 1.1.1.2 christos
1900 1.1.1.2 christos const char *
1901 1.1.1.2 christos evutil_format_sockaddr_port(const struct sockaddr *sa, char *out, size_t outlen)
1902 1.1.1.2 christos {
1903 1.1.1.2 christos char b[128];
1904 1.1.1.2 christos const char *res=NULL;
1905 1.1.1.2 christos int port;
1906 1.1.1.2 christos if (sa->sa_family == AF_INET) {
1907 1.1.1.2 christos const struct sockaddr_in *sin = (const struct sockaddr_in*)sa;
1908 1.1.1.2 christos res = evutil_inet_ntop(AF_INET, &sin->sin_addr,b,sizeof(b));
1909 1.1.1.2 christos port = ntohs(sin->sin_port);
1910 1.1.1.2 christos if (res) {
1911 1.1.1.2 christos evutil_snprintf(out, outlen, "%s:%d", b, port);
1912 1.1.1.2 christos return out;
1913 1.1.1.2 christos }
1914 1.1.1.2 christos } else if (sa->sa_family == AF_INET6) {
1915 1.1.1.2 christos const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6*)sa;
1916 1.1.1.2 christos res = evutil_inet_ntop(AF_INET6, &sin6->sin6_addr,b,sizeof(b));
1917 1.1.1.2 christos port = ntohs(sin6->sin6_port);
1918 1.1.1.2 christos if (res) {
1919 1.1.1.2 christos evutil_snprintf(out, outlen, "[%s]:%d", b, port);
1920 1.1.1.2 christos return out;
1921 1.1.1.2 christos }
1922 1.1.1.2 christos }
1923 1.1.1.2 christos
1924 1.1.1.2 christos evutil_snprintf(out, outlen, "<addr with socktype %d>",
1925 1.1.1.2 christos (int)sa->sa_family);
1926 1.1.1.2 christos return out;
1927 1.1.1.2 christos }
1928 1.1.1.2 christos
1929 1.1.1.2 christos int
1930 1.1.1.2 christos evutil_sockaddr_cmp(const struct sockaddr *sa1, const struct sockaddr *sa2,
1931 1.1.1.2 christos int include_port)
1932 1.1.1.2 christos {
1933 1.1.1.2 christos int r;
1934 1.1.1.2 christos if (0 != (r = (sa1->sa_family - sa2->sa_family)))
1935 1.1.1.2 christos return r;
1936 1.1.1.2 christos
1937 1.1.1.2 christos if (sa1->sa_family == AF_INET) {
1938 1.1.1.2 christos const struct sockaddr_in *sin1, *sin2;
1939 1.1.1.2 christos sin1 = (const struct sockaddr_in *)sa1;
1940 1.1.1.2 christos sin2 = (const struct sockaddr_in *)sa2;
1941 1.1.1.2 christos if (sin1->sin_addr.s_addr < sin2->sin_addr.s_addr)
1942 1.1.1.2 christos return -1;
1943 1.1.1.2 christos else if (sin1->sin_addr.s_addr > sin2->sin_addr.s_addr)
1944 1.1.1.2 christos return 1;
1945 1.1.1.2 christos else if (include_port &&
1946 1.1.1.2 christos (r = ((int)sin1->sin_port - (int)sin2->sin_port)))
1947 1.1.1.2 christos return r;
1948 1.1.1.2 christos else
1949 1.1.1.2 christos return 0;
1950 1.1.1.2 christos }
1951 1.1.1.2 christos #ifdef AF_INET6
1952 1.1.1.2 christos else if (sa1->sa_family == AF_INET6) {
1953 1.1.1.2 christos const struct sockaddr_in6 *sin1, *sin2;
1954 1.1.1.2 christos sin1 = (const struct sockaddr_in6 *)sa1;
1955 1.1.1.2 christos sin2 = (const struct sockaddr_in6 *)sa2;
1956 1.1.1.2 christos if ((r = memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16)))
1957 1.1.1.2 christos return r;
1958 1.1.1.2 christos else if (include_port &&
1959 1.1.1.2 christos (r = ((int)sin1->sin6_port - (int)sin2->sin6_port)))
1960 1.1.1.2 christos return r;
1961 1.1.1.2 christos else
1962 1.1.1.2 christos return 0;
1963 1.1.1.2 christos }
1964 1.1 plunky #endif
1965 1.1.1.2 christos return 1;
1966 1.1 plunky }
1967 1.1.1.2 christos
1968 1.1.1.2 christos /* Tables to implement ctypes-replacement EVUTIL_IS*() functions. Each table
1969 1.1.1.2 christos * has 256 bits to look up whether a character is in some set or not. This
1970 1.1.1.2 christos * fails on non-ASCII platforms, but so does every other place where we
1971 1.1.1.2 christos * take a char and write it onto the network.
1972 1.1.1.2 christos **/
1973 1.1.1.2 christos static const ev_uint32_t EVUTIL_ISALPHA_TABLE[8] =
1974 1.1.1.2 christos { 0, 0, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
1975 1.1.1.2 christos static const ev_uint32_t EVUTIL_ISALNUM_TABLE[8] =
1976 1.1.1.2 christos { 0, 0x3ff0000, 0x7fffffe, 0x7fffffe, 0, 0, 0, 0 };
1977 1.1.1.2 christos static const ev_uint32_t EVUTIL_ISSPACE_TABLE[8] = { 0x3e00, 0x1, 0, 0, 0, 0, 0, 0 };
1978 1.1.1.2 christos static const ev_uint32_t EVUTIL_ISXDIGIT_TABLE[8] =
1979 1.1.1.2 christos { 0, 0x3ff0000, 0x7e, 0x7e, 0, 0, 0, 0 };
1980 1.1.1.2 christos static const ev_uint32_t EVUTIL_ISDIGIT_TABLE[8] = { 0, 0x3ff0000, 0, 0, 0, 0, 0, 0 };
1981 1.1.1.2 christos static const ev_uint32_t EVUTIL_ISPRINT_TABLE[8] =
1982 1.1.1.2 christos { 0, 0xffffffff, 0xffffffff, 0x7fffffff, 0, 0, 0, 0x0 };
1983 1.1.1.2 christos static const ev_uint32_t EVUTIL_ISUPPER_TABLE[8] = { 0, 0, 0x7fffffe, 0, 0, 0, 0, 0 };
1984 1.1.1.2 christos static const ev_uint32_t EVUTIL_ISLOWER_TABLE[8] = { 0, 0, 0, 0x7fffffe, 0, 0, 0, 0 };
1985 1.1.1.2 christos /* Upper-casing and lowercasing tables to map characters to upper/lowercase
1986 1.1.1.2 christos * equivalents. */
1987 1.1.1.2 christos static const unsigned char EVUTIL_TOUPPER_TABLE[256] = {
1988 1.1.1.2 christos 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1989 1.1.1.2 christos 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
1990 1.1.1.2 christos 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
1991 1.1.1.2 christos 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
1992 1.1.1.2 christos 64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
1993 1.1.1.2 christos 80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
1994 1.1.1.2 christos 96,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
1995 1.1.1.2 christos 80,81,82,83,84,85,86,87,88,89,90,123,124,125,126,127,
1996 1.1.1.2 christos 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
1997 1.1.1.2 christos 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
1998 1.1.1.2 christos 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
1999 1.1.1.2 christos 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2000 1.1.1.2 christos 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2001 1.1.1.2 christos 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2002 1.1.1.2 christos 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2003 1.1.1.2 christos 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2004 1.1.1.2 christos };
2005 1.1.1.2 christos static const unsigned char EVUTIL_TOLOWER_TABLE[256] = {
2006 1.1.1.2 christos 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
2007 1.1.1.2 christos 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
2008 1.1.1.2 christos 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
2009 1.1.1.2 christos 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
2010 1.1.1.2 christos 64,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2011 1.1.1.2 christos 112,113,114,115,116,117,118,119,120,121,122,91,92,93,94,95,
2012 1.1.1.2 christos 96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
2013 1.1.1.2 christos 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
2014 1.1.1.2 christos 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
2015 1.1.1.2 christos 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
2016 1.1.1.2 christos 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
2017 1.1.1.2 christos 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
2018 1.1.1.2 christos 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
2019 1.1.1.2 christos 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
2020 1.1.1.2 christos 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
2021 1.1.1.2 christos 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
2022 1.1.1.2 christos };
2023 1.1.1.2 christos
2024 1.1.1.2 christos #define IMPL_CTYPE_FN(name) \
2025 1.1.1.2 christos int EVUTIL_##name(char c) { \
2026 1.1.1.2 christos ev_uint8_t u = c; \
2027 1.1.1.2 christos return !!(EVUTIL_##name##_TABLE[(u >> 5) & 7] & (1 << (u & 31))); \
2028 1.1.1.2 christos }
2029 1.1.1.2 christos IMPL_CTYPE_FN(ISALPHA)
2030 1.1.1.2 christos IMPL_CTYPE_FN(ISALNUM)
2031 1.1.1.2 christos IMPL_CTYPE_FN(ISSPACE)
2032 1.1.1.2 christos IMPL_CTYPE_FN(ISDIGIT)
2033 1.1.1.2 christos IMPL_CTYPE_FN(ISXDIGIT)
2034 1.1.1.2 christos IMPL_CTYPE_FN(ISPRINT)
2035 1.1.1.2 christos IMPL_CTYPE_FN(ISLOWER)
2036 1.1.1.2 christos IMPL_CTYPE_FN(ISUPPER)
2037 1.1.1.2 christos
2038 1.1.1.2 christos char EVUTIL_TOLOWER(char c)
2039 1.1.1.2 christos {
2040 1.1.1.2 christos return ((char)EVUTIL_TOLOWER_TABLE[(ev_uint8_t)c]);
2041 1.1.1.2 christos }
2042 1.1.1.2 christos char EVUTIL_TOUPPER(char c)
2043 1.1.1.2 christos {
2044 1.1.1.2 christos return ((char)EVUTIL_TOUPPER_TABLE[(ev_uint8_t)c]);
2045 1.1.1.2 christos }
2046 1.1.1.2 christos int
2047 1.1.1.2 christos evutil_ascii_strcasecmp(const char *s1, const char *s2)
2048 1.1.1.2 christos {
2049 1.1.1.2 christos char c1, c2;
2050 1.1.1.2 christos while (1) {
2051 1.1.1.2 christos c1 = EVUTIL_TOLOWER(*s1++);
2052 1.1.1.2 christos c2 = EVUTIL_TOLOWER(*s2++);
2053 1.1.1.2 christos if (c1 < c2)
2054 1.1.1.2 christos return -1;
2055 1.1.1.2 christos else if (c1 > c2)
2056 1.1.1.2 christos return 1;
2057 1.1.1.2 christos else if (c1 == 0)
2058 1.1.1.2 christos return 0;
2059 1.1.1.2 christos }
2060 1.1.1.2 christos }
2061 1.1.1.2 christos int evutil_ascii_strncasecmp(const char *s1, const char *s2, size_t n)
2062 1.1.1.2 christos {
2063 1.1.1.2 christos char c1, c2;
2064 1.1.1.2 christos while (n--) {
2065 1.1.1.2 christos c1 = EVUTIL_TOLOWER(*s1++);
2066 1.1.1.2 christos c2 = EVUTIL_TOLOWER(*s2++);
2067 1.1.1.2 christos if (c1 < c2)
2068 1.1.1.2 christos return -1;
2069 1.1.1.2 christos else if (c1 > c2)
2070 1.1.1.2 christos return 1;
2071 1.1.1.2 christos else if (c1 == 0)
2072 1.1.1.2 christos return 0;
2073 1.1.1.2 christos }
2074 1.1.1.2 christos return 0;
2075 1.1.1.2 christos }
2076 1.1.1.2 christos
2077 1.1.1.2 christos static int
2078 1.1.1.2 christos evutil_issetugid(void)
2079 1.1.1.2 christos {
2080 1.1.1.2 christos #ifdef _EVENT_HAVE_ISSETUGID
2081 1.1.1.2 christos return issetugid();
2082 1.1.1.2 christos #else
2083 1.1.1.2 christos
2084 1.1.1.2 christos #ifdef _EVENT_HAVE_GETEUID
2085 1.1.1.2 christos if (getuid() != geteuid())
2086 1.1.1.2 christos return 1;
2087 1.1.1.2 christos #endif
2088 1.1.1.2 christos #ifdef _EVENT_HAVE_GETEGID
2089 1.1.1.2 christos if (getgid() != getegid())
2090 1.1.1.2 christos return 1;
2091 1.1.1.2 christos #endif
2092 1.1.1.2 christos return 0;
2093 1.1.1.2 christos #endif
2094 1.1.1.2 christos }
2095 1.1.1.2 christos
2096 1.1.1.2 christos const char *
2097 1.1.1.2 christos evutil_getenv(const char *varname)
2098 1.1.1.2 christos {
2099 1.1.1.2 christos if (evutil_issetugid())
2100 1.1.1.2 christos return NULL;
2101 1.1.1.2 christos
2102 1.1.1.2 christos return getenv(varname);
2103 1.1.1.2 christos }
2104 1.1.1.2 christos
2105 1.1.1.2 christos long
2106 1.1.1.2 christos _evutil_weakrand(void)
2107 1.1.1.2 christos {
2108 1.1.1.2 christos #ifdef WIN32
2109 1.1.1.2 christos return rand();
2110 1.1.1.2 christos #else
2111 1.1.1.2 christos return random();
2112 1.1.1.2 christos #endif
2113 1.1.1.2 christos }
2114 1.1.1.2 christos
2115 1.1.1.3 spz /**
2116 1.1.1.3 spz * Volatile pointer to memset: we use this to keep the compiler from
2117 1.1.1.3 spz * eliminating our call to memset.
2118 1.1.1.3 spz */
2119 1.1.1.3 spz void * (*volatile evutil_memset_volatile_)(void *, int, size_t) = memset;
2120 1.1.1.3 spz
2121 1.1.1.3 spz void
2122 1.1.1.3 spz evutil_memclear_(void *mem, size_t len)
2123 1.1.1.3 spz {
2124 1.1.1.3 spz evutil_memset_volatile_(mem, 0, len);
2125 1.1.1.3 spz }
2126 1.1.1.3 spz
2127 1.1.1.2 christos int
2128 1.1.1.2 christos evutil_sockaddr_is_loopback(const struct sockaddr *addr)
2129 1.1.1.2 christos {
2130 1.1.1.2 christos static const char LOOPBACK_S6[16] =
2131 1.1.1.2 christos "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1";
2132 1.1.1.2 christos if (addr->sa_family == AF_INET) {
2133 1.1.1.2 christos struct sockaddr_in *sin = (struct sockaddr_in *)addr;
2134 1.1.1.2 christos return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
2135 1.1.1.2 christos } else if (addr->sa_family == AF_INET6) {
2136 1.1.1.2 christos struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
2137 1.1.1.2 christos return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
2138 1.1.1.2 christos }
2139 1.1.1.2 christos return 0;
2140 1.1.1.2 christos }
2141 1.1.1.2 christos
2142 1.1.1.2 christos #define MAX_SECONDS_IN_MSEC_LONG \
2143 1.1.1.2 christos (((LONG_MAX) - 999) / 1000)
2144 1.1.1.2 christos
2145 1.1.1.2 christos long
2146 1.1.1.2 christos evutil_tv_to_msec(const struct timeval *tv)
2147 1.1.1.2 christos {
2148 1.1.1.2 christos if (tv->tv_usec > 1000000 || tv->tv_sec > MAX_SECONDS_IN_MSEC_LONG)
2149 1.1.1.2 christos return -1;
2150 1.1.1.2 christos
2151 1.1.1.2 christos return (tv->tv_sec * 1000) + ((tv->tv_usec + 999) / 1000);
2152 1.1.1.2 christos }
2153 1.1.1.2 christos
2154 1.1.1.2 christos int
2155 1.1.1.2 christos evutil_hex_char_to_int(char c)
2156 1.1.1.2 christos {
2157 1.1.1.2 christos switch(c)
2158 1.1.1.2 christos {
2159 1.1.1.2 christos case '0': return 0;
2160 1.1.1.2 christos case '1': return 1;
2161 1.1.1.2 christos case '2': return 2;
2162 1.1.1.2 christos case '3': return 3;
2163 1.1.1.2 christos case '4': return 4;
2164 1.1.1.2 christos case '5': return 5;
2165 1.1.1.2 christos case '6': return 6;
2166 1.1.1.2 christos case '7': return 7;
2167 1.1.1.2 christos case '8': return 8;
2168 1.1.1.2 christos case '9': return 9;
2169 1.1.1.2 christos case 'A': case 'a': return 10;
2170 1.1.1.2 christos case 'B': case 'b': return 11;
2171 1.1.1.2 christos case 'C': case 'c': return 12;
2172 1.1.1.2 christos case 'D': case 'd': return 13;
2173 1.1.1.2 christos case 'E': case 'e': return 14;
2174 1.1.1.2 christos case 'F': case 'f': return 15;
2175 1.1.1.2 christos }
2176 1.1.1.2 christos return -1;
2177 1.1.1.2 christos }
2178 1.1.1.2 christos
2179 1.1.1.2 christos #ifdef WIN32
2180 1.1.1.2 christos HANDLE
2181 1.1.1.2 christos evutil_load_windows_system_library(const TCHAR *library_name)
2182 1.1.1.2 christos {
2183 1.1.1.2 christos TCHAR path[MAX_PATH];
2184 1.1.1.2 christos unsigned n;
2185 1.1.1.2 christos n = GetSystemDirectory(path, MAX_PATH);
2186 1.1.1.2 christos if (n == 0 || n + _tcslen(library_name) + 2 >= MAX_PATH)
2187 1.1.1.2 christos return 0;
2188 1.1.1.2 christos _tcscat(path, TEXT("\\"));
2189 1.1.1.2 christos _tcscat(path, library_name);
2190 1.1.1.2 christos return LoadLibrary(path);
2191 1.1.1.2 christos }
2192 1.1.1.2 christos #endif
2193 1.1.1.2 christos
2194