34 #include <sys/sysctl.h>
48 r = WSAStartup(0x101,&WSAData);
50 log_warn(
LD_NET,
"Error initializing windows network layer: code was %d",r);
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.)",
74 size_t state_size =
sizeof(random_id_state);
76 if (sysctlbyname(
"net.inet.ip.random_id", &random_id_state,
77 &state_size, NULL, 0)) {
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.");
94 static int max_sockets = 1024;
110 #undef DEBUG_SOCKET_COUNTING
111 #ifdef DEBUG_SOCKET_COUNTING
118 static int max_socket = -1;
165 int err = tor_socket_errno(-1);
166 log_info(
LD_NET,
"Close returned an error: %s", tor_socket_strerror(err));
174 #ifdef DEBUG_SOCKET_COUNTING
182 if (s > max_socket) {
183 if (max_socket == -1) {
192 log_warn(
LD_BUG,
"I thought that %d was already open, but socket() just "
193 "gave it to me!", 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);
209 #define mark_socket_open(s) ((void) (s))
210 #define mark_socket_closed(s) ((void) (s))
222 mark_socket_closed(s);
227 if (r != WSAENOTSOCK)
251 socklen_t address_len))
253 return connect(sock,address,address_len);
270 int cloexec,
int nonblock)
278 WSASetLastError(WSAEMFILE);
285 #if defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
286 int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
287 (nonblock ? SOCK_NONBLOCK : 0);
288 s = socket(domain, type|ext_flags, protocol);
298 s = socket(domain, type, protocol);
302 #if defined(FD_CLOEXEC)
304 if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
305 log_warn(
LD_FS,
"Couldn't set FD_CLOEXEC: %s", strerror(errno));
352 mark_socket_closed(s);
378 socklen_t *len,
int cloexec,
int nonblock)
386 WSASetLastError(WSAEMFILE);
393 #if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) \
394 && defined(SOCK_NONBLOCK)
395 int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
396 (nonblock ? SOCK_NONBLOCK : 0);
397 s = accept4(sockfd, addr, len, ext_flags);
404 if (errno != EINVAL && errno != ENOSYS)
408 s = accept(sockfd, addr, len);
412 #if defined(FD_CLOEXEC)
414 if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) {
415 log_warn(
LD_NET,
"Couldn't set FD_CLOEXEC: %s", strerror(errno));
473 #if defined(HAVE_SOCKETPAIR) && !defined(_WIN32)
476 r = socketpair(family, type|SOCK_CLOEXEC, protocol, fd);
486 r = socketpair(family, type, protocol, fd);
490 r = tor_ersatz_socketpair(family, type, protocol, fd);
495 #if defined(FD_CLOEXEC)
497 r = fcntl(fd[0], F_SETFD, FD_CLOEXEC);
505 r = fcntl(fd[1], F_SETFD, FD_CLOEXEC);
519 mark_socket_open(fd[0]);
523 mark_socket_open(fd[1]);
533 socklen_t *address_len))
535 return getsockname(sock, address, address_len);
546 struct sockaddr_storage ss;
547 socklen_t ss_len =
sizeof(ss);
548 memset(&ss, 0,
sizeof(ss));
563 unsigned long nonblocking = 1;
564 ioctlsocket(sock, FIONBIO, (
unsigned long*) &nonblocking);
568 flags = fcntl(sock, F_GETFL, 0);
570 log_warn(
LD_NET,
"Couldn't get file status flags: %s", strerror(errno));
574 if (fcntl(sock, F_SETFL, flags) == -1) {
575 log_warn(
LD_NET,
"Couldn't set file status flags: %s", strerror(errno));
597 while (numread < count) {
598 result = tor_socket_recv(sock, buf+numread, count-numread, 0);
601 else if (result == 0)
605 return (ssize_t)numread;
615 raw_assert(count < SSIZE_MAX);
617 while (written != count) {
618 result = tor_socket_send(fd, buf+written, count-written, 0);
623 return (ssize_t)count;
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))
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"),
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"),
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"),
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)"),
718 tor_socket_strerror(
int e)
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;
int tor_addr_from_sockaddr(tor_addr_t *a, const struct sockaddr *sa, uint16_t *port_out)
Implements a variable-sized (but non-resizeable) bit-array.
static void bitarray_set(bitarray_t *b, int bit)
static unsigned int bitarray_is_set(bitarray_t *b, int bit)
static void bitarray_clear(bitarray_t *b, int bit)
static bitarray_t * bitarray_expand(bitarray_t *ba, unsigned int n_bits_old, unsigned int n_bits_new)
static bitarray_t * bitarray_init_zero(unsigned int n_bits)
Utility macros to handle different features and behavior in different compilers.
tor_mutex_t * tor_mutex_new(void)
Header for compat_mutex.c.
void tor_mutex_release(tor_mutex_t *m)
void tor_mutex_acquire(tor_mutex_t *m)
#define TOR_INVALID_SOCKET
int server_mode(const or_options_t *options)
tor_socket_t tor_accept_socket(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
int tor_close_socket_simple(tor_socket_t s)
tor_socket_t tor_accept_socket_nonblocking(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len)
int get_max_sockets(void)
int tor_close_socket(tor_socket_t s)
static void socket_accounting_lock(void)
ssize_t read_all_from_socket(tor_socket_t sock, char *buf, size_t count)
tor_socket_t tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr, socklen_t *len, int cloexec, int nonblock)
int set_socket_nonblocking(tor_socket_t sock)
ssize_t write_all_to_socket(tor_socket_t fd, const char *buf, size_t count)
tor_socket_t tor_connect_socket(tor_socket_t sock, const struct sockaddr *address, socklen_t address_len)
void check_network_configuration(bool server_mode)
static int n_sockets_open
tor_socket_t tor_open_socket_with_extensions(int domain, int type, int protocol, int cloexec, int nonblock)
static tor_mutex_t * socket_accounting_mutex
int get_n_open_sockets(void)
int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
void tor_release_socket_ownership(tor_socket_t s)
int tor_addr_from_getsockname(struct tor_addr_t *addr_out, tor_socket_t sock)
void tor_take_socket_ownership(tor_socket_t s)
static void socket_accounting_unlock(void)
int tor_getsockname(tor_socket_t sock, struct sockaddr *address, socklen_t *address_len)
void set_max_sockets(int n)
tor_socket_t tor_open_socket(int domain, int type, int protocol)
tor_socket_t tor_open_socket_nonblocking(int domain, int type, int protocol)
#define MOCK_IMPL(rv, funcname, arglist)
Macros to manage assertions, fatal and non-fatal.