2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-28 13:08:06 +00:00

Temporarily move dns_tcpmsg functionality into dispatch

Continuing the effort to move all uses of the isc_socket API into
dispatch.c, this commit removes the dns_tcpmsg module entirely, as
dispatch was its only caller, and moves the parts of its functionality
that were being used into the dispatch module.

This code will be removed when we switch to using netmgr TCPDNS.
This commit is contained in:
Evan Hunt 2020-12-18 17:21:00 -08:00
parent 4f30b679e7
commit 2c7232d82f
8 changed files with 142 additions and 392 deletions

View File

@ -1050,6 +1050,8 @@ update_listener(named_controls_t *cp, controllistener_t **listenerp,
socktext, isc_result_totext(result));
}
#if 0
/* XXX: no unix socket support yet */
if (result == ISC_R_SUCCESS && type == isc_socktype_unix) {
uint32_t perm, owner, group;
perm = cfg_obj_asuint32(cfg_tuple_get(control, "perm"));
@ -1073,6 +1075,7 @@ update_listener(named_controls_t *cp, controllistener_t **listenerp,
socktext);
}
}
#endif
*listenerp = listener;
}

View File

@ -126,7 +126,6 @@ libdns_la_HEADERS = \
include/dns/soa.h \
include/dns/ssu.h \
include/dns/stats.h \
include/dns/tcpmsg.h \
include/dns/time.h \
include/dns/timer.h \
include/dns/transport.h \
@ -232,7 +231,6 @@ libdns_la_SOURCES = \
ssu.c \
ssu_external.c \
stats.c \
tcpmsg.c \
time.c \
timer.c \
transport.c \

View File

