]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Make netmgr initialize and cleanup Winsock itself
authorMichał Kępień <michal@isc.org>
Wed, 2 Dec 2020 21:36:23 +0000 (22:36 +0100)
committerMichał Kępień <michal@isc.org>
Wed, 2 Dec 2020 21:36:23 +0000 (22:36 +0100)
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

index 0a3266c48cef008836afdee7657f8d8cd8f1280a..a4e54b3f5ceb9f42f359ed6d7953d07c297d7854 100644 (file)
@@ -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