21 #ifdef HAVE_NETINET_IN_H
22 #include <netinet/in.h>
28 #define socket_errno() (WSAGetLastError())
29 #define SOCKET_EPROTONOSUPPORT WSAEPROTONOSUPPORT
31 #define closesocket(x) close(x)
32 #define socket_errno() (errno)
33 #define SOCKET_EPROTONOSUPPORT EPROTONOSUPPORT
36 #ifdef NEED_ERSATZ_SOCKETPAIR
39 #define raw_memcmp memcmp
47 get_local_listener(
int family,
int type)
49 struct sockaddr_in sin;
54 memset(&sin, 0,
sizeof(sin));
55 memset(&sin6, 0,
sizeof(sin6));
58 sock = socket(family, type, 0);
63 if (family == AF_INET) {
64 sa = (
struct sockaddr *) &sin;
65 sin.sin_family = AF_INET;
66 sin.sin_addr.s_addr =
tor_htonl(0x7f000001);
69 sa = (
struct sockaddr *) &sin6;
70 sin6.sin6_family = AF_INET6;
71 sin6.sin6_addr.s6_addr[15] = 1;
75 if (bind(sock, sa, len) == -1)
77 if (listen(sock, 1) == -1)
90 sockaddr_eq(
struct sockaddr *sa1,
struct sockaddr *sa2)
92 if (sa1->sa_family != sa2->sa_family)
95 if (sa1->sa_family == AF_INET6) {
98 return sin6_1->sin6_port == sin6_2->sin6_port &&
99 0==raw_memcmp(sin6_1->sin6_addr.s6_addr, sin6_2->sin6_addr.s6_addr, 16);
100 }
else if (sa1->sa_family == AF_INET) {
101 struct sockaddr_in *sin_1 = (
struct sockaddr_in *) sa1;
102 struct sockaddr_in *sin_2 = (
struct sockaddr_in *) sa2;
103 return sin_1->sin_port == sin_2->sin_port &&
104 sin_1->sin_addr.s_addr == sin_2->sin_addr.s_addr;
120 tor_ersatz_socketpair(
int family,
int type,
int protocol,
tor_socket_t fd[2])
130 struct sockaddr_storage accepted_addr_ss;
131 struct sockaddr_storage connect_addr_ss;
132 struct sockaddr *connect_addr = (
struct sockaddr *) &connect_addr_ss;
133 struct sockaddr *accepted_addr = (
struct sockaddr *) &accepted_addr_ss;
135 int saved_errno = -1;
136 int ersatz_domain = AF_INET;
137 socklen_t addrlen =
sizeof(
struct sockaddr_in);
139 memset(&accepted_addr_ss, 0,
sizeof(accepted_addr_ss));
140 memset(&connect_addr_ss, 0,
sizeof(connect_addr_ss));
148 return -WSAEAFNOSUPPORT;
150 return -EAFNOSUPPORT;
157 listener = get_local_listener(ersatz_domain, type);
159 int first_errno = socket_errno();
160 if (first_errno == SOCKET_EPROTONOSUPPORT) {
162 ersatz_domain = AF_INET6;
164 listener = get_local_listener(ersatz_domain, type);
176 connector = socket(ersatz_domain, type, 0);
178 goto tidy_up_and_fail;
180 size =
sizeof(connect_addr_ss);
181 if (getsockname(listener, connect_addr, &size) == -1)
182 goto tidy_up_and_fail;
184 goto abort_tidy_up_and_fail;
185 if (connect(connector, connect_addr, size) == -1)
186 goto tidy_up_and_fail;
188 size =
sizeof(accepted_addr_ss);
189 acceptor = accept(listener, accepted_addr, &size);
191 goto tidy_up_and_fail;
193 goto abort_tidy_up_and_fail;
196 if (getsockname(connector, connect_addr, &size) == -1)
197 goto tidy_up_and_fail;
199 if (!sockaddr_eq(accepted_addr, connect_addr))
200 goto abort_tidy_up_and_fail;
201 closesocket(listener);
206 abort_tidy_up_and_fail:
208 saved_errno = WSAECONNABORTED;
210 saved_errno = ECONNABORTED;
216 closesocket(listener);
218 closesocket(connector);
220 closesocket(acceptor);
Inline functions for reading and writing multibyte values from the middle of strings,...
static uint32_t tor_htonl(uint32_t a)
Define in6_addr, its members, and related types on platforms that lack it.
#define TOR_INVALID_SOCKET
Integer definitions used throughout Tor.