@ -35,7 +35,6 @@
#include <dns/log.h>
#include <dns/message.h>
#include <dns/stats.h>
#include <dns/tcpmsg.h>
#include <dns/types.h>
typedef ISC_LIST(dns_dispentry_t) dns_displist_t;
@ -133,6 +132,18 @@ struct dispsocket {
ISC_LINK(dispsocket_t) blink;
};
typedef struct tcpmsg {
uint16_t size;
dns_dispatch_t *disp;
isc_buffer_t buffer;
isc_task_t *task;
isc_taskaction_t action;
void *arg;
isc_event_t event;
isc_result_t result;
isc_sockaddr_t address;
} tcpmsg_t;
/*%
* Number of tasks for each dispatch that use separate sockets for different
* transactions. This must be a power of 2 as it will divide 32 bit numbers
@ -176,7 +187,7 @@ struct dns_dispatch {
unsigned int nsockets;
unsigned int requests; /*%< how many requests we have */
unsigned int tcpbuffers; /*%< allocated buffers */
dns_tcpmsg_t tcpmsg; /*%< for tcp streams */
tcpmsg_t tcpmsg;
};
#define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ')
@ -1123,7 +1134,7 @@ restart:
static void
tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
dns_dispatch_t *disp = ev_in->ev_arg;
dns_tcpmsg_t *tcpmsg = &disp->tcpmsg;
tcpmsg_t *tcpmsg = &disp->tcpmsg;
dns_messageid_t id;
isc_result_t dres;
unsigned int flags;
@ -1206,13 +1217,13 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
}
dispatch_log(disp, LVL(90), "result %d, length == %d, addr = %p",
tcpmsg->result, tcpmsg->buffer.length,
tcpmsg->buffer.base);
tcpmsg->result, disp->tcpmsg.buffer.length,
disp->tcpmsg.buffer.base);
/*
* Peek into the buffer to see what we can see.
*/
dres = dns_message_peekheader(&tcpmsg->buffer, &id, &flags);
dres = dns_message_peekheader(&disp->tcpmsg.buffer, &id, &flags);
if (dres != ISC_R_SUCCESS) {
dispatch_log(disp, LVL(10), "got garbage packet");
goto restart;
@ -1258,7 +1269,10 @@ tcp_recv(isc_task_t *task, isc_event_t *ev_in) {
* resp contains the information on the place to send it to.
* Send the event off.
*/
dns_tcpmsg_keepbuffer(tcpmsg, &rev->buffer);
rev->buffer = disp->tcpmsg.buffer;
disp->tcpmsg.buffer.base = NULL;
disp->tcpmsg.buffer.length = 0;
disp->tcpbuffers++;
rev->result = ISC_R_SUCCESS;
rev->id = id;
@ -1288,6 +1302,115 @@ restart:
UNLOCK(&disp->lock);
}
static void
recv_tcpmsg(isc_task_t *task, isc_event_t *ev_in) {
isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
tcpmsg_t *tcpmsg = ev_in->ev_arg;
isc_event_t *dev = &tcpmsg->event;
UNUSED(task);
tcpmsg->address = ev->address;
if (ev->result != ISC_R_SUCCESS) {
tcpmsg->result = ev->result;
goto send_and_free;
}
tcpmsg->result = ISC_R_SUCCESS;
isc_buffer_add(&tcpmsg->buffer, ev->n);
send_and_free:
isc_task_send(tcpmsg->task, &dev);
tcpmsg->task = NULL;
isc_event_free(&ev_in);
}
static void
recv_tcplen(isc_task_t *task, isc_event_t *ev_in) {
isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
tcpmsg_t *tcpmsg = ev_in->ev_arg;
isc_event_t *dev = &tcpmsg->event;
isc_region_t region;
isc_result_t result;
tcpmsg->address = ev->address;
if (ev->result != ISC_R_SUCCESS) {
tcpmsg->result = ev->result;
goto send_and_free;
}
/*
* Success.
*/
tcpmsg->size = ntohs(tcpmsg->size);
if (tcpmsg->size == 0) {
tcpmsg->result = ISC_R_UNEXPECTEDEND;
goto send_and_free;
}
region.base = isc_mem_get(tcpmsg->disp->mgr->mctx, tcpmsg->size);
region.length = tcpmsg->size;
if (region.base == NULL) {
tcpmsg->result = ISC_R_NOMEMORY;
goto send_and_free;
}
isc_buffer_init(&tcpmsg->buffer, region.base, region.length);
result = isc_socket_recv(tcpmsg->disp->socket, &region, 0, task,
recv_tcpmsg, tcpmsg);
if (result != ISC_R_SUCCESS) {
tcpmsg->result = result;
goto send_and_free;
}
isc_event_free(&ev_in);
return;
send_and_free:
isc_task_send(tcpmsg->task, &dev);
tcpmsg->task = NULL;
isc_event_free(&ev_in);
return;
}
static isc_result_t
tcp_readmessage(tcpmsg_t *tcpmsg, isc_task_t *task, isc_taskaction_t action,
void *arg) {
isc_result_t result;
isc_region_t region;
REQUIRE(task != NULL);
REQUIRE(tcpmsg->task == NULL); /* not currently in use */
if (tcpmsg->buffer.base != NULL) {
isc_mem_put(tcpmsg->disp->mgr->mctx, tcpmsg->buffer.base,
tcpmsg->buffer.length);
tcpmsg->buffer.base = NULL;
tcpmsg->buffer.length = 0;
}
tcpmsg->task = task;
tcpmsg->action = action;
tcpmsg->arg = arg;
tcpmsg->result = ISC_R_UNEXPECTED; /* unknown right now */
ISC_EVENT_INIT(&tcpmsg->event, sizeof(isc_event_t), 0, 0,
DNS_EVENT_TCPMSG, action, arg, tcpmsg, NULL, NULL);
region.base = (unsigned char *)&tcpmsg->size;
region.length = 2; /* uint16_t */
result = isc_socket_recv(tcpmsg->disp->socket, &region, 0, tcpmsg->task,
recv_tcplen, tcpmsg);
if (result != ISC_R_SUCCESS) {
tcpmsg->task = NULL;
}
return (result);
}
/*
* disp must be locked.
*/
@ -1333,8 +1456,8 @@ startrecv(dns_dispatch_t *disp, dispsocket_t *dispsock) {
break;
case isc_sockettype_tcp:
res = dns_tcpmsg_readmessage(&disp->tcpmsg, disp->task[0],
tcp_recv, disp);
res = tcp_readmessage(&disp->tcpmsg, disp->task[0], tcp_recv,
disp);
if (res != ISC_R_SUCCESS) {
disp->shutdown_why = res;
disp->shutting_down = 1;
@ -1732,7 +1855,12 @@ dispatch_free(dns_dispatch_t **dispp) {
REQUIRE(VALID_DISPATCHMGR(mgr));
if (disp->tcpmsg_valid) {
dns_tcpmsg_invalidate(&disp->tcpmsg);
if (disp->tcpmsg.buffer.base != NULL) {
isc_mem_put(disp->mgr->mctx, disp->tcpmsg.buffer.base,
disp->tcpmsg.buffer.length);
disp->tcpmsg.buffer.base = NULL;
disp->tcpmsg.buffer.length = 0;
}
disp->tcpmsg_valid = 0;
}
@ -1820,7 +1948,7 @@ dns_dispatch_createtcp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
isc_task_setname(disp->task[0], "tcpdispatch", disp);
dns_tcpmsg_init(mgr->mctx, disp->socket, &disp->tcpmsg);
disp->tcpmsg = (tcpmsg_t){ .disp = disp, .result = ISC_R_UNEXPECTED };
disp->tcpmsg_valid = 1;
/*

View File

@ -1,141 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
#ifndef DNS_TCPMSG_H
#define DNS_TCPMSG_H 1
/*! \file dns/tcpmsg.h */
#include <inttypes.h>
#include <isc/buffer.h>
#include <isc/lang.h>
#include <isc/socket.h>
typedef struct dns_tcpmsg {
/* private (don't touch!) */
unsigned int magic;
uint16_t size;
isc_buffer_t buffer;
unsigned int maxsize;
isc_mem_t * mctx;
isc_socket_t * sock;
isc_task_t * task;
isc_taskaction_t action;
void * arg;
isc_event_t event;
/* public (read-only) */
isc_result_t result;
isc_sockaddr_t address;
} dns_tcpmsg_t;
ISC_LANG_BEGINDECLS
void
dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg);
/*%<
* Associate a tcp message state with a given memory context and
* TCP socket.
*
* Requires:
*
*\li "mctx" and "sock" be non-NULL and valid types.
*
*\li "sock" be a read/write TCP socket.
*
*\li "tcpmsg" be non-NULL and an uninitialized or invalidated structure.
*
* Ensures:
*
*\li "tcpmsg" is a valid structure.
*/
void
dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize);
/*%<
* Set the maximum packet size to "maxsize"
*
* Requires:
*
*\li "tcpmsg" be valid.
*
*\li 512 <= "maxsize" <= 65536
*/
isc_result_t
dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg, isc_task_t *task,
isc_taskaction_t action, void *arg);
/*%<
* Schedule an event to be delivered when a DNS message is readable, or
* when an error occurs on the socket.
*
* Requires:
*
*\li "tcpmsg" be valid.
*
*\li "task", "taskaction", and "arg" be valid.
*
* Returns:
*
*\li ISC_R_SUCCESS -- no error
*\li Anything that the isc_socket_recv() call can return. XXXMLG
*
* Notes:
*
*\li The event delivered is a fully generic event. It will contain no
* actual data. The sender will be a pointer to the dns_tcpmsg_t.
* The result code inside that structure should be checked to see
* what the final result was.
*/
void
dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg);
/*%<
* Cancel a readmessage() call. The event will still be posted with a
* CANCELED result code.
*
* Requires:
*
*\li "tcpmsg" be valid.
*/
void
dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer);
/*%<
* If a dns buffer is to be kept between calls, this function marks the
* internal state-machine buffer as invalid, and copies all the contents
* of the state into "buffer".
*
* Requires:
*
*\li "tcpmsg" be valid.
*
*\li "buffer" be non-NULL.
*/
void
dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg);
/*%<
* Clean up all allocated state, and invalidate the structure.
*
* Requires:
*
*\li "tcpmsg" be valid.
*
* Ensures:
*
*\li "tcpmsg" is invalidated and disassociated with all memory contexts,
* sockets, etc.
*/
ISC_LANG_ENDDECLS
#endif /* DNS_TCPMSG_H */

