load: implemented option loading diff from ZF ignoring serial

This commit is contained in:
Libor Peltan 2018-06-22 11:52:53 +02:00 committed by Daniel Salzman
parent 5620e73875
commit f8cd4feca0
7 changed files with 64 additions and 6 deletions

View file

@ -982,7 +982,7 @@ zone:
semantic\-checks: BOOL
disable\-any: BOOL
zonefile\-sync: TIME
zonefile\-load: none | difference | whole
zonefile\-load: none | difference | difference\-no\-serial | whole
journal\-content: none | changes | all
max\-journal\-usage: SIZE
max\-journal\-depth: INT
@ -1141,8 +1141,11 @@ Possible values:
.IP \(bu 2
\fBnone\fP The zonefile is not used at all.
.IP \(bu 2
\fBdifference\fP If the zone contents are available during server start or reload,
the difference is computed between them and the zonefile, checked and applied afterwards.
\fBdifference\fP If the zone contents is available during server start or reload,
the difference is computed between them and the zonefile, checked, and applied afterwards.
.IP \(bu 2
\fBdifference\-no\-serial\fP Same as \fBdifference\fP, but the SOA serial in the zonefile is
ignored, the server takes care of incrementing the serial automatically.
.IP \(bu 2
\fBwhole\fP Zone contents are loaded from zonefile.
.UNINDENT

View file

@ -1113,7 +1113,7 @@ Definition of zones served by the server.
semantic-checks: BOOL
disable-any: BOOL
zonefile-sync: TIME
zonefile-load: none | difference | whole
zonefile-load: none | difference | difference-no-serial | whole
journal-content: none | changes | all
max-journal-usage: SIZE
max-journal-depth: INT
@ -1288,8 +1288,10 @@ Selects how the zonefile contents are applied during zone load.
Possible values:
- ``none`` The zonefile is not used at all.
- ``difference`` If the zone contents are available during server start or reload,
the difference is computed between them and the zonefile, checked and applied afterwards.
- ``difference`` If the zone contents is available during server start or reload,
the difference is computed between them and the zonefile, checked, and applied afterwards.
- ``difference-no-serial`` Same as ``difference``, but the SOA serial in the zonefile is
ignored, the server takes care of incrementing the serial automatically.
- ``whole`` Zone contents are loaded from zonefile.
When ``difference`` is configured and there are no zone contents yet (cold start of Knot

View file

@ -103,6 +103,7 @@ static const knot_lookup_t journal_content[] = {
static const knot_lookup_t zonefile_load[] = {
{ ZONEFILE_LOAD_NONE, "none" },
{ ZONEFILE_LOAD_DIFF, "difference" },
{ ZONEFILE_LOAD_DIFSE, "difference-no-serial" },
{ ZONEFILE_LOAD_WHOLE, "whole" },
{ 0, NULL }
};

View file

@ -145,6 +145,7 @@ enum {
ZONEFILE_LOAD_NONE = 0,
ZONEFILE_LOAD_DIFF = 1,
ZONEFILE_LOAD_WHOLE = 2,
ZONEFILE_LOAD_DIFSE = 3,
};
extern const knot_lookup_t acl_actions[];

View file

@ -95,6 +95,17 @@ int event_load(conf_t *conf, zone_t *zone)
}
goto cleanup;
}
// If configured and possible, fix the SOA serial of zonefile.
if (zf_conts != NULL && zf_from == ZONEFILE_LOAD_DIFSE) {
zone_contents_t *relevant = (zone->contents != NULL ? zone->contents : journal_conts);
if (relevant != NULL) {
uint32_t serial = zone_contents_serial(relevant);
conf_val_t policy = conf_zone_get(conf, C_SERIAL_POLICY, zone->name);
zone_contents_set_soa_serial(zf_conts, serial_next(serial, conf_opt(&policy)));
}
}
// If configured and appliable to zonefile, load journal changes.
zone->zonefile.serial = zone_contents_serial(zf_conts);
zone->zonefile.exists = (zf_conts != NULL);
@ -201,6 +212,17 @@ int event_load(conf_t *conf, zone_t *zone)
zf_conts = NULL;
journal_conts = NULL;
// If the change is only automatically incremented SOA serial, make it no change.
if (zf_from == ZONEFILE_LOAD_DIFSE && (up.flags & UPDATE_INCREMENTAL) &&
changeset_differs_just_serial(&up.change)) {
uint32_t orig_ser = knot_soa_serial(&up.change.soa_from->rrs);
ret = changeset_remove_addition(&up.change, up.change.soa_to);
zone_contents_set_soa_serial(up.new_cont, orig_ser);
if (ret != KNOT_EOK) {
goto cleanup;
}
}
// Sign zone using DNSSEC if configured.
zone_sign_reschedule_t dnssec_refresh = { .allow_rollover = true, .allow_nsec3resalt = true, };
if (dnssec_enable) {

View file

@ -531,6 +531,25 @@ int changeset_cancelout(changeset_t *ch)
return ret;
}
bool changeset_differs_just_serial(const changeset_t *ch)
{
if (ch == NULL || ch->soa_from == NULL || ch->soa_to == NULL) {
return false;
}
if (!zone_contents_is_empty(ch->remove) || !zone_contents_is_empty(ch->add)) {
return false;
}
knot_rrset_t *soa_to_cpy = knot_rrset_copy(ch->soa_to, NULL);
knot_soa_serial_set(&soa_to_cpy->rrs, knot_soa_serial(&ch->soa_from->rrs));
bool res = knot_rrset_equal(ch->soa_from, soa_to_cpy, KNOT_RRSET_COMPARE_WHOLE);
knot_rrset_free(soa_to_cpy, NULL);
return res;
}
int changeset_to_contents(changeset_t *ch, zone_contents_t **out)
{
assert(ch->soa_from == NULL);

View file

@ -158,6 +158,16 @@ int changeset_preapply_fix(const zone_contents_t *zone, changeset_t *ch);
*/
int changeset_cancelout(changeset_t *ch);
/*!
* \brief Check the changes and SOA, ignoring possibly updated SOA serial.
*
* \param ch Changeset in question.
*
* \return false if the changeset changes other records than SOA, or some SOA field other than serial changed
* true otherwise
*/
bool changeset_differs_just_serial(const changeset_t *ch);
/*!
* \brief Loads zone contents from botstrap changeset.
*