mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 07:35:26 +00:00
Reimplement the max-transfer-time-out and max-transfer-idle-out
While refactoring the libns to use the new network manager, the max-transfer-*-out options were not implemented and they were turned non-operational. Reimplement the max-transfer-idle-out functionality using the write timer and max-transfer-time-out using the new isc_nm_timer API.
This commit is contained in:
107
lib/ns/xfrout.c
107
lib/ns/xfrout.c
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <isc/formatcheck.h>
|
#include <isc/formatcheck.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
|
#include <isc/netmgr.h>
|
||||||
#include <isc/print.h>
|
#include <isc/print.h>
|
||||||
#include <isc/result.h>
|
#include <isc/result.h>
|
||||||
#include <isc/stats.h>
|
#include <isc/stats.h>
|
||||||
@@ -668,6 +669,12 @@ typedef struct {
|
|||||||
const char *mnemonic; /* Style of transfer */
|
const char *mnemonic; /* Style of transfer */
|
||||||
uint32_t end_serial; /* Serial number after XFR is done */
|
uint32_t end_serial; /* Serial number after XFR is done */
|
||||||
struct xfr_stats stats; /*%< Transfer statistics */
|
struct xfr_stats stats; /*%< Transfer statistics */
|
||||||
|
|
||||||
|
/* Timeouts */
|
||||||
|
uint64_t maxtime; /*%< Maximum XFR timeout (in ms) */
|
||||||
|
isc_nm_timer_t *maxtime_timer;
|
||||||
|
|
||||||
|
uint64_t idletime; /*%< XFR idle timeout (in ms) */
|
||||||
} xfrout_ctx_t;
|
} xfrout_ctx_t;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -695,6 +702,9 @@ xfrout_maybe_destroy(xfrout_ctx_t *xfr);
|
|||||||
static void
|
static void
|
||||||
xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
|
xfrout_ctx_destroy(xfrout_ctx_t **xfrp);
|
||||||
|
|
||||||
|
static void
|
||||||
|
xfrout_client_timeout(void *arg, isc_result_t result);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xfrout_log1(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
|
xfrout_log1(ns_client_t *client, dns_name_t *zonename, dns_rdataclass_t rdclass,
|
||||||
int level, const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
|
int level, const char *fmt, ...) ISC_FORMAT_PRINTF(5, 6);
|
||||||
@@ -1143,6 +1153,14 @@ have_stream:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Start the timers */
|
||||||
|
if (xfr->maxtime > 0) {
|
||||||
|
xfrout_log(xfr, ISC_LOG_ERROR,
|
||||||
|
"starting maxtime timer %" PRIu64 " ms",
|
||||||
|
xfr->maxtime);
|
||||||
|
isc_nm_timer_start(xfr->maxtime_timer, xfr->maxtime);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hand the context over to sendstream(). Set xfr to NULL;
|
* Hand the context over to sendstream(). Set xfr to NULL;
|
||||||
* sendstream() is responsible for either passing the
|
* sendstream() is responsible for either passing the
|
||||||
@@ -1202,64 +1220,52 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
|||||||
bool verified_tsig, unsigned int maxtime,
|
bool verified_tsig, unsigned int maxtime,
|
||||||
unsigned int idletime, bool many_answers,
|
unsigned int idletime, bool many_answers,
|
||||||
xfrout_ctx_t **xfrp) {
|
xfrout_ctx_t **xfrp) {
|
||||||
xfrout_ctx_t *xfr;
|
xfrout_ctx_t *xfr = NULL;
|
||||||
unsigned int len;
|
unsigned int len = NS_CLIENT_TCP_BUFFER_SIZE;
|
||||||
void *mem;
|
void *mem = NULL;
|
||||||
|
|
||||||
REQUIRE(xfrp != NULL && *xfrp == NULL);
|
REQUIRE(xfrp != NULL && *xfrp == NULL);
|
||||||
|
|
||||||
UNUSED(maxtime);
|
|
||||||
UNUSED(idletime);
|
|
||||||
|
|
||||||
xfr = isc_mem_get(mctx, sizeof(*xfr));
|
xfr = isc_mem_get(mctx, sizeof(*xfr));
|
||||||
xfr->mctx = NULL;
|
*xfr = (xfrout_ctx_t){
|
||||||
|
.client = client,
|
||||||
|
.id = id,
|
||||||
|
.qname = qname,
|
||||||
|
.qtype = qtype,
|
||||||
|
.qclass = qclass,
|
||||||
|
.maxtime = maxtime * 1000, /* in milliseconds */
|
||||||
|
.idletime = idletime * 1000, /* In milliseconds */
|
||||||
|
.tsigkey = tsigkey,
|
||||||
|
.lasttsig = lasttsig,
|
||||||
|
.verified_tsig = verified_tsig,
|
||||||
|
.many_answers = many_answers,
|
||||||
|
};
|
||||||
|
|
||||||
isc_mem_attach(mctx, &xfr->mctx);
|
isc_mem_attach(mctx, &xfr->mctx);
|
||||||
xfr->client = client;
|
|
||||||
xfr->id = id;
|
|
||||||
xfr->qname = qname;
|
|
||||||
xfr->qtype = qtype;
|
|
||||||
xfr->qclass = qclass;
|
|
||||||
xfr->zone = NULL;
|
|
||||||
xfr->db = NULL;
|
|
||||||
xfr->ver = NULL;
|
|
||||||
if (zone != NULL) { /* zone will be NULL if it's DLZ */
|
if (zone != NULL) { /* zone will be NULL if it's DLZ */
|
||||||
dns_zone_attach(zone, &xfr->zone);
|
dns_zone_attach(zone, &xfr->zone);
|
||||||
}
|
}
|
||||||
dns_db_attach(db, &xfr->db);
|
dns_db_attach(db, &xfr->db);
|
||||||
dns_db_attachversion(db, ver, &xfr->ver);
|
dns_db_attachversion(db, ver, &xfr->ver);
|
||||||
xfr->question_added = false;
|
|
||||||
xfr->end_of_stream = false;
|
|
||||||
xfr->tsigkey = tsigkey;
|
|
||||||
xfr->lasttsig = lasttsig;
|
|
||||||
xfr->verified_tsig = verified_tsig;
|
|
||||||
xfr->many_answers = many_answers;
|
|
||||||
xfr->sends = 0;
|
|
||||||
xfr->shuttingdown = false;
|
|
||||||
xfr->poll = false;
|
|
||||||
xfr->mnemonic = NULL;
|
|
||||||
xfr->buf.base = NULL;
|
|
||||||
xfr->buf.length = 0;
|
|
||||||
xfr->txmem = NULL;
|
|
||||||
xfr->txmemlen = 0;
|
|
||||||
xfr->stream = NULL;
|
|
||||||
xfr->quota = NULL;
|
|
||||||
|
|
||||||
xfr->stats.nmsg = 0;
|
|
||||||
xfr->stats.nrecs = 0;
|
|
||||||
xfr->stats.nbytes = 0;
|
|
||||||
isc_time_now(&xfr->stats.start);
|
isc_time_now(&xfr->stats.start);
|
||||||
|
|
||||||
|
isc_nm_timer_create(xfr->client->handle, xfrout_client_timeout, xfr,
|
||||||
|
&xfr->maxtime_timer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a temporary buffer for the uncompressed response
|
* Allocate a temporary buffer for the uncompressed response
|
||||||
* message data. The size should be no more than 65535 bytes
|
* message data. The buffer size must be 65535 bytes
|
||||||
* so that the compressed data will fit in a TCP message,
|
* (NS_CLIENT_TCP_BUFFER_SIZE): small enough that compressed
|
||||||
* and no less than 65535 bytes so that an almost maximum-sized
|
* data will fit in a single TCP message, and big enough to
|
||||||
* RR will fit. Note that although 65535-byte RRs are allowed
|
* hold a maximum-sized RR.
|
||||||
* in principle, they cannot be zone-transferred (at least not
|
*
|
||||||
* if uncompressible), because the message and RR headers would
|
* Note that although 65535-byte RRs are allowed in principle, they
|
||||||
* push the size of the TCP message over the 65536 byte limit.
|
* cannot be zone-transferred (at least not if uncompressible),
|
||||||
|
* because the message and RR headers would push the size of the
|
||||||
|
* TCP message over the 65536 byte limit.
|
||||||
*/
|
*/
|
||||||
len = 65535;
|
|
||||||
mem = isc_mem_get(mctx, len);
|
mem = isc_mem_get(mctx, len);
|
||||||
isc_buffer_init(&xfr->buf, mem, len);
|
isc_buffer_init(&xfr->buf, mem, len);
|
||||||
|
|
||||||
@@ -1267,7 +1273,6 @@ xfrout_ctx_create(isc_mem_t *mctx, ns_client_t *client, unsigned int id,
|
|||||||
* Allocate another temporary buffer for the compressed
|
* Allocate another temporary buffer for the compressed
|
||||||
* response message.
|
* response message.
|
||||||
*/
|
*/
|
||||||
len = NS_CLIENT_TCP_BUFFER_SIZE;
|
|
||||||
mem = isc_mem_get(mctx, len);
|
mem = isc_mem_get(mctx, len);
|
||||||
isc_buffer_init(&xfr->txbuf, (char *)mem, len);
|
isc_buffer_init(&xfr->txbuf, (char *)mem, len);
|
||||||
xfr->txmem = mem;
|
xfr->txmem = mem;
|
||||||
@@ -1557,6 +1562,10 @@ sendstream(xfrout_ctx_t *xfr) {
|
|||||||
|
|
||||||
isc_nmhandle_attach(xfr->client->handle,
|
isc_nmhandle_attach(xfr->client->handle,
|
||||||
&xfr->client->sendhandle);
|
&xfr->client->sendhandle);
|
||||||
|
if (xfr->idletime > 0) {
|
||||||
|
isc_nmhandle_setwritetimeout(xfr->client->sendhandle,
|
||||||
|
xfr->idletime);
|
||||||
|
}
|
||||||
isc_nm_send(xfr->client->sendhandle, &used, xfrout_senddone,
|
isc_nm_send(xfr->client->sendhandle, &used, xfrout_senddone,
|
||||||
xfr);
|
xfr);
|
||||||
xfr->sends++;
|
xfr->sends++;
|
||||||
@@ -1622,6 +1631,9 @@ xfrout_ctx_destroy(xfrout_ctx_t **xfrp) {
|
|||||||
|
|
||||||
INSIST(xfr->sends == 0);
|
INSIST(xfr->sends == 0);
|
||||||
|
|
||||||
|
isc_nm_timer_stop(xfr->maxtime_timer);
|
||||||
|
isc_nm_timer_detach(&xfr->maxtime_timer);
|
||||||
|
|
||||||
if (xfr->stream != NULL) {
|
if (xfr->stream != NULL) {
|
||||||
xfr->stream->methods->destroy(&xfr->stream);
|
xfr->stream->methods->destroy(&xfr->stream);
|
||||||
}
|
}
|
||||||
@@ -1726,6 +1738,15 @@ xfrout_maybe_destroy(xfrout_ctx_t *xfr) {
|
|||||||
xfrout_ctx_destroy(&xfr);
|
xfrout_ctx_destroy(&xfr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xfrout_client_timeout(void *arg, isc_result_t result) {
|
||||||
|
xfrout_ctx_t *xfr = (xfrout_ctx_t *)arg;
|
||||||
|
|
||||||
|
xfr->shuttingdown = true;
|
||||||
|
xfrout_log(xfr, ISC_LOG_ERROR, "%s: %s", "aborted",
|
||||||
|
isc_result_totext(result));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Log outgoing zone transfer messages in a format like
|
* Log outgoing zone transfer messages in a format like
|
||||||
* <client>: transfer of <zone>: <message>
|
* <client>: transfer of <zone>: <message>
|
||||||
|
Reference in New Issue
Block a user