Line data Source code
1 : /* Copyright (c) 2003-2004, Roger Dingledine
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : /**
7 : * \file socket.c
8 : * \brief Compatibility and utility functions for working with network
9 : * sockets.
10 : **/
11 :
12 : #include "lib/net/socket.h"
13 : #include "lib/net/socketpair.h"
14 : #include "lib/net/address.h"
15 : #include "lib/cc/compat_compiler.h"
16 : #include "lib/err/torerr.h"
17 : #include "lib/lock/compat_mutex.h"
18 : #include "lib/log/log.h"
19 : #include "lib/log/util_bug.h"
20 :
21 : #ifdef _WIN32
22 : #include <winsock2.h>
23 : #include <windows.h>
24 : #endif
25 : #ifdef HAVE_UNISTD_H
26 : #include <unistd.h>
27 : #endif
28 : #ifdef HAVE_FCNTL_H
29 : #include <fcntl.h>
30 : #endif
31 : #include <stddef.h>
32 : #include <string.h>
33 : #ifdef __FreeBSD__
34 : #include <sys/sysctl.h>
35 : #endif
36 :
37 : /** Called before we make any calls to network-related functions.
38 : * (Some operating systems require their network libraries to be
39 : * initialized.) */
40 : int
41 5560 : network_init(void)
42 : {
43 : #ifdef _WIN32
44 : /* This silly exercise is necessary before windows will allow
45 : * gethostbyname to work. */
46 : WSADATA WSAData;
47 : int r;
48 : r = WSAStartup(0x101,&WSAData);
49 : if (r) {
50 : log_warn(LD_NET,"Error initializing windows network layer: code was %d",r);
51 : return -1;
52 : }
53 : if (sizeof(SOCKET) != sizeof(tor_socket_t)) {
54 : log_warn(LD_BUG,"The tor_socket_t type does not match SOCKET in size; Tor "
55 : "might not work. (Sizes are %d and %d respectively.)",
56 : (int)sizeof(tor_socket_t), (int)sizeof(SOCKET));
57 : }
58 : /* WSAData.iMaxSockets might show the max sockets we're allowed to use.
59 : * We might use it to complain if we're trying to be a server but have
60 : * too few sockets available. */
61 : #endif /* defined(_WIN32) */
62 5560 : return 0;
63 : }
64 :
65 : /**
66 : * Warn the user if any system network parameters should be changed.
67 : */
68 : void
69 558 : check_network_configuration(bool server_mode)
70 : {
71 : #ifdef __FreeBSD__
72 : if (server_mode) {
73 : int random_id_state;
74 : size_t state_size = sizeof(random_id_state);
75 :
76 : if (sysctlbyname("net.inet.ip.random_id", &random_id_state,
77 : &state_size, NULL, 0)) {
78 : log_warn(LD_CONFIG,
79 : "Failed to figure out if IP ids are randomized.");
80 : } else if (random_id_state == 0) {
81 : log_warn(LD_CONFIG, "Looks like IP ids are not randomized. "
82 : "Please consider setting the net.inet.ip.random_id sysctl, "
83 : "so your relay makes it harder to figure out how busy it is.");
84 : }
85 : }
86 : #else /* !defined(__FreeBSD__) */
87 558 : (void) server_mode;
88 : #endif /* defined(__FreeBSD__) */
89 558 : }
90 :
91 : /* When set_max_file_sockets() is called, update this with the max file
92 : * descriptor value so we can use it to check the limit when opening a new
93 : * socket. Default value is what Debian sets as the default hard limit. */
94 : static int max_sockets = 1024;
95 :
96 : /** Return the maximum number of allowed sockets. */
97 : int
98 1 : get_max_sockets(void)
99 : {
100 1 : return max_sockets;
101 : }
102 :
103 : /** Set the maximum number of allowed sockets to <b>n</b> */
104 : void
105 8 : set_max_sockets(int n)
106 : {
107 8 : max_sockets = n;
108 8 : }
109 :
110 : #undef DEBUG_SOCKET_COUNTING
111 : #ifdef DEBUG_SOCKET_COUNTING
112 : #include "lib/container/bitarray.h"
113 :
114 : /** A bitarray of all fds that should be passed to tor_socket_close(). Only
115 : * used if DEBUG_SOCKET_COUNTING is defined. */
116 : static bitarray_t *open_sockets = NULL;
117 : /** The size of <b>open_sockets</b>, in bits. */
118 : static int max_socket = -1;
119 : #endif /* defined(DEBUG_SOCKET_COUNTING) */
120 :
121 : /** Count of number of sockets currently open. (Undercounts sockets opened by
122 : * eventdns and libevent.) */
123 : static int n_sockets_open = 0;
124 :
125 : /** Mutex to protect open_sockets, max_socket, and n_sockets_open. */
126 : static tor_mutex_t *socket_accounting_mutex = NULL;
127 :
128 : /** Helper: acquire the socket accounting lock. */
129 : static inline void
130 103 : socket_accounting_lock(void)
131 : {
132 103 : if (PREDICT_UNLIKELY(!socket_accounting_mutex))
133 19 : socket_accounting_mutex = tor_mutex_new();
134 103 : tor_mutex_acquire(socket_accounting_mutex);
135 103 : }
136 :
137 : /** Helper: release the socket accounting lock. */
138 : static inline void
139 103 : socket_accounting_unlock(void)
140 : {
141 103 : tor_mutex_release(socket_accounting_mutex);
142 103 : }
143 :
144 : /** As close(), but guaranteed to work for sockets across platforms (including
145 : * Windows, where close()ing a socket doesn't work. Returns 0 on success and
146 : * the socket error code on failure. */
147 : int
148 34 : tor_close_socket_simple(tor_socket_t s)
149 : {
150 34 : int r = 0;
151 :
152 : /* On Windows, you have to call close() on fds returned by open(),
153 : * and closesocket() on fds returned by socket(). On Unix, everything
154 : * gets close()'d. We abstract this difference by always using
155 : * tor_close_socket to close sockets, and always using close() on
156 : * files.
157 : */
158 : #if defined(_WIN32)
159 : r = closesocket(s);
160 : #else
161 34 : r = close(s);
162 : #endif
163 :
164 34 : if (r != 0) {
165 5 : int err = tor_socket_errno(-1);
166 5 : log_info(LD_NET, "Close returned an error: %s", tor_socket_strerror(err));
167 5 : return err;
168 : }
169 :
170 : return r;
171 : }
172 :
173 : /** @{ */
174 : #ifdef DEBUG_SOCKET_COUNTING
175 : /** Helper: if DEBUG_SOCKET_COUNTING is enabled, remember that <b>s</b> is
176 : * now an open socket. */
177 : static inline void
178 : mark_socket_open(tor_socket_t s)
179 : {
180 : /* XXXX This bitarray business will NOT work on windows: sockets aren't
181 : small ints there. */
182 : if (s > max_socket) {
183 : if (max_socket == -1) {
184 : open_sockets = bitarray_init_zero(s+128);
185 : max_socket = s+128;
186 : } else {
187 : open_sockets = bitarray_expand(open_sockets, max_socket, s+128);
188 : max_socket = s+128;
189 : }
190 : }
191 : if (bitarray_is_set(open_sockets, s)) {
192 : log_warn(LD_BUG, "I thought that %d was already open, but socket() just "
193 : "gave it to me!", s);
194 : }
195 : bitarray_set(open_sockets, s);
196 : }
197 : static inline void
198 : mark_socket_closed(tor_socket_t s)
199 : {
200 : if (s > max_socket || ! bitarray_is_set(open_sockets, s)) {
201 : log_warn(LD_BUG, "Closing a socket (%d) that wasn't returned by tor_open_"
202 : "socket(), or that was already closed or something.", s);
203 : } else {
204 : tor_assert(open_sockets && s <= max_socket);
205 : bitarray_clear(open_sockets, s);
206 : }
207 : }
208 : #else /* !defined(DEBUG_SOCKET_COUNTING) */
209 : #define mark_socket_open(s) ((void) (s))
210 : #define mark_socket_closed(s) ((void) (s))
211 : #endif /* defined(DEBUG_SOCKET_COUNTING) */
212 : /** @} */
213 :
214 : /** As tor_close_socket_simple(), but keeps track of the number
215 : * of open sockets. Returns 0 on success, -1 on failure. */
216 32 : MOCK_IMPL(int,
217 : tor_close_socket,(tor_socket_t s))
218 : {
219 32 : int r = tor_close_socket_simple(s);
220 :
221 32 : socket_accounting_lock();
222 32 : mark_socket_closed(s);
223 32 : if (r == 0) {
224 27 : --n_sockets_open;
225 : } else {
226 : #ifdef _WIN32
227 : if (r != WSAENOTSOCK)
228 : --n_sockets_open;
229 : #else
230 5 : if (r != EBADF)
231 : --n_sockets_open; // LCOV_EXCL_LINE -- EIO and EINTR too hard to force.
232 : #endif /* defined(_WIN32) */
233 : r = -1;
234 : }
235 :
236 32 : tor_assert_nonfatal(n_sockets_open >= 0);
237 32 : socket_accounting_unlock();
238 32 : return r;
239 : }
240 :
241 : /** As socket(), but counts the number of open sockets. */
242 19 : MOCK_IMPL(tor_socket_t,
243 : tor_open_socket,(int domain, int type, int protocol))
244 : {
245 19 : return tor_open_socket_with_extensions(domain, type, protocol, 1, 0);
246 : }
247 :
248 : /** Mockable wrapper for connect(). */
249 17 : MOCK_IMPL(tor_socket_t,
250 : tor_connect_socket,(tor_socket_t sock, const struct sockaddr *address,
251 : socklen_t address_len))
252 : {
253 17 : return connect(sock,address,address_len);
254 : }
255 :
256 : /** As socket(), but creates a nonblocking socket and
257 : * counts the number of open sockets. */
258 : tor_socket_t
259 2 : tor_open_socket_nonblocking(int domain, int type, int protocol)
260 : {
261 2 : return tor_open_socket_with_extensions(domain, type, protocol, 1, 1);
262 : }
263 :
264 : /** As socket(), but counts the number of open sockets and handles
265 : * socket creation with either of SOCK_CLOEXEC and SOCK_NONBLOCK specified.
266 : * <b>cloexec</b> and <b>nonblock</b> should be either 0 or 1 to indicate
267 : * if the corresponding extension should be used.*/
268 : tor_socket_t
269 25 : tor_open_socket_with_extensions(int domain, int type, int protocol,
270 : int cloexec, int nonblock)
271 : {
272 25 : tor_socket_t s;
273 :
274 : /* We are about to create a new file descriptor so make sure we have
275 : * enough of them. */
276 25 : if (get_n_open_sockets() >= max_sockets - 1) {
277 : #ifdef _WIN32
278 : WSASetLastError(WSAEMFILE);
279 : #else
280 0 : errno = EMFILE;
281 : #endif
282 0 : return TOR_INVALID_SOCKET;
283 : }
284 :
285 : #if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
286 25 : int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
287 25 : (nonblock ? SOCK_NONBLOCK : 0);
288 25 : s = socket(domain, type|ext_flags, protocol);
289 25 : if (SOCKET_OK(s))
290 25 : goto socket_ok;
291 : /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
292 : * even though we were built on a system with SOCK_CLOEXEC and SOCK_NONBLOCK
293 : * support, we are running on one without. */
294 0 : if (errno != EINVAL)
295 : return s;
296 : #endif /* defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) */
297 :
298 0 : s = socket(domain, type, protocol);
299 0 : if (! SOCKET_OK(s))
300 : return s;
301 :
302 : #if defined(FD_CLOEXEC)
303 0 : if (cloexec) {
304 0 : if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
305 0 : log_warn(LD_FS,"Couldn't set FD_CLOEXEC: %s", strerror(errno));
306 0 : tor_close_socket_simple(s);
307 0 : return TOR_INVALID_SOCKET;
308 : }
309 : }
310 : #else /* !defined(FD_CLOEXEC) */
311 : (void)cloexec;
312 : #endif /* defined(FD_CLOEXEC) */
313 :
314 0 : if (nonblock) {
315 0 : if (set_socket_nonblocking(s) == -1) {
316 0 : tor_close_socket_simple(s);
317 0 : return TOR_INVALID_SOCKET;
318 : }
319 : }
320 :
321 0 : goto socket_ok; /* So that socket_ok will not be unused. */
322 :
323 25 : socket_ok:
324 25 : tor_take_socket_ownership(s);
325 25 : return s;
326 : }
327 :
328 : /**
329 : * For socket accounting: remember that we are the owner of the socket
330 : * <b>s</b>. This will prevent us from overallocating sockets, and prevent us
331 : * from asserting later when we close the socket <b>s</b>.
332 : */
333 : void
334 25 : tor_take_socket_ownership(tor_socket_t s)
335 : {
336 25 : socket_accounting_lock();
337 25 : ++n_sockets_open;
338 25 : mark_socket_open(s);
339 25 : socket_accounting_unlock();
340 25 : }
341 :
342 : /**
343 : * For socket accounting: declare that we are no longer the owner of the
344 : * socket <b>s</b>. This will prevent us from overallocating sockets, and
345 : * prevent us from asserting later when we close the socket <b>s</b>.
346 : */
347 : void
348 0 : tor_release_socket_ownership(tor_socket_t s)
349 : {
350 0 : socket_accounting_lock();
351 0 : --n_sockets_open;
352 0 : mark_socket_closed(s);
353 0 : socket_accounting_unlock();
354 0 : }
355 :
356 : /** As accept(), but counts the number of open sockets. */
357 : tor_socket_t
358 0 : tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
359 : {
360 0 : return tor_accept_socket_with_extensions(sockfd, addr, len, 1, 0);
361 : }
362 :
363 : /** As accept(), but returns a nonblocking socket and
364 : * counts the number of open sockets. */
365 : tor_socket_t
366 0 : tor_accept_socket_nonblocking(tor_socket_t sockfd, struct sockaddr *addr,
367 : socklen_t *len)
368 : {
369 0 : return tor_accept_socket_with_extensions(sockfd, addr, len, 1, 1);
370 : }
371 :
372 : /** As accept(), but counts the number of open sockets and handles
373 : * socket creation with either of SOCK_CLOEXEC and SOCK_NONBLOCK specified.
374 : * <b>cloexec</b> and <b>nonblock</b> should be either 0 or 1 to indicate
375 : * if the corresponding extension should be used.*/
376 : tor_socket_t
377 0 : tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr,
378 : socklen_t *len, int cloexec, int nonblock)
379 : {
380 0 : tor_socket_t s;
381 :
382 : /* We are about to create a new file descriptor so make sure we have
383 : * enough of them. */
384 0 : if (get_n_open_sockets() >= max_sockets - 1) {
385 : #ifdef _WIN32
386 : WSASetLastError(WSAEMFILE);
387 : #else
388 0 : errno = EMFILE;
389 : #endif
390 0 : return TOR_INVALID_SOCKET;
391 : }
392 :
393 : #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) \
394 : && defined(SOCK_NONBLOCK)
395 0 : int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
396 0 : (nonblock ? SOCK_NONBLOCK : 0);
397 0 : s = accept4(sockfd, addr, len, ext_flags);
398 0 : if (SOCKET_OK(s))
399 0 : goto socket_ok;
400 : /* If we got an error, see if it is ENOSYS. ENOSYS indicates that,
401 : * even though we were built on a system with accept4 support, we
402 : * are running on one without. Also, check for EINVAL, which indicates that
403 : * we are missing SOCK_CLOEXEC/SOCK_NONBLOCK support. */
404 0 : if (errno != EINVAL && errno != ENOSYS)
405 : return s;
406 : #endif /* defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) ... */
407 :
408 0 : s = accept(sockfd, addr, len);
409 0 : if (!SOCKET_OK(s))
410 : return s;
411 :
412 : #if defined(FD_CLOEXEC)
413 0 : if (cloexec) {
414 0 : if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
415 0 : log_warn(LD_NET, "Couldn't set FD_CLOEXEC: %s", strerror(errno));
416 0 : tor_close_socket_simple(s);
417 0 : return TOR_INVALID_SOCKET;
418 : }
419 : }
420 : #else /* !defined(FD_CLOEXEC) */
421 : (void)cloexec;
422 : #endif /* defined(FD_CLOEXEC) */
423 :
424 0 : if (nonblock) {
425 0 : if (set_socket_nonblocking(s) == -1) {
426 0 : tor_close_socket_simple(s);
427 0 : return TOR_INVALID_SOCKET;
428 : }
429 : }
430 :
431 0 : goto socket_ok; /* So that socket_ok will not be unused. */
432 :
433 0 : socket_ok:
434 0 : tor_take_socket_ownership(s);
435 0 : return s;
436 : }
437 :
438 : /** Return the number of sockets we currently have opened. */
439 : int
440 44 : get_n_open_sockets(void)
441 : {
442 44 : int n;
443 44 : socket_accounting_lock();
444 44 : n = n_sockets_open;
445 44 : socket_accounting_unlock();
446 44 : return n;
447 : }
448 :
449 : /**
450 : * Allocate a pair of connected sockets. (Like socketpair(family,
451 : * type,protocol,fd), but works on systems that don't have
452 : * socketpair.)
453 : *
454 : * Currently, only (AF_UNIX, SOCK_STREAM, 0) sockets are supported.
455 : *
456 : * Note that on systems without socketpair, this call will fail if
457 : * localhost is inaccessible (for example, if the networking
458 : * stack is down). And even if it succeeds, the socket pair will not
459 : * be able to read while localhost is down later (the socket pair may
460 : * even close, depending on OS-specific timeouts). The socket pair
461 : * should work on IPv4-only, IPv6-only, and dual-stack systems, as long
462 : * as they have the standard localhost addresses.
463 : *
464 : * Returns 0 on success and -errno on failure; do not rely on the value
465 : * of errno or WSAGetLastError().
466 : **/
467 : /* It would be nicer just to set errno, but that won't work for windows. */
468 : int
469 2 : tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
470 : {
471 2 : int r;
472 : //don't use win32 socketpairs (they are always bad)
473 : #if defined(HAVE_SOCKETPAIR) && !defined(_WIN32)
474 :
475 : #ifdef SOCK_CLOEXEC
476 2 : r = socketpair(family, type|SOCK_CLOEXEC, protocol, fd);
477 2 : if (r == 0)
478 2 : goto sockets_ok;
479 : /* If we got an error, see if it is EINVAL. EINVAL might indicate that,
480 : * even though we were built on a system with SOCK_CLOEXEC support, we
481 : * are running on one without. */
482 0 : if (errno != EINVAL)
483 0 : return -errno;
484 : #endif /* defined(SOCK_CLOEXEC) */
485 :
486 0 : r = socketpair(family, type, protocol, fd);
487 0 : if (r < 0)
488 0 : return -errno;
489 : #else /* !(defined(HAVE_SOCKETPAIR) && !defined(_WIN32)) */
490 : r = tor_ersatz_socketpair(family, type, protocol, fd);
491 : if (r < 0)
492 : return -r;
493 : #endif /* defined(HAVE_SOCKETPAIR) && !defined(_WIN32) */
494 :
495 : #if defined(FD_CLOEXEC)
496 0 : if (SOCKET_OK(fd[0])) {
497 0 : r = fcntl(fd[0], F_SETFD, FD_CLOEXEC);
498 0 : if (r == -1) {
499 0 : close(fd[0]);
500 0 : close(fd[1]);
501 0 : return -errno;
502 : }
503 : }
504 0 : if (SOCKET_OK(fd[1])) {
505 0 : r = fcntl(fd[1], F_SETFD, FD_CLOEXEC);
506 0 : if (r == -1) {
507 0 : close(fd[0]);
508 0 : close(fd[1]);
509 0 : return -errno;
510 : }
511 : }
512 : #endif /* defined(FD_CLOEXEC) */
513 0 : goto sockets_ok; /* So that sockets_ok will not be unused. */
514 :
515 2 : sockets_ok:
516 2 : socket_accounting_lock();
517 2 : if (SOCKET_OK(fd[0])) {
518 2 : ++n_sockets_open;
519 2 : mark_socket_open(fd[0]);
520 : }
521 2 : if (SOCKET_OK(fd[1])) {
522 2 : ++n_sockets_open;
523 2 : mark_socket_open(fd[1]);
524 : }
525 2 : socket_accounting_unlock();
526 :
527 2 : return 0;
528 : }
529 :
530 : /** Mockable wrapper for getsockname(). */
531 9 : MOCK_IMPL(int,
532 : tor_getsockname,(tor_socket_t sock, struct sockaddr *address,
533 : socklen_t *address_len))
534 : {
535 9 : return getsockname(sock, address, address_len);
536 : }
537 :
538 : /**
539 : * Find the local address associated with the socket <b>sock</b>, and
540 : * place it in *<b>addr_out</b>. Return 0 on success, -1 on failure.
541 : *
542 : * (As tor_getsockname, but instead places the result in a tor_addr_t.) */
543 : int
544 11 : tor_addr_from_getsockname(struct tor_addr_t *addr_out, tor_socket_t sock)
545 : {
546 11 : struct sockaddr_storage ss;
547 11 : socklen_t ss_len = sizeof(ss);
548 11 : memset(&ss, 0, sizeof(ss));
549 :
550 11 : if (tor_getsockname(sock, (struct sockaddr *) &ss, &ss_len) < 0)
551 : return -1;
552 :
553 11 : return tor_addr_from_sockaddr(addr_out, (struct sockaddr *)&ss, NULL);
554 : }
555 :
556 : /** Turn <b>socket</b> into a nonblocking socket. Return 0 on success, -1
557 : * on failure.
558 : */
559 : int
560 5 : set_socket_nonblocking(tor_socket_t sock)
561 : {
562 : #if defined(_WIN32)
563 : unsigned long nonblocking = 1;
564 : ioctlsocket(sock, FIONBIO, (unsigned long*) &nonblocking);
565 : #else
566 5 : int flags;
567 :
568 5 : flags = fcntl(sock, F_GETFL, 0);
569 5 : if (flags == -1) {
570 0 : log_warn(LD_NET, "Couldn't get file status flags: %s", strerror(errno));
571 0 : return -1;
572 : }
573 5 : flags |= O_NONBLOCK;
574 5 : if (fcntl(sock, F_SETFL, flags) == -1) {
575 0 : log_warn(LD_NET, "Couldn't set file status flags: %s", strerror(errno));
576 0 : return -1;
577 : }
578 : #endif /* defined(_WIN32) */
579 :
580 : return 0;
581 : }
582 :
583 : /** Read from <b>sock</b> to <b>buf</b>, until we get <b>count</b> bytes or
584 : * reach the end of the file. Return the number of bytes read, or -1 on
585 : * error. Only use if fd is a blocking fd. */
586 : ssize_t
587 0 : read_all_from_socket(tor_socket_t sock, char *buf, size_t count)
588 : {
589 0 : size_t numread = 0;
590 0 : ssize_t result;
591 :
592 0 : if (count > SIZE_T_CEILING || count > SSIZE_MAX) {
593 0 : errno = EINVAL;
594 0 : return -1;
595 : }
596 :
597 0 : while (numread < count) {
598 0 : result = tor_socket_recv(sock, buf+numread, count-numread, 0);
599 0 : if (result<0)
600 : return -1;
601 0 : else if (result == 0)
602 : break;
603 0 : numread += result;
604 : }
605 0 : return (ssize_t)numread;
606 : }
607 :
608 : /** Write <b>count</b> bytes from <b>buf</b> to <b>sock</b>. Return the number
609 : * of bytes written, or -1 on error. Only use if fd is a blocking fd. */
610 : ssize_t
611 0 : write_all_to_socket(tor_socket_t fd, const char *buf, size_t count)
612 : {
613 0 : size_t written = 0;
614 0 : ssize_t result;
615 0 : raw_assert(count < SSIZE_MAX);
616 :
617 0 : while (written != count) {
618 0 : result = tor_socket_send(fd, buf+written, count-written, 0);
619 0 : if (result<0)
620 : return -1;
621 0 : written += result;
622 : }
623 0 : return (ssize_t)count;
624 : }
625 :
626 : /**
627 : * On Windows, WSAEWOULDBLOCK is not always correct: when you see it,
628 : * you need to ask the socket for its actual errno. Also, you need to
629 : * get your errors from WSAGetLastError, not errno. (If you supply a
630 : * socket of -1, we check WSAGetLastError, but don't correct
631 : * WSAEWOULDBLOCKs.)
632 : *
633 : * The upshot of all of this is that when a socket call fails, you
634 : * should call tor_socket_errno <em>at most once</em> on the failing
635 : * socket to get the error.
636 : */
637 : #if defined(_WIN32)
638 : int
639 : tor_socket_errno(tor_socket_t sock)
640 : {
641 : int optval, optvallen=sizeof(optval);
642 : int err = WSAGetLastError();
643 : if (err == WSAEWOULDBLOCK && SOCKET_OK(sock)) {
644 : if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)&optval, &optvallen))
645 : return err;
646 : if (optval)
647 : return optval;
648 : }
649 : return err;
650 : }
651 : #endif /* defined(_WIN32) */
652 :
653 : #if defined(_WIN32)
654 : #define E(code, s) { code, (s " [" #code " ]") }
655 : struct { int code; const char *msg; } windows_socket_errors[] = {
656 : E(WSAEINTR, "Interrupted function call"),
657 : E(WSAEACCES, "Permission denied"),
658 : E(WSAEFAULT, "Bad address"),
659 : E(WSAEINVAL, "Invalid argument"),
660 : E(WSAEMFILE, "Too many open files"),
661 : E(WSAEWOULDBLOCK, "Resource temporarily unavailable"),
662 : E(WSAEINPROGRESS, "Operation now in progress"),
663 : E(WSAEALREADY, "Operation already in progress"),
664 : E(WSAENOTSOCK, "Socket operation on nonsocket"),
665 : E(WSAEDESTADDRREQ, "Destination address required"),
666 : E(WSAEMSGSIZE, "Message too long"),
667 : E(WSAEPROTOTYPE, "Protocol wrong for socket"),
668 : E(WSAENOPROTOOPT, "Bad protocol option"),
669 : E(WSAEPROTONOSUPPORT, "Protocol not supported"),
670 : E(WSAESOCKTNOSUPPORT, "Socket type not supported"),
671 : /* What's the difference between NOTSUPP and NOSUPPORT? :) */
672 : E(WSAEOPNOTSUPP, "Operation not supported"),
673 : E(WSAEPFNOSUPPORT, "Protocol family not supported"),
674 : E(WSAEAFNOSUPPORT, "Address family not supported by protocol family"),
675 : E(WSAEADDRINUSE, "Address already in use"),
676 : E(WSAEADDRNOTAVAIL, "Cannot assign requested address"),
677 : E(WSAENETDOWN, "Network is down"),
678 : E(WSAENETUNREACH, "Network is unreachable"),
679 : E(WSAENETRESET, "Network dropped connection on reset"),
680 : E(WSAECONNABORTED, "Software caused connection abort"),
681 : E(WSAECONNRESET, "Connection reset by peer"),
682 : E(WSAENOBUFS, "No buffer space available"),
683 : E(WSAEISCONN, "Socket is already connected"),
684 : E(WSAENOTCONN, "Socket is not connected"),
685 : E(WSAESHUTDOWN, "Cannot send after socket shutdown"),
686 : E(WSAETIMEDOUT, "Connection timed out"),
687 : E(WSAECONNREFUSED, "Connection refused"),
688 : E(WSAEHOSTDOWN, "Host is down"),
689 : E(WSAEHOSTUNREACH, "No route to host"),
690 : E(WSAEPROCLIM, "Too many processes"),
691 : /* Yes, some of these start with WSA, not WSAE. No, I don't know why. */
692 : E(WSASYSNOTREADY, "Network subsystem is unavailable"),
693 : E(WSAVERNOTSUPPORTED, "Winsock.dll out of range"),
694 : E(WSANOTINITIALISED, "Successful WSAStartup not yet performed"),
695 : E(WSAEDISCON, "Graceful shutdown now in progress"),
696 : #ifdef WSATYPE_NOT_FOUND
697 : E(WSATYPE_NOT_FOUND, "Class type not found"),
698 : #endif
699 : E(WSAHOST_NOT_FOUND, "Host not found"),
700 : E(WSATRY_AGAIN, "Nonauthoritative host not found"),
701 : E(WSANO_RECOVERY, "This is a nonrecoverable error"),
702 : E(WSANO_DATA, "Valid name, no data record of requested type)"),
703 :
704 : /* There are some more error codes whose numeric values are marked
705 : * <b>OS dependent</b>. They start with WSA_, apparently for the same
706 : * reason that practitioners of some craft traditions deliberately
707 : * introduce imperfections into their baskets and rugs "to allow the
708 : * evil spirits to escape." If we catch them, then our binaries
709 : * might not report consistent results across versions of Windows.
710 : * Thus, I'm going to let them all fall through.
711 : */
712 : { -1, NULL },
713 : };
714 : /** There does not seem to be a strerror equivalent for Winsock errors.
715 : * Naturally, we have to roll our own.
716 : */
717 : const char *
718 : tor_socket_strerror(int e)
719 : {
720 : int i;
721 : for (i=0; windows_socket_errors[i].code >= 0; ++i) {
722 : if (e == windows_socket_errors[i].code)
723 : return windows_socket_errors[i].msg;
724 : }
725 : return strerror(e);
726 : }
727 : #endif /* defined(_WIN32) */
|