40 #include <sys/socket.h>
42 static const char* notify_str =
"notify";
44 static void notify_handle_zone(
netio_type* netio,
55 ods_log_assert(notify);
75 if(t > notify_time(notify) + 10) {
76 time_t extra = t - notify_time(notify);
77 time_t base = extra*9/10;
78 #ifdef HAVE_ARC4RANDOM_UNIFORM
79 t = notify_time(notify) + base +
80 arc4random_uniform(extra-base);
82 t = notify_time(notify) + base +
83 arc4random()%(extra-base);
85 t = notify_time(notify) + base +
86 random()%(extra-base);
103 if (!xfrhandler || !zone) {
108 ods_log_error(
"[%s] unable to create notify structure: "
109 " allocator_alloc() failed", notify_str);
150 ods_log_assert(zone);
157 ods_log_debug(
"[%s] setup notify for zone %s", notify_str, zone->
name);
158 notify_set_timer(notify, notify_time(notify));
175 ods_log_assert(xfrhandler);
177 ods_log_assert(zone);
178 ods_log_assert(zone->
name);
195 ods_log_debug(
"[%s] zone %s notify off waiting list",
196 notify_str, zone->
name);
202 ods_log_debug(
"[%s] notify for zone %s disabled", notify_str, zone->
name);
221 ods_log_assert(zone);
222 ods_log_assert(zone->
name);
223 ods_log_debug(
"[%s] zone %s no more secondaries, disable notify",
224 notify_str, zone->
name);
225 notify_disable(notify);
238 ssize_t received = 0;
239 ods_log_assert(notify);
241 ods_log_assert(xfrhandler);
245 if (received == -1) {
246 ods_log_error(
"[%s] unable to read packet: recvfrom() failed fd %d "
247 "(%s)", notify_str, notify->
handler.
fd, strerror(errno));
264 ods_log_assert(notify);
269 ods_log_assert(xfrhandler);
270 ods_log_assert(zone);
271 ods_log_assert(zone->
name);
275 ods_log_error(
"[%s] zone %s received bad notify reply opcode/qr from %s",
280 ods_log_error(
"[%s] zone %s received bad notify reply id from %s",
287 ods_log_error(
"[%s] zone %s received bad notify rcode %s from %s",
288 notify_str, zone->
name, str?str:
"UNKNOWN",
295 ods_log_debug(
"[%s] zone %s secondary %s notify reply ok", notify_str,
308 struct sockaddr_storage to;
309 socklen_t to_len = 0;
313 ods_log_assert(buffer);
314 ods_log_assert(notify);
324 fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
326 ods_log_error(
"[%s] unable to send data over udp to %s: "
332 interface_type interface = notify->xfrhandler->engine->dnshandler->interfaces->interfaces[0];
333 if (!interface.address) {
334 ods_log_error(
"[%s] unable to get the address of interface", notify_str);
339 struct sockaddr_in addr;
341 addr.sin_addr = interface.addr.addr;
343 if (bind(fd, (
struct sockaddr *) &addr,
sizeof(addr)) != 0) {
344 ods_log_error(
"[%s] unable to bind address %s: bind failed %s", notify_str, interface.address, strerror(errno));
350 struct sockaddr_in6 addr6;
352 addr6.sin6_addr = interface.addr.addr6;
354 if (bind(fd, (
struct sockaddr *) &addr6,
sizeof(addr6)) != 0) {
355 ods_log_error(
"[%s] unable to bind address %s: bind() failed %s", notify_str, interface.address, strerror(errno));
362 ods_log_deeebug(
"[%s] send %ld bytes over udp to %s", notify_str,
365 (
struct sockaddr*)&to, to_len);
367 ods_log_error(
"[%s] unable to send data over udp to %s: "
392 ods_log_error(
"[%s] unable to sign notify: tsig unknown algorithm "
396 ods_log_assert(algo);
409 ods_log_debug(
"[%s] tsig append rr to notify id=%u", notify_str,
426 ods_log_assert(notify);
431 ods_log_assert(xfrhandler);
432 ods_log_assert(zone);
433 ods_log_assert(zone->
name);
449 notify_tsig_sign(notify, xfrhandler->
packet);
454 ods_log_error(
"[%s] unable to send notify retry %u for zone %s to "
455 "%s: notify_send_udp() failed", notify_str, notify->
retry,
459 ods_log_verbose(
"[%s] notify retry %u for zone %s sent to %s", notify_str,
469 notify_handle_zone(
netio_type* ATTR_UNUSED(netio),
479 ods_log_assert(notify);
482 ods_log_assert(xfrhandler);
483 ods_log_assert(zone);
484 ods_log_assert(zone->
name);
485 ods_log_debug(
"[%s] handle notify for zone %s", notify_str, zone->
name);
488 ods_log_debug(
"[%s] already waiting, skipping notify for zone %s",
489 notify_str, zone->
name);
490 ods_log_assert(notify->
handler.
fd == -1);
494 ods_log_debug(
"[%s] read notify ok for zone %s", notify_str,
496 ods_log_assert(notify->
handler.
fd != -1);
497 if (notify_udp_read_packet(notify)) {
498 if (notify_handle_reply(notify)) {
503 ods_log_debug(
"[%s] notify timeout for zone %s", notify_str,
512 ods_log_verbose(
"[%s] notify max retry for zone %s, %s unreachable",
527 notify_update_soa(
notify_type* notify, ldns_rr* soa)
533 ldns_rr_free(notify->
soa);
553 ods_log_assert(xfrhandler);
555 ods_log_assert(zone);
556 ods_log_assert(zone->
name);
562 ods_log_warning(
"[%s] zone %s has no notify acl", notify_str,
567 ods_log_debug(
"[%s] zone %s already on waiting list", notify_str,
571 notify_update_soa(notify, soa);
573 notify_setup(notify);
575 ods_log_debug(
"[%s] zone %s notify enabled", notify_str,
590 ods_log_debug(
"[%s] zone %s notify on waiting list", notify_str,
610 ldns_rr_free(notify->
soa);
int acl_parse_family(const char *a)
void buffer_clear(buffer_type *buffer)
void buffer_set_limit(buffer_type *buffer, size_t limit)
int buffer_pkt_qr(buffer_type *buffer)
ldns_pkt_opcode buffer_pkt_opcode(buffer_type *buffer)
uint8_t * buffer_begin(buffer_type *buffer)
ldns_pkt_rcode buffer_pkt_rcode(buffer_type *buffer)
void buffer_flip(buffer_type *buffer)
size_t buffer_position(buffer_type *buffer)
void buffer_pkt_notify(buffer_type *buffer, ldns_rdf *qname, ldns_rr_class qclass)
uint16_t buffer_pkt_arcount(buffer_type *buffer)
uint8_t * buffer_current(buffer_type *buffer)
size_t buffer_remaining(buffer_type *buffer)
const char * buffer_rcode2str(ldns_pkt_rcode rcode)
int buffer_write_rr(buffer_type *buffer, ldns_rr *rr)
void buffer_pkt_set_ancount(buffer_type *buffer, uint16_t count)
void buffer_pkt_set_aa(buffer_type *buffer)
void buffer_pkt_set_arcount(buffer_type *buffer, uint16_t count)
uint16_t buffer_pkt_id(buffer_type *buffer)
void log_dname(ldns_rdf *rdf, const char *pre, int level)
enum netio_events_enum netio_events_type
notify_type * notify_create(xfrhandler_type *xfrhandler, zone_type *zone)
void notify_send(notify_type *notify)
void notify_cleanup(notify_type *notify)
void notify_enable(notify_type *notify, ldns_rr *soa)
#define NOTIFY_RETRY_TIMEOUT
struct timespec * timeout
netio_events_type event_types
netio_event_handler_type event_handler
notify_type * waiting_next
xfrhandler_type * xfrhandler
netio_handler_type handler
uint16_t original_query_id
notify_type * notify_waiting_last
notify_type * notify_waiting_first
adapter_type * adoutbound
void tsig_rr_cleanup(tsig_rr_type *trr)
tsig_algo_type * tsig_lookup_algo(const char *name)
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
void tsig_rr_sign(tsig_rr_type *trr)
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
void tsig_rr_prepare(tsig_rr_type *trr)
tsig_rr_type * tsig_rr_create()
socklen_t xfrd_acl_sockaddr_to(acl_type *acl, struct sockaddr_storage *to)
time_t xfrhandler_time(xfrhandler_type *xfrhandler)