Compare commits

...

2 Commits

Author SHA1 Message Date
Mark Andrews
aa05e17efe Add named option -T firstdelta 2024-10-02 07:30:28 +10:00
Mark Andrews
14dd4fc8ea Send single deltas IXFR responses 2024-10-01 12:03:26 +10:00
3 changed files with 63 additions and 10 deletions

View File

@@ -135,6 +135,7 @@ static bool dropedns = false;
static bool ednsformerr = false;
static bool ednsnotimp = false;
static bool ednsrefused = false;
static bool firstdelta = false;
static bool fixedlocal = false;
static bool noaa = false;
static bool noedns = false;
@@ -703,6 +704,8 @@ parse_T_opt(char *option) {
ednsnotimp = true;
} else if (!strcmp(option, "ednsrefused")) {
ednsrefused = true;
} else if (!strcmp(option, "firstdelta")) {
firstdelta = true;
} else if (!strcmp(option, "fixedlocal")) {
fixedlocal = true;
} else if (!strcmp(option, "keepstderr")) {
@@ -1297,6 +1300,9 @@ setup(void) {
if (ednsrefused) {
ns_server_setoption(sctx, NS_SERVER_EDNSREFUSED, true);
}
if (firstdelta) {
ns_server_setoption(sctx, NS_SERVER_FIRSTDELTA, true);
}
if (fixedlocal) {
ns_server_setoption(sctx, NS_SERVER_FIXEDLOCAL, true);
}

View File

@@ -50,6 +50,7 @@
#define NS_SERVER_TRANSFERSLOWLY 0x00010000U /*%< -T transferslowly */
#define NS_SERVER_TRANSFERSTUCK 0x00020000U /*%< -T transferstuck */
#define NS_SERVER_LOGRESPONSES 0x00040000U /*%< log responses */
#define NS_SERVER_FIRSTDELTA 0x00080000U /*%< only send first delta */
/*%
* Type for callback function to get hostname.

View File

@@ -228,8 +228,8 @@ static rrstream_methods_t ixfr_rrstream_methods;
static isc_result_t
ixfr_rrstream_create(isc_mem_t *mctx, const char *journal_filename,
uint32_t begin_serial, uint32_t end_serial, size_t *sizep,
rrstream_t **sp) {
uint32_t begin_serial, uint32_t *end_serial, size_t *sizep,
dns_difftuple_t **soa_tuple, rrstream_t **sp) {
isc_result_t result;
ixfr_rrstream_t *s = NULL;
@@ -243,9 +243,41 @@ ixfr_rrstream_create(isc_mem_t *mctx, const char *journal_filename,
CHECK(dns_journal_open(mctx, journal_filename, DNS_JOURNAL_READ,
&s->journal));
CHECK(dns_journal_iter_init(s->journal, begin_serial, end_serial,
CHECK(dns_journal_iter_init(s->journal, begin_serial, *end_serial,
sizep));
if (soa_tuple != NULL) {
unsigned int n_soa = 0;
INSIST(*soa_tuple == NULL);
CHECK(dns_journal_first_rr(s->journal));
for (result = dns_journal_first_rr(s->journal);
result == ISC_R_SUCCESS;
result = dns_journal_next_rr(s->journal))
{
dns_name_t *name = NULL;
dns_rdata_t *rdata = NULL;
uint32_t ttl;
dns_journal_current_rr(s->journal, &name, &ttl, &rdata);
if (rdata->type == dns_rdatatype_soa) {
n_soa++;
if (n_soa == 2) {
dns_rdata_soa_t soa;
dns_rdata_tostruct(rdata, &soa, NULL);
*end_serial = soa.serial;
dns_difftuple_create(
mctx, DNS_DIFFOP_EXISTS, name,
ttl, rdata, soa_tuple);
break;
}
}
}
CHECK(dns_journal_iter_init(s->journal, begin_serial,
*end_serial, sizep));
}
*sp = (rrstream_t *)s;
return (ISC_R_SUCCESS);
@@ -432,7 +464,7 @@ static rrstream_methods_t soa_rrstream_methods;
static isc_result_t
soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
rrstream_t **sp) {
dns_difftuple_t **soa_tuple, rrstream_t **sp) {
soa_rrstream_t *s;
isc_result_t result;
@@ -444,8 +476,14 @@ soa_rrstream_create(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *ver,
s->common.methods = &soa_rrstream_methods;
s->soa_tuple = NULL;
CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
&s->soa_tuple));
if (soa_tuple == NULL || *soa_tuple == NULL) {
CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_EXISTS,
&s->soa_tuple));
} else {
INSIST(*soa_tuple != NULL);
s->soa_tuple = *soa_tuple;
*soa_tuple = NULL;
}
*sp = (rrstream_t *)s;
return (ISC_R_SUCCESS);
@@ -753,6 +791,7 @@ ns_xfr_start(ns_client_t *client, dns_rdatatype_t reqtype) {
bool is_ixfr = false;
bool useviewacl = false;
uint32_t begin_serial = 0, current_serial;
dns_difftuple_t *soa_tuple = NULL;
switch (reqtype) {
case dns_rdatatype_axfr:
@@ -974,6 +1013,8 @@ got_soa:
if (reqtype == dns_rdatatype_ixfr) {
size_t jsize;
uint64_t dbsize;
bool firstdelta = ns_server_getoption(client->manager->sctx,
NS_SERVER_FIRSTDELTA);
if (!have_soa) {
FAILC(DNS_R_FORMERR, "IXFR request missing SOA");
@@ -995,7 +1036,8 @@ got_soa:
if (DNS_SERIAL_GE(begin_serial, current_serial) ||
(client->attributes & NS_CLIENTATTR_TCP) == 0)
{
CHECK(soa_rrstream_create(mctx, db, ver, &stream));
CHECK(soa_rrstream_create(mctx, db, ver, NULL,
&stream));
is_poll = true;
goto have_stream;
}
@@ -1025,8 +1067,9 @@ got_soa:
journalfile = is_dlz ? NULL : dns_zone_getjournal(zone);
if (journalfile != NULL) {
result = ixfr_rrstream_create(
mctx, journalfile, begin_serial, current_serial,
&jsize, &data_stream);
mctx, journalfile, begin_serial,
&current_serial, &jsize,
firstdelta ? &soa_tuple : NULL, &data_stream);
} else {
result = ISC_R_NOTFOUND;
}
@@ -1074,7 +1117,7 @@ got_soa:
/*
* Bracket the data stream with SOAs.
*/
CHECK(soa_rrstream_create(mctx, db, ver, &soa_stream));
CHECK(soa_rrstream_create(mctx, db, ver, &soa_tuple, &soa_stream));
CHECK(compound_rrstream_create(mctx, &soa_stream, &data_stream,
&stream));
soa_stream = NULL;
@@ -1176,6 +1219,9 @@ failure:
if (result == DNS_R_REFUSED) {
inc_stats(client, zone, ns_statscounter_xfrrej);
}
if (soa_tuple != NULL) {
dns_difftuple_free(&soa_tuple);
}
if (current_soa_tuple != NULL) {
dns_difftuple_free(&current_soa_tuple);
}