From: Michał Kępień Date: Wed, 2 Dec 2020 21:36:23 +0000 (+0100) Subject: Make netmgr initialize and cleanup Winsock itself X-Git-Tag: v9.16.11~17^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=12fa8a7aedf53f2a42008664bd507116c31d169d;p=thirdparty%2Fbind9.git 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. (cherry picked from commit 88f96faba872cfe7006c6de84759515bdf6e9c47) --- diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 9fc7a393312..7e3d778fc94 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