]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
netmgr fixes:
authorEvan Hunt <each@isc.org>
Fri, 10 Jan 2020 22:25:30 +0000 (14:25 -0800)
committerEvan Hunt <each@isc.org>
Mon, 13 Jan 2020 18:54:17 +0000 (10:54 -0800)
 - use UV_{TC,UD}P_IPV6ONLY for IPv6 sockets, keeping the pre-netmgr
   behaviour.
 - add a new listening_error bool flag which is set if the child
   listener fails to start listening. This fixes a bug where named would
   hang if, e.g.,  we failed to bind to a TCP socket.

lib/isc/netmgr/netmgr-int.h
lib/isc/netmgr/tcp.c
lib/isc/netmgr/udp.c

index 68f3f399b8542beaf70cc4b6ed15b8bd7397d1f0..a451012e16e9cbc8e3ea1ad91fa1020678abae47 100644 (file)
@@ -390,6 +390,7 @@ struct isc_nmsocket {
         */
        atomic_bool             closed;
        atomic_bool             listening;
+       atomic_bool             listen_error;
        isc_refcount_t          references;
 
        /*%
index 46c612ab832227bcae8456e189fb67ce36287351..bab631533f8688c3a516d800cae72f1df4559965 100644 (file)
@@ -180,7 +180,8 @@ isc_nm_listentcp(isc_nm_t *mgr, isc_nmiface_t *iface,
                                       (isc__netievent_t *) ievent);
 
                LOCK(&nsock->lock);
-               while (!atomic_load(&nsock->listening)) {
+               while (!atomic_load(&nsock->listening) &&
+                      !atomic_load(&nsock->listen_error)) {
                        WAIT(&nsock->cond, &nsock->lock);
                }
                UNLOCK(&nsock->lock);
@@ -213,7 +214,7 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
                (isc__netievent_tcplisten_t *) ev0;
        isc_nmsocket_t *sock = ievent->sock;
        struct sockaddr_storage sname;
-       int r, snamelen = sizeof(sname);
+       int r, flags = 0, snamelen = sizeof(sname);
 
        REQUIRE(isc__nm_in_netthread());
        REQUIRE(sock->type == isc_nm_tcplistener);
@@ -241,13 +242,19 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
                /* It was never opened */
                atomic_store(&sock->closed, true);
                sock->result = isc__nm_uverr2result(r);
+               atomic_store(&sock->listen_error, true);
                goto done;
        }
+       if (sock->iface->addr.type.sa.sa_family == AF_INET6) {
+               flags = UV_TCP_IPV6ONLY;
+       }
 
-       r = uv_tcp_bind(&sock->uv_handle.tcp, &sock->iface->addr.type.sa, 0);
+       r = uv_tcp_bind(&sock->uv_handle.tcp,
+                       &sock->iface->addr.type.sa, flags);
        if (r != 0) {
                uv_close(&sock->uv_handle.handle, tcp_close_cb);
                sock->result = isc__nm_uverr2result(r);
+               atomic_store(&sock->listen_error, true);
                goto done;
        }
 
@@ -257,10 +264,12 @@ isc__nm_async_tcplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
         * initially returning success even if bind() fails, and this
         * could cause a deadlock later if we didn't check first.)
         */
-       r = uv_tcp_getsockname(&sock->uv_handle.tcp, &sname, &snamelen);
+       r = uv_tcp_getsockname(&sock->uv_handle.tcp,
+                              (struct sockaddr*) &sname, &snamelen);
        if (r != 0) {
                uv_close(&sock->uv_handle.handle, tcp_close_cb);
                sock->result = isc__nm_uverr2result(r);
+               atomic_store(&sock->listen_error, true);
                goto done;
        }
 
index abd950a2790157769c35f8c61645b85d1dfdf859..2731ce24970f56f5dd3843e11c5811cba2bf16ed 100644 (file)
@@ -130,8 +130,12 @@ isc__nm_async_udplisten(isc__networker_t *worker, isc__netievent_t *ev0) {
                            (isc_nmsocket_t **)&sock->uv_handle.udp.data);
 
        uv_udp_open(&sock->uv_handle.udp, sock->fd);
+       int flags = 0;
+       if (sock->iface->addr.type.sa.sa_family == AF_INET6) {
+               flags = UV_UDP_IPV6ONLY;
+       }
        uv_udp_bind(&sock->uv_handle.udp,
-                   &sock->parent->iface->addr.type.sa, 0);
+                   &sock->parent->iface->addr.type.sa, flags);
        uv_recv_buffer_size(&sock->uv_handle.handle,
                            &(int){16 * 1024 * 1024});
        uv_send_buffer_size(&sock->uv_handle.handle,