From 3382a923f523ff35789cc0890864055175057e87 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Sat, 26 Jan 2013 03:52:32 +0100 Subject: [PATCH] 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. --- src/win/winsock.c | 58 +++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/win/winsock.c b/src/win/winsock.c index 2c3e49a1..cbd25af0 100644 --- a/src/win/winsock.c +++ b/src/win/winsock.c @@ -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"); } }