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"); } }