View File

@ -1,234 +0,0 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
/*! \file */
#include <inttypes.h>
#include <isc/mem.h>
#include <isc/print.h>
#include <isc/task.h>
#include <isc/util.h>
#include <dns/events.h>
#include <dns/result.h>
#include <dns/tcpmsg.h>
#ifdef TCPMSG_DEBUG
#include <stdio.h> /* Required for printf. */
#define XDEBUG(x) printf x
#else /* ifdef TCPMSG_DEBUG */
#define XDEBUG(x)
#endif /* ifdef TCPMSG_DEBUG */
#define TCPMSG_MAGIC ISC_MAGIC('T', 'C', 'P', 'm')
#define VALID_TCPMSG(foo) ISC_MAGIC_VALID(foo, TCPMSG_MAGIC)
static void
recv_length(isc_task_t *, isc_event_t *);
static void
recv_message(isc_task_t *, isc_event_t *);
static void
recv_length(isc_task_t *task, isc_event_t *ev_in) {
isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
isc_event_t *dev;
dns_tcpmsg_t *tcpmsg = ev_in->ev_arg;
isc_region_t region;
isc_result_t result;
INSIST(VALID_TCPMSG(tcpmsg));
dev = &tcpmsg->event;
tcpmsg->address = ev->address;
if (ev->result != ISC_R_SUCCESS) {
tcpmsg->result = ev->result;
goto send_and_free;
}
/*
* Success.
*/
tcpmsg->size = ntohs(tcpmsg->size);
if (tcpmsg->size == 0) {
tcpmsg->result = ISC_R_UNEXPECTEDEND;
goto send_and_free;
}
if (tcpmsg->size > tcpmsg->maxsize) {
tcpmsg->result = ISC_R_RANGE;
goto send_and_free;
}
region.base = isc_mem_get(tcpmsg->mctx, tcpmsg->size);
region.length = tcpmsg->size;
if (region.base == NULL) {
tcpmsg->result = ISC_R_NOMEMORY;
goto send_and_free;
}
XDEBUG(("Allocated %d bytes\n", tcpmsg->size));
isc_buffer_init(&tcpmsg->buffer, region.base, region.length);
result = isc_socket_recv(tcpmsg->sock, &region, 0, task, recv_message,
tcpmsg);
if (result != ISC_R_SUCCESS) {
tcpmsg->result = result;
goto send_and_free;
}
isc_event_free(&ev_in);
return;
send_and_free:
isc_task_send(tcpmsg->task, &dev);
tcpmsg->task = NULL;
isc_event_free(&ev_in);
return;
}
static void
recv_message(isc_task_t *task, isc_event_t *ev_in) {
isc_socketevent_t *ev = (isc_socketevent_t *)ev_in;
isc_event_t *dev;
dns_tcpmsg_t *tcpmsg = ev_in->ev_arg;
(void)task;
INSIST(VALID_TCPMSG(tcpmsg));
dev = &tcpmsg->event;
tcpmsg->address = ev->address;
if (ev->result != ISC_R_SUCCESS) {
tcpmsg->result = ev->result;
goto send_and_free;
}
tcpmsg->result = ISC_R_SUCCESS;
isc_buffer_add(&tcpmsg->buffer, ev->n);
XDEBUG(("Received %u bytes (of %d)\n", ev->n, tcpmsg->size));
send_and_free:
isc_task_send(tcpmsg->task, &dev);
tcpmsg->task = NULL;
isc_event_free(&ev_in);
}
void
dns_tcpmsg_init(isc_mem_t *mctx, isc_socket_t *sock, dns_tcpmsg_t *tcpmsg) {
REQUIRE(mctx != NULL);
REQUIRE(sock != NULL);
REQUIRE(tcpmsg != NULL);
tcpmsg->magic = TCPMSG_MAGIC;
tcpmsg->size = 0;
tcpmsg->buffer.base = NULL;
tcpmsg->buffer.length = 0;
tcpmsg->maxsize = 65535; /* Largest message possible. */
tcpmsg->mctx = mctx;
tcpmsg->sock = sock;
tcpmsg->task = NULL; /* None yet. */
tcpmsg->result = ISC_R_UNEXPECTED; /* None yet. */
/* Should probably initialize the event here, but it can wait. */
}
void
dns_tcpmsg_setmaxsize(dns_tcpmsg_t *tcpmsg, unsigned int maxsize) {
REQUIRE(VALID_TCPMSG(tcpmsg));
REQUIRE(maxsize < 65536);
tcpmsg->maxsize = maxsize;
}
isc_result_t
dns_tcpmsg_readmessage(dns_tcpmsg_t *tcpmsg, isc_task_t *task,
isc_taskaction_t action, void *arg) {
isc_result_t result;
isc_region_t region;
REQUIRE(VALID_TCPMSG(tcpmsg));
REQUIRE(task != NULL);
REQUIRE(tcpmsg->task == NULL); /* not currently in use */
if (tcpmsg->buffer.base != NULL) {
isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base,
tcpmsg->buffer.length);
tcpmsg->buffer.base = NULL;
tcpmsg->buffer.length = 0;
}
tcpmsg->task = task;
tcpmsg->action = action;
tcpmsg->arg = arg;
tcpmsg->result = ISC_R_UNEXPECTED; /* unknown right now */
ISC_EVENT_INIT(&tcpmsg->event, sizeof(isc_event_t), 0, 0,
DNS_EVENT_TCPMSG, action, arg, tcpmsg, NULL, NULL);
region.base = (unsigned char *)&tcpmsg->size;
region.length = 2; /* uint16_t */
result = isc_socket_recv(tcpmsg->sock, &region, 0, tcpmsg->task,
recv_length, tcpmsg);
if (result != ISC_R_SUCCESS) {
tcpmsg->task = NULL;
}
return (result);
}
void
dns_tcpmsg_cancelread(dns_tcpmsg_t *tcpmsg) {
REQUIRE(VALID_TCPMSG(tcpmsg));
isc_socket_cancel(tcpmsg->sock, NULL, ISC_SOCKCANCEL_RECV);
}
void
dns_tcpmsg_keepbuffer(dns_tcpmsg_t *tcpmsg, isc_buffer_t *buffer) {
REQUIRE(VALID_TCPMSG(tcpmsg));
REQUIRE(buffer != NULL);
*buffer = tcpmsg->buffer;
tcpmsg->buffer.base = NULL;
tcpmsg->buffer.length = 0;
}
#if 0
void
dns_tcpmsg_freebuffer(dns_tcpmsg_t *tcpmsg) {
REQUIRE(VALID_TCPMSG(tcpmsg));
if (tcpmsg->buffer.base == NULL) {
return;
}
isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base, tcpmsg->buffer.length);
tcpmsg->buffer.base = NULL;
tcpmsg->buffer.length = 0;
}
#endif /* if 0 */
void
dns_tcpmsg_invalidate(dns_tcpmsg_t *tcpmsg) {
REQUIRE(VALID_TCPMSG(tcpmsg));
tcpmsg->magic = 0;
if (tcpmsg->buffer.base != NULL) {
isc_mem_put(tcpmsg->mctx, tcpmsg->buffer.base,
tcpmsg->buffer.length);
tcpmsg->buffer.base = NULL;
tcpmsg->buffer.length = 0;
}
}

