mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 06:55:30 +00:00
clean up when socket is shut down; commented
This commit is contained in:
@@ -60,6 +60,7 @@ static void tcp_send(isc_task_t *task, isc_event_t *event);
|
|||||||
static void tcp_recv_len(isc_task_t *task, isc_event_t *event);
|
static void tcp_recv_len(isc_task_t *task, isc_event_t *event);
|
||||||
static void tcp_recv_req(isc_task_t *task, isc_event_t *event);
|
static void tcp_recv_req(isc_task_t *task, isc_event_t *event);
|
||||||
static void tcp_accept(isc_task_t *task, isc_event_t *event);
|
static void tcp_accept(isc_task_t *task, isc_event_t *event);
|
||||||
|
static void tcp_listener_free(tcp_listener_t **lp);
|
||||||
|
|
||||||
static tcp_cctx_t *
|
static tcp_cctx_t *
|
||||||
tcp_cctx_allocate(isc_mem_t *mctx)
|
tcp_cctx_allocate(isc_mem_t *mctx)
|
||||||
@@ -112,24 +113,26 @@ tcp_restart(isc_task_t *task, tcp_cctx_t *ctx)
|
|||||||
isc_mem_stats(ctx->mctx, stdout);
|
isc_mem_stats(ctx->mctx, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A worker task is shutting down, presumably because the
|
||||||
|
* socket has been shut down.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
tcp_shutdown(isc_task_t *task, isc_event_t *event)
|
tcp_shutdown(isc_task_t *task, isc_event_t *event)
|
||||||
{
|
{
|
||||||
tcp_cctx_t *ctx;
|
tcp_cctx_t *ctx;
|
||||||
tcp_listener_t *l;
|
tcp_listener_t *l;
|
||||||
|
isc_boolean_t free_listener = ISC_FALSE;
|
||||||
|
|
||||||
ctx = (tcp_cctx_t *)(event->arg);
|
ctx = (tcp_cctx_t *)(event->arg);
|
||||||
l = ctx->parent;
|
l = ctx->parent;
|
||||||
|
|
||||||
LOCK(&l->lock);
|
LOCK(&l->lock);
|
||||||
|
|
||||||
if (ctx->csock != NULL)
|
|
||||||
isc_socket_detach(&ctx->csock);
|
|
||||||
|
|
||||||
REQUIRE(l->nwactive > 0);
|
REQUIRE(l->nwactive > 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove our task from the list of tasks that the listener
|
* Remove our task from the list of tasks that the listener
|
||||||
* maintains by setting things to NULL, then freeing the
|
* maintains by setting things to NULL, then freeing the
|
||||||
* pointers we maintain.
|
* pointers we maintain.
|
||||||
*/
|
*/
|
||||||
@@ -139,16 +142,29 @@ tcp_shutdown(isc_task_t *task, isc_event_t *event)
|
|||||||
|
|
||||||
l->nwactive--;
|
l->nwactive--;
|
||||||
|
|
||||||
|
if (l->nwactive == 0)
|
||||||
|
free_listener = ISC_TRUE;
|
||||||
|
|
||||||
UNLOCK(&l->lock);
|
UNLOCK(&l->lock);
|
||||||
|
|
||||||
#ifdef NOISY
|
#ifdef NOISY
|
||||||
printf("Final shutdown slot %u\n", ctx->slot);
|
printf("Final shutdown slot %u\n", ctx->slot);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This is where the pointers are freed. */
|
||||||
tcp_cctx_free(ctx);
|
tcp_cctx_free(ctx);
|
||||||
|
isc_task_detach(&task);
|
||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
|
if (free_listener)
|
||||||
|
tcp_listener_free(&l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have received the 2-byte length prefix (or a socket shutdown
|
||||||
|
* request).
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
tcp_recv_len(isc_task_t *task, isc_event_t *event)
|
tcp_recv_len(isc_task_t *task, isc_event_t *event)
|
||||||
{
|
{
|
||||||
@@ -209,6 +225,9 @@ tcp_recv_len(isc_task_t *task, isc_event_t *event)
|
|||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have received the actual request data.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
tcp_recv_req(isc_task_t *task, isc_event_t *event)
|
tcp_recv_req(isc_task_t *task, isc_event_t *event)
|
||||||
{
|
{
|
||||||
@@ -419,6 +438,18 @@ tcp_listener_allocate(isc_mem_t *mctx, u_int nwmax)
|
|||||||
return (l);
|
return (l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
tcp_listener_free(tcp_listener_t **lp)
|
||||||
|
{
|
||||||
|
tcp_listener_t *l = *lp;
|
||||||
|
isc_mem_put(l->mctx, l->ctxs, sizeof(tcp_cctx_t *) * l->nwmax);
|
||||||
|
isc_mem_put(l->mctx, l->tasks, sizeof(isc_task_t *) * l->nwmax);
|
||||||
|
isc_mutex_destroy(&l->lock);
|
||||||
|
isc_mem_put(l->mctx, l, sizeof(tcp_listener_t));
|
||||||
|
*lp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
tcp_listener_start(tcp_listener_t *l,
|
tcp_listener_start(tcp_listener_t *l,
|
||||||
isc_socket_t *sock, isc_taskmgr_t *tmgr,
|
isc_socket_t *sock, isc_taskmgr_t *tmgr,
|
||||||
|
@@ -55,3 +55,10 @@ isc_result_t tcp_listener_start(tcp_listener_t *l,
|
|||||||
dns_result_t (*dispatch)(isc_mem_t *,
|
dns_result_t (*dispatch)(isc_mem_t *,
|
||||||
isc_region_t *,
|
isc_region_t *,
|
||||||
unsigned int));
|
unsigned int));
|
||||||
|
/*
|
||||||
|
* Notes:
|
||||||
|
* There is no need to hold on to the udp_listener_t * after starting
|
||||||
|
* the listener, and here is no need to shut down the listener explicitly.
|
||||||
|
* It will shut down itself and free its resources when its socket is
|
||||||
|
* shut down.
|
||||||
|
*/
|
||||||
|
@@ -52,7 +52,7 @@ static void udp_cctx_free(udp_cctx_t *ctx);
|
|||||||
|
|
||||||
static void udp_send(isc_task_t *task, isc_event_t *event);
|
static void udp_send(isc_task_t *task, isc_event_t *event);
|
||||||
static void udp_recv(isc_task_t *task, isc_event_t *event);
|
static void udp_recv(isc_task_t *task, isc_event_t *event);
|
||||||
|
static void udp_listener_free(udp_listener_t **lp);
|
||||||
|
|
||||||
|
|
||||||
static udp_cctx_t *
|
static udp_cctx_t *
|
||||||
@@ -83,12 +83,16 @@ udp_cctx_free(udp_cctx_t *ctx)
|
|||||||
isc_mem_put(ctx->mctx, ctx, sizeof(udp_cctx_t));
|
isc_mem_put(ctx->mctx, ctx, sizeof(udp_cctx_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A worker task is shutting down, presumably because the
|
||||||
|
* socket has been shut down.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
udp_shutdown(isc_task_t *task, isc_event_t *event)
|
udp_shutdown(isc_task_t *task, isc_event_t *event)
|
||||||
{
|
{
|
||||||
udp_cctx_t *ctx;
|
udp_cctx_t *ctx;
|
||||||
udp_listener_t *l;
|
udp_listener_t *l;
|
||||||
isc_socket_t *sock;
|
isc_boolean_t free_listener = ISC_FALSE;
|
||||||
|
|
||||||
ctx = (udp_cctx_t *)(event->arg);
|
ctx = (udp_cctx_t *)(event->arg);
|
||||||
l = ctx->parent;
|
l = ctx->parent;
|
||||||
@@ -98,29 +102,40 @@ udp_shutdown(isc_task_t *task, isc_event_t *event)
|
|||||||
REQUIRE(l->nwactive > 0);
|
REQUIRE(l->nwactive > 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* remove our task from the list of tasks that the listener
|
* Remove our task from the list of tasks that the listener
|
||||||
* maintains by setting things to NULL, then freeing the
|
* maintains by setting things to NULL, then freeing the
|
||||||
* pointers we maintain.
|
* pointers we maintain.
|
||||||
*/
|
*/
|
||||||
INSIST(l->tasks[ctx->slot] == task);
|
INSIST(l->tasks[ctx->slot] == task);
|
||||||
l->tasks[ctx->slot] = NULL;
|
l->tasks[ctx->slot] = NULL;
|
||||||
|
INSIST(l->ctxs[ctx->slot] == ctx);
|
||||||
l->ctxs[ctx->slot] = NULL;
|
l->ctxs[ctx->slot] = NULL;
|
||||||
|
|
||||||
l->nwactive--;
|
l->nwactive--;
|
||||||
|
|
||||||
sock = l->sock;
|
if (l->nwactive == 0)
|
||||||
isc_socket_detach(&sock);
|
free_listener = ISC_TRUE;
|
||||||
|
|
||||||
UNLOCK(&l->lock);
|
UNLOCK(&l->lock);
|
||||||
|
|
||||||
#ifdef NOISY
|
#ifdef NOISY
|
||||||
printf("Final shutdown slot %u\n", ctx->slot);
|
printf("Final shutdown slot %u\n", ctx->slot);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This is where the pointers are freed. */
|
||||||
udp_cctx_free(ctx);
|
udp_cctx_free(ctx);
|
||||||
|
isc_task_detach(&task);
|
||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
|
|
||||||
|
if (free_listener)
|
||||||
|
udp_listener_free(&l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We got the data we were waiting to receive, or
|
||||||
|
* a socket shutdown request.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
udp_recv(isc_task_t *task, isc_event_t *event)
|
udp_recv(isc_task_t *task, isc_event_t *event)
|
||||||
{
|
{
|
||||||
@@ -157,13 +172,21 @@ udp_recv(isc_task_t *task, isc_event_t *event)
|
|||||||
result = ctx->parent->dispatch(ctx->mctx, ®ion, 0);
|
result = ctx->parent->dispatch(ctx->mctx, ®ion, 0);
|
||||||
|
|
||||||
if (result == DNS_R_SUCCESS) {
|
if (result == DNS_R_SUCCESS) {
|
||||||
|
/* Send a reply as soon as the socket is ready to do so. */
|
||||||
isc_socket_sendto(sock, ®ion, task, udp_send, ctx,
|
isc_socket_sendto(sock, ®ion, task, udp_send, ctx,
|
||||||
&dev->address, dev->addrlength);
|
&dev->address, dev->addrlength);
|
||||||
|
} else {
|
||||||
|
/* Send no reply, just wait for the next request. */
|
||||||
|
isc_socket_recv(sock, ®ion, ISC_FALSE, task, udp_recv, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_event_free(&event);
|
isc_event_free(&event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The data we were waiting to send was sent, or we got a socket
|
||||||
|
* shutdown request.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
udp_send(isc_task_t *task, isc_event_t *event)
|
udp_send(isc_task_t *task, isc_event_t *event)
|
||||||
{
|
{
|
||||||
@@ -234,6 +257,19 @@ udp_listener_allocate(isc_mem_t *mctx, u_int nwmax)
|
|||||||
return (l);
|
return (l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
udp_listener_free(udp_listener_t **lp)
|
||||||
|
{
|
||||||
|
udp_listener_t *l = *lp;
|
||||||
|
isc_mem_put(l->mctx, l->ctxs, sizeof(udp_cctx_t *) * l->nwmax);
|
||||||
|
l->ctxs = NULL;
|
||||||
|
isc_mem_put(l->mctx, l->tasks, sizeof(isc_task_t *) * l->nwmax);
|
||||||
|
l->tasks = NULL;
|
||||||
|
isc_mutex_destroy(&l->lock);
|
||||||
|
isc_mem_put(l->mctx, l, sizeof(udp_listener_t));
|
||||||
|
*lp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
udp_listener_start(udp_listener_t *l,
|
udp_listener_start(udp_listener_t *l,
|
||||||
isc_socket_t *sock, isc_taskmgr_t *tmgr,
|
isc_socket_t *sock, isc_taskmgr_t *tmgr,
|
||||||
|
@@ -55,3 +55,10 @@ isc_result_t udp_listener_start(udp_listener_t *l,
|
|||||||
dns_result_t (*dispatch)(isc_mem_t *,
|
dns_result_t (*dispatch)(isc_mem_t *,
|
||||||
isc_region_t *,
|
isc_region_t *,
|
||||||
unsigned int));
|
unsigned int));
|
||||||
|
/*
|
||||||
|
* Notes:
|
||||||
|
* There is no need to hold on to the udp_listener_t * after starting
|
||||||
|
* the listener, and here is no need to shut down the listener explicitly.
|
||||||
|
* It will shut down itself and free its resources when its socket is
|
||||||
|
* shut down.
|
||||||
|
*/
|
||||||
|
Reference in New Issue
Block a user