Skip to content
This repository
  • 10 commits
  • 7 files changed
  • 0 comments
  • 2 contributors
Jan 30, 2013
Bert Belder piscisaureus windows: map ERROR_DIRECTORY to UV_ENOENT 4c5c5d9
Bert Belder piscisaureus win: sort error code mappings d27d1e5
Bert Belder piscisaureus win: add error mappings related to unsupported protocols f0844ee
Bert Belder piscisaureus win: fix uv_winsock_init crash when no IPv4 stack present
uv_winsock_init() tries to create an IPv4 socket in order to detect
if the system has any layered service providers (LSPs) installed.
When creating this socket failed it would call uv_fatal_error and exit
with the following message:

  socket: (10047) An address incompatible with the requested protocol was used.

This patch fixes that. It also includes some minor style tweaks.
3382a92
Bert Belder piscisaureus win/tcp: make uv_tcp_set_socket set UV_HANDLE_IPV6
This makes uv_tcp_set_socket responsible for setting the UV_HANDLE_IPV6
flag. This fixes a couple of situations where the the fact that a socket
is an IPv6 socket is not taken into account when deciding whether a call
to SetFileCompletionNotificationModes is appropriate.
c45564a
Bert Belder piscisaureus win/udp: make uv_udp_set_socket set UV_HANDLE_IPV6
This patch makes uv_udp_set_socket responsible for setting the
UV_HANDLE_IPV6 flag.

In addition, this patch fixes some minor style issues.
6b1cca3
Bert Belder piscisaureus win/udp: fix bug in getsockopt() return value check 36883f2
Bert Belder piscisaureus win: get rid of early ipv6 support detection
No longer explictly check wheter an IPv6 stack is present when the user
tries to use IPV6 sockets. Instead realy on the operating system
to report the lack of protocol support via appropriate error messages.
034ea31
Feb 21, 2013
Ben Noordhuis bnoordhuis build: handle bad gcc -dumpversion output
`gcc -dumpversion` usually prints major.minor - but on sunos it prints
major.minor.patch.
1ba01fd
Ben Noordhuis bnoordhuis unix: handle EINPROGRESS for unix sockets
Before this commit, it was assumed that connect() on UNIX sockets never
returns EINPROGRESS. It turned out to be a bad assumption: Dave Pacheco
reports sporadic hangups on SmartOS because of that.

It's not clear to me _why_ the Illumos kernel returns that error but
that's inconsequential: whatever the cause, libuv needs to handle it
and now it does.

This is a back-port of commit 3348cd7 from the master branch.

Fixes joyent/node#4785.

Conflicts:
	src/unix/pipe.c
86ae8b3
4 gyp_uv
@@ -22,7 +22,9 @@ def compiler_version():
22 22 proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
23 23 is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
24 24 proc = subprocess.Popen(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE)
25   - version = tuple(map(int, proc.communicate()[0].split('.')))
  25 + version = proc.communicate()[0].split('.')
  26 + version = map(int, version[:2])
  27 + version = tuple(version)
