commit fc0dc5aa9ef526a8ed776fe4896fe4007173c638 Author: Nick Mathewson nickm@torproject.org Date: Wed Aug 1 09:40:02 2018 -0400
Refactor tor_ersatz_socketpair() not to need socket.
This change also makes tor_ersatz_socketpair() follow the same interface as socketpair() rather than tor_socketpair(), so it now needs to be wrapped in the same code as socketpair() does. --- src/lib/net/socket.c | 10 ++++++---- src/lib/net/socketpair.c | 34 ++++++++++++++++++++++------------ src/lib/net/socketpair.h | 4 ++-- src/test/test_util.c | 24 +++++++++++++++++------- 4 files changed, 47 insertions(+), 25 deletions(-)
diff --git a/src/lib/net/socket.c b/src/lib/net/socket.c index 5487b8d9d..06421b080 100644 --- a/src/lib/net/socket.c +++ b/src/lib/net/socket.c @@ -420,9 +420,9 @@ get_n_open_sockets(void) int tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) { + int r; //don't use win32 socketpairs (they are always bad) #if defined(HAVE_SOCKETPAIR) && !defined(_WIN32) - int r;
#ifdef SOCK_CLOEXEC r = socketpair(family, type|SOCK_CLOEXEC, protocol, fd); @@ -438,6 +438,11 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) r = socketpair(family, type, protocol, fd); if (r < 0) return -errno; +#else + r = tor_ersatz_socketpair(family, type, protocol, fd); + if (r < 0) + return -r; +#endif
#if defined(FD_CLOEXEC) if (SOCKET_OK(fd[0])) { @@ -472,9 +477,6 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) socket_accounting_unlock();
return 0; -#else /* !(defined(HAVE_SOCKETPAIR) && !defined(_WIN32)) */ - return tor_ersatz_socketpair(family, type, protocol, fd); -#endif /* defined(HAVE_SOCKETPAIR) && !defined(_WIN32) */ }
/** Mockable wrapper for getsockname(). */ diff --git a/src/lib/net/socketpair.c b/src/lib/net/socketpair.c index b656938c4..c4e0d1eed 100644 --- a/src/lib/net/socketpair.c +++ b/src/lib/net/socketpair.c @@ -3,18 +3,28 @@ * Copyright (c) 2007-2018, The Tor Project, Inc. */
#include "lib/net/socketpair.h" -#include "lib/net/socket.h" +#include "lib/net/inaddr_st.h" #include "lib/arch/bytes.h"
#include <errno.h> #include <string.h>
+#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif + #ifdef _WIN32 #include <winsock2.h> #include <windows.h> +#define socket_errno() (WSAGetLastError()) +#define SOCKET_EPROTONOSUPPORT WSAEPROTONOSUPPORT +#else +#define closesocket(x) close(x) +#define socket_errno() (errno) +#define SOCKET_EPROTONOSUPPORT EPROTONOSUPPORT #endif
#ifdef NEED_ERSATZ_SOCKETPAIR @@ -34,7 +44,7 @@ get_local_listener(int family, int type) memset(&sin6, 0, sizeof(sin6));
tor_socket_t sock = TOR_INVALID_SOCKET; - sock = tor_open_socket(family, type, 0); + sock = socket(family, type, 0); if (!SOCKET_OK(sock)) { return TOR_INVALID_SOCKET; } @@ -58,7 +68,7 @@ get_local_listener(int family, int type)
return sock; err: - tor_close_socket(sock); + closesocket(sock); return TOR_INVALID_SOCKET; }
@@ -87,7 +97,7 @@ sockaddr_eq(struct sockaddr *sa1, struct sockaddr *sa2) * Helper used to implement socketpair on systems that lack it, by * making a direct connection to localhost. */ -STATIC int +int tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) { /* This socketpair does not work when localhost is down. So @@ -127,8 +137,8 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
listener = get_local_listener(ersatz_domain, type); if (!SOCKET_OK(listener)) { - int first_errno = tor_socket_errno(-1); - if (first_errno == SOCK_ERRNO(EPROTONOSUPPORT)) { + int first_errno = socket_errno(); + if (first_errno == SOCKET_EPROTONOSUPPORT) { /* Assume we're on an IPv6-only system */ ersatz_domain = AF_INET6; addrlen = sizeof(struct sockaddr_in6); @@ -144,7 +154,7 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) } }
- connector = tor_open_socket(ersatz_domain, type, 0); + connector = socket(ersatz_domain, type, 0); if (!SOCKET_OK(connector)) goto tidy_up_and_fail; /* We want to find out the port number to connect to. */ @@ -157,7 +167,7 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) goto tidy_up_and_fail;
size = sizeof(accepted_addr_ss); - acceptor = tor_accept_socket(listener, accepted_addr, &size); + acceptor = accept(listener, accepted_addr, &size); if (!SOCKET_OK(acceptor)) goto tidy_up_and_fail; if (size != addrlen) @@ -169,7 +179,7 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) /* Set *_tor_addr and *_port to the address and port that was used */ if (!sockaddr_eq(accepted_addr, connect_addr)) goto abort_tidy_up_and_fail; - tor_close_socket(listener); + closesocket(listener); fd[0] = connector; fd[1] = acceptor; return 0; @@ -184,11 +194,11 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2]) if (saved_errno < 0) saved_errno = errno; if (SOCKET_OK(listener)) - tor_close_socket(listener); + closesocket(listener); if (SOCKET_OK(connector)) - tor_close_socket(connector); + closesocket(connector); if (SOCKET_OK(acceptor)) - tor_close_socket(acceptor); + closesocket(acceptor); return -saved_errno; }
diff --git a/src/lib/net/socketpair.h b/src/lib/net/socketpair.h index 3efa65a67..6eecc0737 100644 --- a/src/lib/net/socketpair.h +++ b/src/lib/net/socketpair.h @@ -12,8 +12,8 @@
#if !defined(HAVE_SOCKETPAIR) || defined(_WIN32) || defined(TOR_UNIT_TESTS) #define NEED_ERSATZ_SOCKETPAIR -STATIC int tor_ersatz_socketpair(int family, int type, int protocol, - tor_socket_t fd[2]); +int tor_ersatz_socketpair(int family, int type, int protocol, + tor_socket_t fd[2]); #endif
#endif diff --git a/src/test/test_util.c b/src/test/test_util.c index 7afe83c69..d8246941e 100644 --- a/src/test/test_util.c +++ b/src/test/test_util.c @@ -5540,10 +5540,13 @@ test_util_socketpair(void *arg)
tt_assert(SOCKET_OK(fds[0])); tt_assert(SOCKET_OK(fds[1])); - tt_int_op(get_n_open_sockets(), OP_EQ, n + 2); + if (ersatz) + tt_int_op(get_n_open_sockets(), OP_EQ, n); + else + tt_int_op(get_n_open_sockets(), OP_EQ, n + 2); #ifdef CAN_CHECK_CLOEXEC - tt_int_op(fd_is_cloexec(fds[0]), OP_EQ, 1); - tt_int_op(fd_is_cloexec(fds[1]), OP_EQ, 1); + tt_int_op(fd_is_cloexec(fds[0]), OP_EQ, !ersatz); + tt_int_op(fd_is_cloexec(fds[1]), OP_EQ, !ersatz); #endif #ifdef CAN_CHECK_NONBLOCK tt_int_op(fd_is_nonblocking(fds[0]), OP_EQ, 0); @@ -5551,10 +5554,17 @@ test_util_socketpair(void *arg) #endif
done: - if (SOCKET_OK(fds[0])) - tor_close_socket(fds[0]); - if (SOCKET_OK(fds[1])) - tor_close_socket(fds[1]); + if (ersatz) { + if (SOCKET_OK(fds[0])) + tor_close_socket_simple(fds[0]); + if (SOCKET_OK(fds[1])) + tor_close_socket_simple(fds[1]); + } else { + if (SOCKET_OK(fds[0])) + tor_close_socket(fds[0]); + if (SOCKET_OK(fds[1])) + tor_close_socket(fds[1]); + } }
#undef SOCKET_EPROTO