static void xfrd_notify_send_udp(struct notify_zone_t* zone, buffer_type* packet) { int fd; if(zone->notify_send_enable) { notify_send_disable(zone); } /* Set timeout for next reply */ zone->notify_timeout.tv_sec = XFRD_NOTIFY_RETRY_TIMOUT; /* send NOTIFY to secondary. */ xfrd_setup_packet(packet, TYPE_SOA, CLASS_IN, zone->apex, qid_generate()); zone->notify_query_id = ID(packet); OPCODE_SET(packet, OPCODE_NOTIFY); AA_SET(packet); if(zone->current_soa->serial != 0) { /* add current SOA to answer section */ ANCOUNT_SET(packet, 1); xfrd_write_soa_buffer(packet, zone->apex, zone->current_soa); } if(zone->notify_current->key_options) { xfrd_tsig_sign_request(packet, &zone->notify_tsig, zone->notify_current); } buffer_flip(packet); fd = xfrd_send_udp(zone->notify_current, packet, zone->options->pattern->outgoing_interface); if(fd == -1) { log_msg(LOG_ERR, "xfrd: zone %s: could not send notify #%d to %s", zone->apex_str, zone->notify_retry, zone->notify_current->ip_address_spec); event_set(&zone->notify_send_handler, -1, EV_TIMEOUT, xfrd_handle_notify_send, zone); if(event_base_set(xfrd->event_base, &zone->notify_send_handler) != 0) log_msg(LOG_ERR, "notify_send: event_base_set failed"); if(evtimer_add(&zone->notify_send_handler, &zone->notify_timeout) != 0) log_msg(LOG_ERR, "notify_send: evtimer_add failed"); zone->notify_send_enable = 1; return; } event_set(&zone->notify_send_handler, fd, EV_READ | EV_TIMEOUT, xfrd_handle_notify_send, zone); if(event_base_set(xfrd->event_base, &zone->notify_send_handler) != 0) log_msg(LOG_ERR, "notify_send: event_base_set failed"); if(event_add(&zone->notify_send_handler, &zone->notify_timeout) != 0) log_msg(LOG_ERR, "notify_send: evtimer_add failed"); zone->notify_send_enable = 1; DEBUG(DEBUG_XFRD,1, (LOG_INFO, "xfrd: zone %s: sent notify #%d to %s", zone->apex_str, zone->notify_retry, zone->notify_current->ip_address_spec)); }
void xfrd_setup_packet(buffer_type* packet, uint16_t type, uint16_t klass, const dname_type* dname) { /* Set up the header */ buffer_clear(packet); ID_SET(packet, qid_generate()); FLAGS_SET(packet, 0); OPCODE_SET(packet, OPCODE_QUERY); QDCOUNT_SET(packet, 1); ANCOUNT_SET(packet, 0); NSCOUNT_SET(packet, 0); ARCOUNT_SET(packet, 0); buffer_skip(packet, QHEADERSZ); /* The question record. */ buffer_write(packet, dname_name(dname), dname->name_size); buffer_write_u16(packet, type); buffer_write_u16(packet, klass); }