]> 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:50:00 +0000 (10:50 +1000)
(cherry picked from commit 2f558854b7e844fa9d61c16edd6785544216714d)

bin/named/main.c
lib/isc/include/isc/socket.h
lib/isc/unix/socket.c
lib/isc/win32/socket.c

index 6371d15090c7ea7dddf0d90a87fa80cb9bdeae8b..c64fb0082b9ac1e2af6570d3f54f855a3b748866 100644 (file)
@@ -611,6 +611,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 98fa51bfd6ceb72b3d8f8471ddbb3c08103843b2..44a2d40b23b1a678e195dd487e754d67965eeb69 100644 (file)
@@ -1005,7 +1005,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 d9a0c200470b6f320002bb56fd5c179b223bcabb..35b4206f447eb4d971aa20a56f04bcdcf0188177 100644 (file)
@@ -385,7 +385,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 {
@@ -1594,8 +1594,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,
@@ -1668,7 +1671,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);
@@ -3576,7 +3579,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 2dd9579827825d8eaec14f2c149007ab2f5b00f1..7554e8cb65caa85ee08bb74dc70964b9df2fc24a 100644 (file)
@@ -300,19 +300,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.
@@ -1126,12 +1127,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;
        }
@@ -1240,6 +1252,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));
@@ -2097,9 +2121,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--;
@@ -2107,13 +2133,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;
 
@@ -3887,9 +3916,10 @@ isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
        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;
 }