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.
This commit is contained in:
Bert Belder 2013-01-26 03:52:32 +01:00
parent f0844ee760
commit 3382a923f5

View File

@ -75,6 +75,12 @@ BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) {
}
static int error_means_no_support(DWORD error) {
return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT ||
error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT;
}
void uv_winsock_init() {
const GUID wsaid_connectex = WSAID_CONNECTEX;
const GUID wsaid_acceptex = WSAID_ACCEPTEX;
@ -100,29 +106,30 @@ void uv_winsock_init() {
/* Detect non-IFS LSPs */
dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (dummy == INVALID_SOCKET) {
if (dummy != INVALID_SOCKET) {
opt_len = (int) sizeof protocol_info;
if (!getsockopt(dummy,
SOL_SOCKET,
SO_PROTOCOL_INFOW,
(char*) &protocol_info,
&opt_len) == SOCKET_ERROR)
uv_fatal_error(WSAGetLastError(), "getsockopt");
if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
uv_tcp_non_ifs_lsp_ipv4 = 1;
if (closesocket(dummy) == SOCKET_ERROR)
uv_fatal_error(WSAGetLastError(), "closesocket");
} else if (!error_means_no_support(WSAGetLastError())) {
/* Any error other than "socket type not supported" is fatal. */
uv_fatal_error(WSAGetLastError(), "socket");
}
opt_len = (int) sizeof protocol_info;
if (!getsockopt(dummy,
SOL_SOCKET,
SO_PROTOCOL_INFOW,
(char*) &protocol_info,
&opt_len) == SOCKET_ERROR) {
uv_fatal_error(WSAGetLastError(), "socket");
}
if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) {
uv_tcp_non_ifs_lsp_ipv4 = 1;
}
if (closesocket(dummy) == SOCKET_ERROR) {
uv_fatal_error(WSAGetLastError(), "closesocket");
}
/* Detect IPV6 support and non-IFS LSPs */
dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP);
if (dummy != INVALID_SOCKET) {
uv_allow_ipv6 = TRUE;
@ -131,17 +138,18 @@ void uv_winsock_init() {
SOL_SOCKET,
SO_PROTOCOL_INFOW,
(char*) &protocol_info,
&opt_len) == SOCKET_ERROR) {
uv_fatal_error(WSAGetLastError(), "socket");
}
&opt_len) == SOCKET_ERROR)
uv_fatal_error(WSAGetLastError(), "getsockopt");
if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) {
if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES))
uv_tcp_non_ifs_lsp_ipv6 = 1;
}
if (closesocket(dummy) == SOCKET_ERROR) {
if (closesocket(dummy) == SOCKET_ERROR)
uv_fatal_error(WSAGetLastError(), "closesocket");
}
} else if (!error_means_no_support(WSAGetLastError())) {
/* Any error other than "socket type not supported" is fatal. */
uv_fatal_error(WSAGetLastError(), "socket");
}
}