diff options
Diffstat (limited to '')
-rw-r--r-- | src/knot/events/handlers/notify.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/src/knot/events/handlers/notify.c b/src/knot/events/handlers/notify.c index ccddf88..9dae70a 100644 --- a/src/knot/events/handlers/notify.c +++ b/src/knot/events/handlers/notify.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2023 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> +/* Copyright (C) 2024 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,6 +15,7 @@ */ #include <assert.h> +#include <urcu.h> #include "contrib/openbsd/siphash.h" #include "knot/common/log.h" @@ -40,7 +41,7 @@ static notifailed_rmt_hash notifailed_hash(conf_val_t *rmt_id) struct notify_data { const knot_dname_t *zone; const knot_rrset_t *soa; - const struct sockaddr *remote; + const conf_remote_t *remote; query_edns_data_t edns; }; @@ -82,9 +83,9 @@ static const knot_layer_api_t NOTIFY_API = { }; #define NOTIFY_OUT_LOG(priority, zone, remote, flags, fmt, ...) \ - ns_log(priority, zone, LOG_OPERATION_NOTIFY, LOG_DIRECTION_OUT, remote, \ + ns_log(priority, zone, LOG_OPERATION_NOTIFY, LOG_DIRECTION_OUT, &(remote)->addr, \ ((flags) & KNOT_REQUESTOR_QUIC) ? KNOTD_QUERY_PROTO_QUIC : KNOTD_QUERY_PROTO_TCP, \ - ((flags) & KNOT_REQUESTOR_REUSED), fmt, ## __VA_ARGS__) + ((flags) & KNOT_REQUESTOR_REUSED), (remote)->key.name, fmt, ## __VA_ARGS__) static int send_notify(conf_t *conf, zone_t *zone, const knot_rrset_t *soa, const conf_remote_t *slave, int timeout, bool retry) @@ -92,7 +93,7 @@ static int send_notify(conf_t *conf, zone_t *zone, const knot_rrset_t *soa, struct notify_data data = { .zone = zone->name, .soa = soa, - .remote = (struct sockaddr *)&slave->addr, + .remote = slave, .edns = query_edns_data_init(conf, slave, 0) }; @@ -118,16 +119,16 @@ static int send_notify(conf_t *conf, zone_t *zone, const knot_rrset_t *soa, const char *log_retry = retry ? "retry, " : ""; if (ret == KNOT_EOK && knot_pkt_ext_rcode(req->resp) == 0) { - NOTIFY_OUT_LOG(LOG_INFO, zone->name, &slave->addr, + NOTIFY_OUT_LOG(LOG_INFO, zone->name, slave, requestor.layer.flags, "%sserial %u", log_retry, knot_soa_serial(soa->rrs.rdata)); zone->timers.last_notified_serial = (knot_soa_serial(soa->rrs.rdata) | LAST_NOTIFIED_SERIAL_VALID); } else if (knot_pkt_ext_rcode(req->resp) == 0) { - NOTIFY_OUT_LOG(LOG_WARNING, zone->name, &slave->addr, + NOTIFY_OUT_LOG(LOG_WARNING, zone->name, slave, requestor.layer.flags, "%sfailed (%s)", log_retry, knot_strerror(ret)); } else { - NOTIFY_OUT_LOG(LOG_WARNING, zone->name, &slave->addr, + NOTIFY_OUT_LOG(LOG_WARNING, zone->name, slave, requestor.layer.flags, "%sserver responded with error '%s'", log_retry, knot_pkt_ext_rcode_name(req->resp)); @@ -151,7 +152,13 @@ int event_notify(conf_t *conf, zone_t *zone) // NOTIFY content int timeout = conf->cache.srv_tcp_remote_io_timeout; + rcu_read_lock(); knot_rrset_t soa = node_rrset(zone->contents->apex, KNOT_RRTYPE_SOA); + knot_rrset_t *soa_cpy = knot_rrset_copy(&soa, NULL); + rcu_read_unlock(); + if (soa_cpy == NULL) { + return KNOT_ENOMEM; + } // in case of re-try, NOTIFY only failed remotes pthread_mutex_lock(&zone->preferred_lock); @@ -176,7 +183,7 @@ int event_notify(conf_t *conf, zone_t *zone) for (int i = 0; i < addr_count; i++) { conf_remote_t slave = conf_remote(conf, iter.id, i); - ret = send_notify(conf, zone, &soa, &slave, timeout, retry); + ret = send_notify(conf, zone, soa_cpy, &slave, timeout, retry); if (ret == KNOT_EOK) { break; } @@ -196,7 +203,7 @@ int event_notify(conf_t *conf, zone_t *zone) if (failed) { notifailed_rmt_dynarray_sort_dedup(&zone->notifailed); - uint32_t retry_in = knot_soa_retry(soa.rrs.rdata); + uint32_t retry_in = knot_soa_retry(soa_cpy->rrs.rdata); conf_val_t val = conf_zone_get(conf, C_RETRY_MIN_INTERVAL, zone->name); retry_in = MAX(retry_in, conf_int(&val)); val = conf_zone_get(conf, C_RETRY_MAX_INTERVAL, zone->name); @@ -205,6 +212,7 @@ int event_notify(conf_t *conf, zone_t *zone) zone_events_schedule_at(zone, ZONE_EVENT_NOTIFY, time(NULL) + retry_in); } pthread_mutex_unlock(&zone->preferred_lock); + knot_rrset_free(soa_cpy, NULL); return failed ? KNOT_ERROR : KNOT_EOK; } |