26 28 return (version, is_clang)
27 29
28 30
11 src/unix/pipe.c
@@ -186,16 +186,14 @@ void uv_pipe_connect(uv_connect_t* req,
186 186 uv_strlcpy(saddr.sun_path, name, sizeof(saddr.sun_path));
187 187 saddr.sun_family = AF_UNIX;
188 188
189   - /* We don't check for EINPROGRESS. Think about it: the socket
190   - * is either there or not.
191   - */
192 189 do {
193 190 r = connect(handle->fd, (struct sockaddr*)&saddr, sizeof saddr);
194 191 }
195 192 while (r == -1 && errno == EINTR);
196 193
197 194 if (r == -1)
198   - goto out;
  195 + if (errno != EINPROGRESS)
  196 + goto out;
199 197
200 198 if (new_sock)
201 199 if (uv__stream_open((uv_stream_t*)handle,
@@ -216,8 +214,9 @@ void uv_pipe_connect(uv_connect_t* req,
216 214 req->cb = cb;
217 215 ngx_queue_init(&req->queue);
218 216
219   - /* Run callback on next tick. */
220   - uv__io_feed(handle->loop, &handle->write_watcher, UV__IO_WRITE);
  217 + /* Force callback to run on next tick in case of error. */
  218 + if (err != 0)
  219 + uv__io_feed(handle->loop, &handle->write_watcher, UV__IO_WRITE);
221 220
222 221 /* Mimic the Windows pipe implementation, always
223 222 * return 0 and let the callback handle errors.
70 src/win/error.c
@@ -66,30 +66,6 @@ void uv_fatal_error(const int errorno, const char* syscall) {
66 66 uv_err_code uv_translate_sys_error(int sys_errno) {
67 67 switch (sys_errno) {
68 68 case ERROR_SUCCESS: return UV_OK;
69   - case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
70   - case ERROR_BUS_RESET: return UV_EIO;
71   - case ERROR_CRC: return UV_EIO;
72   - case ERROR_DEVICE_DOOR_OPEN: return UV_EIO;
73   - case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO;
74   - case ERROR_DISK_CORRUPT: return UV_EIO;
75   - case ERROR_EOM_OVERFLOW: return UV_EIO;
76   - case ERROR_FILEMARK_DETECTED: return UV_EIO;
77   - case ERROR_GEN_FAILURE: return UV_EIO;
78   - case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO;
79   - case ERROR_IO_DEVICE: return UV_EIO;
80   - case ERROR_NO_DATA_DETECTED: return UV_EIO;
81   - case ERROR_NO_SIGNAL_SENT: return UV_EIO;
82   - case ERROR_OPEN_FAILED: return UV_EIO;
83   - case ERROR_SETMARK_DETECTED: return UV_EIO;
84   - case ERROR_SIGNAL_REFUSED: return UV_EIO;
85   - case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
86   - case ERROR_INVALID_NAME: return UV_ENOENT;
87   - case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
88   - case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
89   - case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
90   - case WSANO_DATA: return UV_ENOENT;
91   - case ERROR_ACCESS_DENIED: return UV_EPERM;
92   - case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
93 69 case ERROR_NOACCESS: return UV_EACCES;
94 70 case WSAEACCES: return UV_EACCES;
95 71 case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
@@ -98,8 +74,12 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
98 74 case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT;
99 75 case WSAEWOULDBLOCK: return UV_EAGAIN;
100 76 case WSAEALREADY: return UV_EALREADY;
  77 + case ERROR_INVALID_FLAGS: return UV_EBADF;
  78 + case ERROR_INVALID_HANDLE: return UV_EBADF;
101 79 case ERROR_LOCK_VIOLATION: return UV_EBUSY;
  80 + case ERROR_PIPE_BUSY: return UV_EBUSY;
102 81 case ERROR_SHARING_VIOLATION: return UV_EBUSY;
  82 + case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
103 83 case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED;
104 84 case WSAECONNABORTED: return UV_ECONNABORTED;
105 85 case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED;
@@ -114,9 +94,29 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
114 94 case WSAEHOSTUNREACH: return UV_EHOSTUNREACH;
115 95 case ERROR_OPERATION_ABORTED: return UV_EINTR;
116 96 case WSAEINTR: return UV_EINTR;
  97 + case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
117 98 case ERROR_INVALID_DATA: return UV_EINVAL;
  99 + case ERROR_INVALID_PARAMETER: return UV_EINVAL;
118 100 case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL;
119 101 case WSAEINVAL: return UV_EINVAL;
  102 + case WSAEPFNOSUPPORT: return UV_EINVAL;
  103 + case WSAESOCKTNOSUPPORT: return UV_EINVAL;
  104 + case ERROR_BEGINNING_OF_MEDIA: return UV_EIO;
  105 + case ERROR_BUS_RESET: return UV_EIO;
  106 + case ERROR_CRC: return UV_EIO;
  107 + case ERROR_DEVICE_DOOR_OPEN: return UV_EIO;
  108 + case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO;
  109 + case ERROR_DISK_CORRUPT: return UV_EIO;
  110 + case ERROR_EOM_OVERFLOW: return UV_EIO;
  111 + case ERROR_FILEMARK_DETECTED: return UV_EIO;
  112 + case ERROR_GEN_FAILURE: return UV_EIO;
  113 + case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO;
  114 + case ERROR_IO_DEVICE: return UV_EIO;
  115 + case ERROR_NO_DATA_DETECTED: return UV_EIO;
  116 + case ERROR_NO_SIGNAL_SENT: return UV_EIO;
  117 + case ERROR_OPEN_FAILED: return UV_EIO;
  118 + case ERROR_SETMARK_DETECTED: return UV_EIO;
  119 + case ERROR_SIGNAL_REFUSED: return UV_EIO;
120 120 case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP;
121 121 case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE;
122 122 case WSAEMFILE: return UV_EMFILE;
@@ -125,6 +125,14 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
125 125 case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
126 126 case WSAENETUNREACH: return UV_ENETUNREACH;
127 127 case WSAENOBUFS: return UV_ENOBUFS;
  128 + case ERROR_DIRECTORY: return UV_ENOENT;
  129 + case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
  130 + case ERROR_INVALID_NAME: return UV_ENOENT;
  131 + case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT;
  132 + case ERROR_MOD_NOT_FOUND: return UV_ENOENT;
  133 + case ERROR_PATH_NOT_FOUND: return UV_ENOENT;
  134 + case WSAHOST_NOT_FOUND: return UV_ENOENT;
  135 + case WSANO_DATA: return UV_ENOENT;
128 136 case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM;
129 137 case ERROR_OUTOFMEMORY: return UV_ENOMEM;
130 138 case ERROR_CANNOT_MAKE: return UV_ENOSPC;
@@ -132,26 +140,22 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
132 140 case ERROR_EA_TABLE_FULL: return UV_ENOSPC;
133 141 case ERROR_END_OF_MEDIA: return UV_ENOSPC;
134 142 case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC;
135   - case ERROR_WRITE_PROTECT: return UV_EROFS;
136 143 case ERROR_NOT_CONNECTED: return UV_ENOTCONN;
137 144 case WSAENOTCONN: return UV_ENOTCONN;
138 145 case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY;
  146 + case WSAENOTSOCK: return UV_ENOTSOCK;
139 147 case ERROR_NOT_SUPPORTED: return UV_ENOTSUP;
140   - case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL;
141   - case ERROR_INVALID_FLAGS: return UV_EBADF;
142   - case ERROR_INVALID_HANDLE: return UV_EBADF;
143   - case ERROR_INVALID_PARAMETER: return UV_EINVAL;
144   - case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET;
145 148 case ERROR_BROKEN_PIPE: return UV_EOF;
  149 + case ERROR_ACCESS_DENIED: return UV_EPERM;
  150 + case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM;
146 151 case ERROR_BAD_PIPE: return UV_EPIPE;
147 152 case ERROR_NO_DATA: return UV_EPIPE;
148 153 case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE;
149 154 case WSAESHUTDOWN: return UV_EPIPE;
150   - case ERROR_PIPE_BUSY: return UV_EBUSY;
  155 + case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT;
  156 + case ERROR_WRITE_PROTECT: return UV_EROFS;
151 157 case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT;
152 158 case WSAETIMEDOUT: return UV_ETIMEDOUT;
153   - case WSAHOST_NOT_FOUND: return UV_ENOENT;
154   - case WSAENOTSOCK: return UV_ENOTSOCK;
155 159 case ERROR_NOT_SAME_DEVICE: return UV_EXDEV;
156 160 default: return UV_UNKNOWN;
157 161 }
3  src/win/internal.h
@@ -323,9 +323,6 @@ int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
323 323 int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info,
324 324 OVERLAPPED* overlapped);
325 325
326   -/* Whether ipv6 is supported */
327   -extern int uv_allow_ipv6;
328   -
329 326 /* Whether there are any non-IFS LSPs stacked on TCP */
330 327 extern int uv_tcp_non_ifs_lsp_ipv4;
331 328 extern int uv_tcp_non_ifs_lsp_ipv6;
64 src/win/tcp.c
@@ -81,7 +81,7 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign
81 81
82 82
83 83 static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
84   - SOCKET socket, int imported) {
  84 + SOCKET socket, int family, int imported) {
85 85 DWORD yes = 1;
86 86 int non_ifs_lsp;
87 87
@@ -107,8 +107,11 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
107 107 }
108 108 }
109 109
110   - non_ifs_lsp = (handle->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 :
111   - uv_tcp_non_ifs_lsp_ipv4;
  110 + if (family == AF_INET6) {
  111 + non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6;
  112 + } else {
  113 + non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4;
  114 + }
112 115
113 116 if (pSetFileCompletionNotificationModes && !non_ifs_lsp) {
114 117 if (pSetFileCompletionNotificationModes((HANDLE) socket,
@@ -134,6 +137,12 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
134 137
135 138 handle->socket = socket;
136 139
  140 + if (family == AF_INET6) {
  141 + handle->flags |= UV_HANDLE_IPV6;
  142 + } else {
  143 + assert(!(handle->flags & UV_HANDLE_IPV6));
  144 + }
  145 +
137 146 return 0;
138 147 }
139 148
@@ -238,14 +247,14 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
238 247
239 248
240 249 static int uv__bind(uv_tcp_t* handle,
241   - int domain,
  250 + int family,
242 251 struct sockaddr* addr,
243 252 int addrsize) {
244 253 DWORD err;
245 254 int r;
246 255
247 256 if (handle->socket == INVALID_SOCKET) {
248   - SOCKET sock = socket(domain, SOCK_STREAM, 0);
  257 + SOCKET sock = socket(family, SOCK_STREAM, 0);
249 258 if (sock == INVALID_SOCKET) {
250 259 uv__set_sys_error(handle->loop, WSAGetLastError());
251 260 return -1;
@@ -258,7 +267,7 @@ static int uv__bind(uv_tcp_t* handle,
258 267 return -1;
259 268 }
260 269
261   - if (uv_tcp_set_socket(handle->loop, handle, sock, 0) == -1) {
  270 + if (uv_tcp_set_socket(handle->loop, handle, sock, family, 0) < 0) {
262 271 closesocket(sock);
263 272 return -1;
264 273 }
@@ -293,17 +302,10 @@ int uv__tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
293 302
294 303
295 304 int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
296   - if (uv_allow_ipv6) {
297   - handle->flags |= UV_HANDLE_IPV6;
298   - return uv__bind(handle,
299   - AF_INET6,
300   - (struct sockaddr*)&addr,
301   - sizeof(struct sockaddr_in6));
302   -
303   - } else {
304   - uv__set_sys_error(handle->loop, WSAEAFNOSUPPORT);
305   - return -1;
306   - }
  305 + return uv__bind(handle,
  306 + AF_INET6,
  307 + (struct sockaddr*)&addr,
  308 + sizeof(struct sockaddr_in6));
307 309 }
308 310
309 311
@@ -592,6 +594,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
592 594 int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
593 595 uv_loop_t* loop = server->loop;
594 596 int rv = 0;
  597 + int family;
595 598
596 599 uv_tcp_accept_t* req = server->pending_accepts;
597 600
@@ -606,7 +609,17 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
606 609 return -1;
607 610 }
608 611
609   - if (uv_tcp_set_socket(client->loop, client, req->accept_socket, 0) == -1) {
  612 + if (server->flags & UV_HANDLE_IPV6) {
  613 + family = AF_INET6;
  614 + } else {
  615 + family = AF_INET;
  616 + }
  617 +
  618 + if (uv_tcp_set_socket(client->loop,
  619 + client,
  620 + req->accept_socket,
  621 + family,
  622 + 0) < 0) {
610 623 closesocket(req->accept_socket);
611 624 rv = -1;
612 625 } else {
@@ -756,11 +769,6 @@ int uv__tcp_connect6(uv_connect_t* req,
756 769 BOOL success;
757 770 DWORD bytes;
758 771
759   - if (!uv_allow_ipv6) {
760   - uv__set_sys_error(loop, WSAEAFNOSUPPORT);
761   - return -1;
762   - }
763   -
764 772 if (handle->flags & UV_HANDLE_BIND_ERROR) {
765 773 uv__set_sys_error(loop, handle->bind_error);
766 774 return -1;
@@ -1181,7 +1189,11 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
1181 1189 return -1;
1182 1190 }
1183 1191
1184   - if (uv_tcp_set_socket(tcp->loop, tcp, socket, 1) != 0) {
  1192 + if (uv_tcp_set_socket(tcp->loop,
  1193 + tcp,
  1194 + socket,
  1195 + socket_protocol_info->iAddressFamily,
  1196 + 1) < 0) {
1185 1197 closesocket(socket);
1186 1198 return -1;
1187 1199 }
@@ -1193,10 +1205,6 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info,
1193 1205 tcp->flags |= UV_HANDLE_BOUND;
1194 1206 tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET;
1195 1207
1196   - if (socket_protocol_info->iAddressFamily == AF_INET6) {
1197   - tcp->flags |= UV_HANDLE_IPV6;
1198   - }
1199   -
1200 1208 tcp->loop->active_tcp_streams++;
1201 1209 return 0;
1202 1210 }
49 src/win/udp.c
@@ -56,8 +56,8 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
56 56 }
57 57
58 58
59   -static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
60   - SOCKET socket) {
  59 +static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
  60 + int family) {
61 61 DWORD yes = 1;
62 62 WSAPROTOCOL_INFOW info;
63 63 int opt_len;
@@ -93,7 +93,7 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
93 93 /* if the user is using the default UDP driver (AFD) and has no other */
94 94 /* LSPs stacked on top. Here we check whether that is the case. */
95 95 opt_len = (int) sizeof info;
96   - if (!getsockopt(socket,
  96 + if (getsockopt(socket,
97 97 SOL_SOCKET,
98 98 SO_PROTOCOL_INFOW,
99 99 (char*) &info,
@@ -118,6 +118,12 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle,
118 118
119 119 handle->socket = socket;
120 120
  121 + if (family == AF_INET6) {
  122 + handle->flags |= UV_HANDLE_IPV6;
  123 + } else {
  124 + assert(!(handle->flags & UV_HANDLE_IPV6));
  125 + }
  126 +
121 127 return 0;
122 128 }
123 129
@@ -164,33 +170,36 @@ void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
164 170
165 171
166 172 static int uv__bind(uv_udp_t* handle,
167   - int domain,
  173 + int family,
168 174 struct sockaddr* addr,
169 175 int addrsize,
170 176 unsigned int flags) {
171 177 int r;
172 178 DWORD no = 0, yes = 1;
173 179
174   - if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
  180 + if ((flags & UV_UDP_IPV6ONLY) && family != AF_INET6) {
175 181 /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
176 182 uv__set_artificial_error(handle->loop, UV_EINVAL);
177 183 return -1;
178 184 }
179 185
180 186 if (handle->socket == INVALID_SOCKET) {
181   - SOCKET sock = socket(domain, SOCK_DGRAM, 0);
  187 + SOCKET sock = socket(family, SOCK_DGRAM, 0);
182 188 if (sock == INVALID_SOCKET) {
183 189 uv__set_sys_error(handle->loop, WSAGetLastError());
184 190 return -1;
185 191 }
186 192
187   - if (uv_udp_set_socket(handle->loop, handle, sock) == -1) {
  193 + if (uv_udp_set_socket(handle->loop, handle, sock, family) < 0) {
188 194 closesocket(sock);
189 195 return -1;
190 196 }
  197 +
  198 + if (family == AF_INET6)
  199 + handle->flags |= UV_HANDLE_IPV6;
191 200 }
192 201
193   - if (domain == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
  202 + if (family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
194 203 /* On windows IPV6ONLY is on by default. */
195 204 /* If the user doesn't specify it libuv turns it off. */
196 205
@@ -238,17 +247,11 @@ int uv__udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
238 247
239 248 int uv__udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
240 249 unsigned int flags) {
241   - if (uv_allow_ipv6) {
242   - handle->flags |= UV_HANDLE_IPV6;
243   - return uv__bind(handle,
244   - AF_INET6,
245   - (struct sockaddr*) &addr,
246   - sizeof(struct sockaddr_in6),
247   - flags);
248   - } else {
249   - uv__set_sys_error(handle->loop, WSAEAFNOSUPPORT);
250   - return -1;
251   - }
  250 + return uv__bind(handle,
  251 + AF_INET6,
  252 + (struct sockaddr*) &addr,
  253 + sizeof(struct sockaddr_in6),
  254 + flags);
252 255 }
253 256
254 257
@@ -645,10 +648,10 @@ int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
645 648 }
646 649
647 650 if (setsockopt(handle->socket,
648   - SOL_SOCKET,
649   - SO_BROADCAST,
650   - (char*) &optval,
651   - sizeof optval)) {
  651 + SOL_SOCKET,
  652 + SO_BROADCAST,
  653 + (char*) &optval,
  654 + sizeof optval)) {
652 655 uv__set_sys_error(handle->loop, WSAGetLastError());
653 656 return -1;
654 657 }
59 src/win/winsock.c
@@ -25,9 +25,6 @@
25 25 #include "internal.h"
26 26
27 27
28   -/* Whether ipv6 is supported */
29   -int uv_allow_ipv6;
30   -
31 28 /* Whether there are any non-IFS LSPs stacked on TCP */
32 29 int uv_tcp_non_ifs_lsp_ipv4;
33 30 int uv_tcp_non_ifs_lsp_ipv6;
@@ -75,6 +72,12 @@ BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) {
75 72 }
76 73
77 74
  75 +static int error_means_no_support(DWORD error) {
  76 + return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT ||
  77 + error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT;
  78 +}
  79 +
  80 +
78 81 void uv_winsock_init() {
79 82 const GUID wsaid_connectex = WSAID_CONNECTEX;
80 83 const GUID wsaid_acceptex = WSAID_ACCEPTEX;
@@ -100,48 +103,48 @@ void uv_winsock_init() {
100 103
101 104 /* Detect non-IFS LSPs */
102 105 dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
103   - if (dummy == INVALID_SOCKET) {
104   - uv_fatal_error(WSAGetLastError(), "socket");
105   - }
106 106
107   - opt_len = (int) sizeof protocol_info;
108   - if (!getsockopt(dummy,
109   - SOL_SOCKET,
110   - SO_PROTOCOL_INFOW,
111   - (char*) &protocol_info,
112   - &opt_len) == SOCKET_ERROR) {
113   - uv_fatal_error(WSAGetLastError(), "socket");
114   - }
  107 + if (dummy != INVALID_SOCKET) {
  108 + opt_len = (int) sizeof protocol_info;
  109 + if (!getsockopt(dummy,
  110 + SOL_SOCKET,
  111 + SO_PROTOCOL_INFOW,
  112 + (char*) &protocol_info,
  113 + &opt_len) == SOCKET_ERROR)
  114 + uv_fatal_error(WSAGetLastError(), "getsockopt");
115 115
116   - if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) {
117   - uv_tcp_non_ifs_lsp_ipv4 = 1;
118   - }
  116 + if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
  117 + uv_tcp_non_ifs_lsp_ipv4 = 1;
  118 +
  119 + if (closesocket(dummy) == SOCKET_ERROR)
  120 + uv_fatal_error(WSAGetLastError(), "closesocket");
119 121
120   - if (closesocket(dummy) == SOCKET_ERROR) {
121   - uv_fatal_error(WSAGetLastError(), "closesocket");
  122 + } else if (!error_means_no_support(WSAGetLastError())) {
  123 + /* Any error other than "socket type not supported" is fatal. */
  124 + uv_fatal_error(WSAGetLastError(), "socket");
122 125 }
123 126
124 127 /* Detect IPV6 support and non-IFS LSPs */
125 128 dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
126   - if (dummy != INVALID_SOCKET) {
127   - uv_allow_ipv6 = TRUE;
128 129
  130 + if (dummy != INVALID_SOCKET) {
129 131 opt_len = (int) sizeof protocol_info;
130 132 if (!getsockopt(dummy,
131 133 SOL_SOCKET,
132 134 SO_PROTOCOL_INFOW,
133 135 (char*) &protocol_info,
134   - &opt_len) == SOCKET_ERROR) {
135   - uv_fatal_error(WSAGetLastError(), "socket");
136   - }
  136 + &opt_len) == SOCKET_ERROR)
  137 + uv_fatal_error(WSAGetLastError(), "getsockopt");
137 138
138   - if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) {
  139 + if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
139 140 uv_tcp_non_ifs_lsp_ipv6 = 1;
140   - }
141 141
142   - if (closesocket(dummy) == SOCKET_ERROR) {
  142 + if (closesocket(dummy) == SOCKET_ERROR)
143 143 uv_fatal_error(WSAGetLastError(), "closesocket");
144   - }
  144 +
  145 + } else if (!error_means_no_support(WSAGetLastError())) {
  146 + /* Any error other than "socket type not supported" is fatal. */
  147 + uv_fatal_error(WSAGetLastError(), "socket");
145 148 }
146 149 }
147 150

No commit comments for this range

Something went wrong with that request. Please try again.