View File

@ -34,7 +34,6 @@
#include <dns/rdataset.h>
#include <dns/result.h>
#include <dns/soa.h>
#include <dns/tcpmsg.h>
#include <dns/transport.h>
#include <dns/tsig.h>
#include <dns/view.h>

View File

@ -70,7 +70,6 @@
#include <dns/name.h>
#include <dns/rdataclass.h>
#include <dns/rdatatype.h>
#include <dns/tcpmsg.h>
#include <dns/types.h>
#include <ns/query.h>

View File

@ -1231,7 +1231,6 @@
./lib/dns/include/dns/soa.h C 2000,2001,2004,2005,2006,2007,2009,2016,2018,2019,2020,2021
./lib/dns/include/dns/ssu.h C 2000,2001,2003,2004,2005,2006,2007,2008,2010,2011,2016,2017,2018,2019,2020,2021
./lib/dns/include/dns/stats.h C 2000,2001,2004,2005,2006,2007,2008,2009,2012,2014,2015,2016,2017,2018,2019,2020,2021
./lib/dns/include/dns/tcpmsg.h C 1999,2000,2001,2004,2005,2006,2007,2015,2016,2018,2019,2020,2021
./lib/dns/include/dns/time.h C 1999,2000,2001,2004,2005,2006,2007,2012,2016,2018,2019,2020,2021
./lib/dns/include/dns/timer.h C 2000,2001,2004,2005,2006,2007,2016,2018,2019,2020,2021
./lib/dns/include/dns/tkey.h C 1999,2000,2001,2004,2005,2006,2007,2009,2010,2011,2016,2018,2019,2020,2021
@ -1471,7 +1470,6 @@
./lib/dns/ssu.c C 2000,2001,2003,2004,2005,2006,2007,2008,2010,2011,2013,2014,2016,2017,2018,2019,2020,2021
./lib/dns/ssu_external.c C 2011,2012,2013,2016,2017,2018,2019,2020,2021
./lib/dns/stats.c C 2000,2001,2004,2005,2007,2008,2009,2012,2016,2018,2019,2020,2021
./lib/dns/tcpmsg.c C 1999,2000,2001,2004,2005,2006,2007,2015,2016,2018,2019,2020,2021
./lib/dns/tests/Kdh.+002+18602.key X 2014,2018,2019,2020,2021
./lib/dns/tests/Krsa.+005+29235.key X 2016,2018,2019,2020,2021
./lib/dns/tests/acl_test.c C 2016,2018,2019,2020,2021