From dc2e1dea864b89f8dbf6365b395d6d0e292e9888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Wed, 2 Dec 2020 22:36:23 +0100 Subject: [PATCH 1/2] Extend log message for unexpected socket() errors Make sure the error code is included in the message logged for unexpected socket creation errors in order to facilitate troubleshooting on Windows. --- lib/isc/netmgr/netmgr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 9feae4f8a4..0a3266c48c 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -2053,8 +2053,10 @@ isc__nm_socket(int domain, int type, int protocol, uv_os_sock_t *sockp) { return (ISC_R_FAMILYNOSUPPORT); default: strerror_r(socket_errno, strbuf, sizeof(strbuf)); - UNEXPECTED_ERROR(__FILE__, __LINE__, - "socket() failed: %s", strbuf); + UNEXPECTED_ERROR( + __FILE__, __LINE__, + "socket() failed with error code %lu: %s", + socket_errno, strbuf); return (ISC_R_UNEXPECTED); } } From 88f96faba872cfe7006c6de84759515bdf6e9c47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Wed, 2 Dec 2020 22:36:23 +0100 Subject: [PATCH 2/2] Make netmgr initialize and cleanup Winsock itself On Windows, WSAStartup() needs to be called to initialize Winsock before any sockets are created or else socket() calls will return error code 10093 (WSANOTINITIALISED). Since BIND's Network Manager is intended to work as a reusable networking library, it should take care of calling WSAStartup() - and its cleanup counterpart, WSACleanup() - itself rather than relying on external code to do it. Add the necessary WSAStartup() and WSACleanup() calls to isc_nm_start() and isc_nm_destroy(), respectively. --- lib/isc/netmgr/netmgr.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 0a3266c48c..a4e54b3f5c 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -185,11 +185,50 @@ isc__nm_test_lb_socket(sa_family_t sa_family, int protocol) { return (result == ISC_R_SUCCESS); } +#ifdef WIN32 +static void +isc__nm_winsock_initialize(void) { + WORD wVersionRequested = MAKEWORD(2, 2); + WSADATA wsaData; + int result; + + result = WSAStartup(wVersionRequested, &wsaData); + if (result != 0) { + char strbuf[ISC_STRERRORSIZE]; + strerror_r(result, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, + "WSAStartup() failed with error code %lu: %s", + result, strbuf); + } + + /* + * Confirm that the WinSock DLL supports version 2.2. Note that if the + * DLL supports versions greater than 2.2 in addition to 2.2, it will + * still return 2.2 in wVersion since that is the version we requested. + */ + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { + UNEXPECTED_ERROR(__FILE__, __LINE__, + "Unusable WinSock DLL version: %u.%u", + LOBYTE(wsaData.wVersion), + HIBYTE(wsaData.wVersion)); + } +} + +static void +isc__nm_winsock_destroy(void) { + WSACleanup(); +} +#endif /* WIN32 */ + isc_nm_t * isc_nm_start(isc_mem_t *mctx, uint32_t workers) { isc_nm_t *mgr = NULL; char name[32]; +#ifdef WIN32 + isc__nm_winsock_initialize(); +#endif /* WIN32 */ + isc__nm_tls_initialize(); if (!isc__nm_test_lb_socket(AF_INET, SOCK_DGRAM) || @@ -352,6 +391,10 @@ nm_destroy(isc_nm_t **mgr0) { isc_mem_put(mgr->mctx, mgr->workers, mgr->nworkers * sizeof(isc__networker_t)); isc_mem_putanddetach(&mgr->mctx, mgr, sizeof(*mgr)); + +#ifdef WIN32 + isc__nm_winsock_destroy(); +#endif /* WIN32 */ } void