]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
implement maxudp under windows
authorMark Andrews <marka@isc.org>
Thu, 8 Aug 2019 08:31:20 +0000 (18:31 +1000)
committerMark Andrews <marka@isc.org>
Wed, 4 Sep 2019 00:04:14 +0000 (10:04 +1000)
bin/named/main.c
lib/isc/include/isc/socket.h
lib/isc/unix/socket.c
lib/isc/win32/socket.c

index 09842fd472979a760ff6a27d84e266d792e4b724..565dfe1253c1fdd11ca5a0b1edbc74c2c6dd52f2 100644 (file)
@@ -646,6 +646,9 @@ parse_T_opt(char *option) {
                maxudp = 1460;
        } else if (!strncmp(option, "maxudp=", 7)) {
                maxudp = atoi(option + 7);
+               if (maxudp <= 0) {
+                       named_main_earlyfatal("bad maxudp");
+               }
        } else if (!strncmp(option, "mkeytimers=", 11)) {
                p = strtok_r(option + 11, "/", &last);
                if (p == NULL) {
index a69222d2537c8af7656c935de758702460ffa4c7..729138733847951508d93dd98fe32d6e1d3502ca 100644 (file)
@@ -1002,7 +1002,7 @@ isc_socketmgr_setreserved(isc_socketmgr_t *mgr, uint32_t);
  */
 
 void
-isc_socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp);
+isc_socketmgr_maxudp(isc_socketmgr_t *mgr, unsigned int maxudp);
 /*%<
  * Test interface. Drop UDP packet > 'maxudp'.
  */
index be8716ef7c34c4c71a58699145d508a27f25cfd4..efdb16b955ca08198975a75c5db3689914329beb 100644 (file)
@@ -386,7 +386,7 @@ struct isc__socketmgr {
        ISC_LIST(isc__socket_t) socklist;
        int                     reserved;       /* unlocked */
        isc_condition_t         shutdown_ok;
-       int                     maxudp;
+       size_t                  maxudp;
 };
 
 struct isc__socketthread {
@@ -1592,8 +1592,11 @@ doio_recv(isc__socket_t *sock, isc_socketevent_t *dev) {
                 * Simulate a firewall blocking UDP responses bigger than
                 * 'maxudp' bytes.
                 */
-               if (sock->manager->maxudp != 0 && cc > sock->manager->maxudp)
+               if (sock->manager->maxudp != 0 &&
+                   cc > (int)sock->manager->maxudp)
+               {
                        return (DOIO_SOFT);
+               }
        }
 
        socket_log(sock, &dev->address, IOEVENT,
@@ -1666,7 +1669,7 @@ doio_send(isc__socket_t *sock, isc_socketevent_t *dev) {
  resend:
        if (sock->type == isc_sockettype_udp &&
            sock->manager->maxudp != 0 &&
-           write_count > (size_t)sock->manager->maxudp)
+           write_count > sock->manager->maxudp)
                cc = write_count;
        else
                cc = sendmsg(sock->fd, &msghdr, 0);
@@ -3521,7 +3524,7 @@ isc_socketmgr_setreserved(isc_socketmgr_t *manager0, uint32_t reserved) {
 }
 
 void
-isc_socketmgr_maxudp(isc_socketmgr_t *manager0, int maxudp) {
+isc_socketmgr_maxudp(isc_socketmgr_t *manager0, unsigned int maxudp) {
        isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
 
        REQUIRE(VALID_MANAGER(manager));
index b754fce82498e383666123727dc0fc7741478942..4ef5c031ec1ae9e5264ad5fee44b14e259f391f2 100644 (file)
@@ -308,19 +308,20 @@ typedef struct IoCompletionInfo {
 
 struct isc_socketmgr {
        /* Not locked. */
-       unsigned int                    magic;
-       isc_mem_t                      *mctx;
-       isc_mutex_t                     lock;
-       isc_stats_t                    *stats;
+       unsigned int            magic;
+       isc_mem_t              *mctx;
+       isc_mutex_t             lock;
+       isc_stats_t            *stats;
 
        /* Locked by manager lock. */
-       ISC_LIST(isc_socket_t)          socklist;
+       ISC_LIST(isc_socket_t)  socklist;
        bool                    bShutdown;
-       isc_condition_t                 shutdown_ok;
-       HANDLE                          hIoCompletionPort;
-       int                             maxIOCPThreads;
-       HANDLE                          hIOCPThreads[MAX_IOCPTHREADS];
-       DWORD                           dwIOCPThreadIds[MAX_IOCPTHREADS];
+       isc_condition_t         shutdown_ok;
+       HANDLE                  hIoCompletionPort;
+       int                     maxIOCPThreads;
+       HANDLE                  hIOCPThreads[MAX_IOCPTHREADS];
+       DWORD                   dwIOCPThreadIds[MAX_IOCPTHREADS];
+       size_t                  maxudp;
 
        /*
         * Debugging.
@@ -1133,12 +1134,23 @@ fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
                        sock->recvbuf.from_addr_len);
                if (isc_sockaddr_getport(&dev->address) == 0) {
                        if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) {
-                               socket_log(__LINE__, sock, &dev->address, IOEVENT,
+                               socket_log(__LINE__, sock, &dev->address,
+                                          IOEVENT,
                                           "dropping source port zero packet");
                        }
                        sock->recvbuf.remaining = 0;
                        return;
                }
+               /*
+                * Simulate a firewall blocking UDP responses bigger than
+                * 'maxudp' bytes.
+                */
+               if (sock->manager->maxudp != 0 &&
+                   sock->recvbuf.remaining > sock->manager->maxudp)
+               {
+                       sock->recvbuf.remaining = 0;
+                       return;
+               }
        } else if (sock->type == isc_sockettype_tcp) {
                dev->address = sock->address;
        }
@@ -1247,6 +1259,18 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
        int status;
        struct msghdr *mh;
 
+       /*
+        * Simulate a firewall blocking UDP responses bigger than
+        * 'maxudp' bytes.
+        */
+       if (sock->type == isc_sockettype_udp &&
+           sock->manager->maxudp != 0 &&
+           dev->region.length - dev->n > sock->manager->maxudp)
+       {
+               *nbytes = dev->region.length - dev->n;
+               return (DOIO_SUCCESS);
+       }
+
        lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle,
                                            HEAP_ZERO_MEMORY,
                                            sizeof(IoCompletionInfo));
@@ -2100,9 +2124,11 @@ internal_recv(isc_socket_t *sock, int nbytes)
                   "internal_recv: %d bytes received", nbytes);
 
        /*
-        * If we got here, the I/O operation succeeded.  However, we might still have removed this
-        * event from our notification list (or never placed it on it due to immediate completion.)
-        * Handle the reference counting here, and handle the cancellation event just after.
+        * If we got here, the I/O operation succeeded.  However, we might
+        * still have removed this event from our notification list (or never
+        * placed it on it due to immediate completion.)
+        * Handle the reference counting here, and handle the cancellation
+        * event just after.
         */
        INSIST(sock->pending_iocp > 0);
        sock->pending_iocp--;
@@ -2110,13 +2136,15 @@ internal_recv(isc_socket_t *sock, int nbytes)
        sock->pending_recv--;
 
        /*
-        * The only way we could have gotten here is that our I/O has successfully completed.
-        * Update our pointers, and move on.  The only odd case here is that we might not
-        * have received enough data on a TCP stream to satisfy the minimum requirements.  If
-        * this is the case, we will re-issue the recv() call for what we need.
+        * The only way we could have gotten here is that our I/O has
+        * successfully completed. Update our pointers, and move on.
+        *  The only odd case here is that we might not have received
+        * enough data on a TCP stream to satisfy the minimum requirements.
+        * If this is the case, we will re-issue the recv() call for what
+        * we need.
         *
-        * We do check for a recv() of 0 bytes on a TCP stream.  This means the remote end
-        * has closed.
+        * We do check for a recv() of 0 bytes on a TCP stream.  This
+        * means the remote end has closed.
         */
        if (nbytes == 0 && sock->type == isc_sockettype_tcp) {
                send_recvdone_abort(sock, ISC_R_EOF);
@@ -2508,6 +2536,7 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
        manager->bShutdown = false;
        manager->totalSockets = 0;
        manager->iocp_total = 0;
+       manager->maxudp = 0;
 
        *managerp = manager;
 
@@ -3870,9 +3899,10 @@ isc_socketmgr_createinctx(isc_mem_t *mctx, isc_socketmgr_t **managerp)
        return (result);
 }
 
-/* Not implemented for win32 */
 void
-isc_socketmgr_maxudp(isc_socketmgr_t *manager, int maxudp) {
-       UNUSED(manager);
-       UNUSED(maxudp);
+isc_socketmgr_maxudp(isc_socketmgr_t *manager, unsigned int maxudp) {
+
+       REQUIRE(VALID_MANAGER(manager));
+
+       manager->maxudp = maxudp;
 }