2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 23:55:27 +00:00

implement maxudp under windows

This commit is contained in:
Mark Andrews
2019-08-08 18:31:20 +10:00
parent ac50b0180b
commit 2f558854b7
4 changed files with 65 additions and 29 deletions

View File

@@ -646,6 +646,9 @@ parse_T_opt(char *option) {
maxudp = 1460; maxudp = 1460;
} else if (!strncmp(option, "maxudp=", 7)) { } else if (!strncmp(option, "maxudp=", 7)) {
maxudp = atoi(option + 7); maxudp = atoi(option + 7);
if (maxudp <= 0) {
named_main_earlyfatal("bad maxudp");
}
} else if (!strncmp(option, "mkeytimers=", 11)) { } else if (!strncmp(option, "mkeytimers=", 11)) {
p = strtok_r(option + 11, "/", &last); p = strtok_r(option + 11, "/", &last);
if (p == NULL) { if (p == NULL) {

View File

@@ -1002,7 +1002,7 @@ isc_socketmgr_setreserved(isc_socketmgr_t *mgr, uint32_t);
*/ */
void 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'. * Test interface. Drop UDP packet > 'maxudp'.
*/ */

View File

@@ -386,7 +386,7 @@ struct isc__socketmgr {
ISC_LIST(isc__socket_t) socklist; ISC_LIST(isc__socket_t) socklist;
int reserved; /* unlocked */ int reserved; /* unlocked */
isc_condition_t shutdown_ok; isc_condition_t shutdown_ok;
int maxudp; size_t maxudp;
}; };
struct isc__socketthread { 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 * Simulate a firewall blocking UDP responses bigger than
* 'maxudp' bytes. * 'maxudp' bytes.
*/ */
if (sock->manager->maxudp != 0 && cc > sock->manager->maxudp) if (sock->manager->maxudp != 0 &&
cc > (int)sock->manager->maxudp)
{
return (DOIO_SOFT); return (DOIO_SOFT);
}
} }
socket_log(sock, &dev->address, IOEVENT, socket_log(sock, &dev->address, IOEVENT,
@@ -1666,7 +1669,7 @@ doio_send(isc__socket_t *sock, isc_socketevent_t *dev) {
resend: resend:
if (sock->type == isc_sockettype_udp && if (sock->type == isc_sockettype_udp &&
sock->manager->maxudp != 0 && sock->manager->maxudp != 0 &&
write_count > (size_t)sock->manager->maxudp) write_count > sock->manager->maxudp)
cc = write_count; cc = write_count;
else else
cc = sendmsg(sock->fd, &msghdr, 0); cc = sendmsg(sock->fd, &msghdr, 0);
@@ -3521,7 +3524,7 @@ isc_socketmgr_setreserved(isc_socketmgr_t *manager0, uint32_t reserved) {
} }
void 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; isc__socketmgr_t *manager = (isc__socketmgr_t *)manager0;
REQUIRE(VALID_MANAGER(manager)); REQUIRE(VALID_MANAGER(manager));

View File

@@ -308,19 +308,20 @@ typedef struct IoCompletionInfo {
struct isc_socketmgr { struct isc_socketmgr {
/* Not locked. */ /* Not locked. */
unsigned int magic; unsigned int magic;
isc_mem_t *mctx; isc_mem_t *mctx;
isc_mutex_t lock; isc_mutex_t lock;
isc_stats_t *stats; isc_stats_t *stats;
/* Locked by manager lock. */ /* Locked by manager lock. */
ISC_LIST(isc_socket_t) socklist; ISC_LIST(isc_socket_t) socklist;
bool bShutdown; bool bShutdown;
isc_condition_t shutdown_ok; isc_condition_t shutdown_ok;
HANDLE hIoCompletionPort; HANDLE hIoCompletionPort;
int maxIOCPThreads; int maxIOCPThreads;
HANDLE hIOCPThreads[MAX_IOCPTHREADS]; HANDLE hIOCPThreads[MAX_IOCPTHREADS];
DWORD dwIOCPThreadIds[MAX_IOCPTHREADS]; DWORD dwIOCPThreadIds[MAX_IOCPTHREADS];
size_t maxudp;
/* /*
* Debugging. * Debugging.
@@ -1133,12 +1134,23 @@ fill_recv(isc_socket_t *sock, isc_socketevent_t *dev) {
sock->recvbuf.from_addr_len); sock->recvbuf.from_addr_len);
if (isc_sockaddr_getport(&dev->address) == 0) { if (isc_sockaddr_getport(&dev->address) == 0) {
if (isc_log_wouldlog(isc_lctx, IOEVENT_LEVEL)) { 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"); "dropping source port zero packet");
} }
sock->recvbuf.remaining = 0; sock->recvbuf.remaining = 0;
return; 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) { } else if (sock->type == isc_sockettype_tcp) {
dev->address = sock->address; dev->address = sock->address;
} }
@@ -1247,6 +1259,18 @@ startio_send(isc_socket_t *sock, isc_socketevent_t *dev, int *nbytes,
int status; int status;
struct msghdr *mh; 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, lpo = (IoCompletionInfo *)HeapAlloc(hHeapHandle,
HEAP_ZERO_MEMORY, HEAP_ZERO_MEMORY,
sizeof(IoCompletionInfo)); sizeof(IoCompletionInfo));
@@ -2100,9 +2124,11 @@ internal_recv(isc_socket_t *sock, int nbytes)
"internal_recv: %d bytes received", nbytes); "internal_recv: %d bytes received", nbytes);
/* /*
* If we got here, the I/O operation succeeded. However, we might still have removed this * If we got here, the I/O operation succeeded. However, we might
* event from our notification list (or never placed it on it due to immediate completion.) * still have removed this event from our notification list (or never
* Handle the reference counting here, and handle the cancellation event just after. * 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); INSIST(sock->pending_iocp > 0);
sock->pending_iocp--; sock->pending_iocp--;
@@ -2110,13 +2136,15 @@ internal_recv(isc_socket_t *sock, int nbytes)
sock->pending_recv--; sock->pending_recv--;
/* /*
* The only way we could have gotten here is that our I/O has successfully completed. * The only way we could have gotten here is that our I/O has
* Update our pointers, and move on. The only odd case here is that we might not * successfully completed. Update our pointers, and move on.
* have received enough data on a TCP stream to satisfy the minimum requirements. If * The only odd case here is that we might not have received
* this is the case, we will re-issue the recv() call for what we need. * 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 * We do check for a recv() of 0 bytes on a TCP stream. This
* has closed. * means the remote end has closed.
*/ */
if (nbytes == 0 && sock->type == isc_sockettype_tcp) { if (nbytes == 0 && sock->type == isc_sockettype_tcp) {
send_recvdone_abort(sock, ISC_R_EOF); 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->bShutdown = false;
manager->totalSockets = 0; manager->totalSockets = 0;
manager->iocp_total = 0; manager->iocp_total = 0;
manager->maxudp = 0;
*managerp = manager; *managerp = manager;
@@ -3870,9 +3899,10 @@ isc_socketmgr_createinctx(isc_mem_t *mctx, isc_socketmgr_t **managerp)
return (result); return (result);
} }
/* Not implemented for win32 */
void void
isc_socketmgr_maxudp(isc_socketmgr_t *manager, int maxudp) { isc_socketmgr_maxudp(isc_socketmgr_t *manager, unsigned int maxudp) {
UNUSED(manager);
UNUSED(maxudp); REQUIRE(VALID_MANAGER(manager));
manager->maxudp = maxudp;
} }