50 #define XFRD_TSIG_MAX_UNSIGNED 100
52 static const char* xfrd_str =
"xfrd";
54 static void xfrd_handle_zone(
netio_type* netio,
56 static void xfrd_make_request(
xfrd_type* xfrd);
58 static socklen_t xfrd_acl_sockaddr(
acl_type* acl,
unsigned int port,
59 struct sockaddr_storage *sck);
63 unsigned rdata_only,
unsigned update, uint32_t t,
66 uint16_t count,
int* done);
79 static void xfrd_udp_obtain(
xfrd_type* xfrd);
80 static void xfrd_udp_read(
xfrd_type* xfrd);
81 static void xfrd_udp_release(
xfrd_type* xfrd);
82 static int xfrd_udp_read_packet(
xfrd_type* xfrd);
84 static int xfrd_udp_send_request_ixfr(
xfrd_type* xfrd);
87 static void xfrd_set_timer(
xfrd_type* xfrd, time_t t);
88 static void xfrd_set_timer_time(
xfrd_type* xfrd, time_t t);
89 static void xfrd_unset_timer(
xfrd_type* xfrd);
101 if (!xfrhandler || !zone) {
107 "allocator_create() failed", xfrd_str);
113 " allocator_alloc() failed", xfrd_str);
165 xfrd_set_timer_time(xfrd, 0);
188 xfrd_set_timer(
xfrd_type* xfrd, time_t t)
197 if(t > xfrd_time(xfrd) + 10) {
198 time_t extra = t - xfrd_time(xfrd);
199 time_t base = extra*9/10;
200 t = xfrd_time(xfrd) + base +
201 random()%(extra-base);
228 xfrd_set_timer_time(
xfrd_type* xfrd, time_t t)
231 xfrd_set_timer(xfrd, xfrd_time(xfrd) + t);
248 ods_log_debug(
"[%s] zone %s sets timer timeout now", xfrd_str,
250 xfrd_set_timer_time(xfrd, 0);
267 ods_log_debug(
"[%s] zone %s sets timer timeout retry %u", xfrd_str,
269 xfrd_set_timer_time(xfrd, xfrd->
soa.
retry);
286 ods_log_debug(
"[%s] zone %s sets timer timeout refresh %u", xfrd_str,
298 xfrd_acl_sockaddr(
acl_type* acl,
unsigned int port,
299 struct sockaddr_storage *sck)
304 memset(sck, 0,
sizeof(
struct sockaddr_storage));
305 if (acl->
family == AF_INET6) {
306 struct sockaddr_in6* sa = (
struct sockaddr_in6*)sck;
307 sa->sin6_family = AF_INET6;
308 sa->sin6_port = htons(port);
310 return sizeof(
struct sockaddr_in6);
312 struct sockaddr_in* sa = (
struct sockaddr_in*)sck;
313 sa->sin_family = AF_INET;
314 sa->sin_port = htons(port);
316 return sizeof(
struct sockaddr_in);
329 unsigned int port = 0;
334 return xfrd_acl_sockaddr(acl, port, to);
352 ods_log_error(
"[%s] unable to sign request: tsig unknown algorithm "
367 ods_log_debug(
"[%s] tsig append rr to request id=%u", xfrd_str,
394 ods_log_error(
"[%s] unable to process tsig: xfr zone %s from %s "
395 "has malformed tsig rr", xfrd_str, zone->
name,
414 ods_log_error(
"[%s] unable to process tsig: xfr zone %s from %s "
415 "has bad tsig signature", xfrd_str, zone->
name,
424 ods_log_error(
"[%s] unable to process tsig: xfr zone %s, from %s "
425 "has too many consecutive packets without tsig", xfrd_str,
430 ods_log_error(
"[%s] unable to process tsig: xfr zone %s from %s "
431 "has no tsig in first packet of reply", xfrd_str,
448 char* xfrfile = NULL;
454 ods_log_crit(
"[%s] unable to commit xfr zone %s: build path failed",
455 xfrd_str, zone->
name);
465 free((
void*)xfrfile);
467 fprintf(fd,
";;ENDPACKET\n");
473 ods_log_crit(
"[%s] unable to commit xfr zone %s: ods_fopen() failed "
474 "(%s)", xfrd_str, zone->
name, strerror(errno));
489 ods_log_debug(
"[%s] reschedule task for zone %s: disk serial=%u "
490 "acquired=%u, memory serial=%u acquired=%u", xfrd_str,
496 ods_log_crit(
"[%s] unable to reschedule task for zone %s: %s",
517 char* xfrfile = NULL;
519 ldns_pkt* pkt = NULL;
520 ldns_status status = LDNS_STATUS_OK;
527 if (status != LDNS_STATUS_OK) {
528 ods_log_crit(
"[%s] unable to dump packet zone %s: ldns_wire2pkt() "
529 "failed (%s)", xfrd_str, zone->
name,
530 ldns_get_errorstr_by_id(status));
536 ods_log_crit(
"[%s] unable to dump packet zone %s: build path failed",
537 xfrd_str, zone->
name);
545 free((
void*) xfrfile);
547 ods_log_crit(
"[%s] unable to dump packet zone %s: ods_fopen() failed "
548 "(%s)", xfrd_str, zone->
name, strerror(errno));
554 fprintf(fd,
";;BEGINPACKET\n");
556 ldns_rr_list_print(fd, ldns_pkt_answer(pkt));
572 size_t rdlength_pos = 0;
573 uint16_t rdlength = 0;
604 uint16_t mname_pos, uint16_t rname_pos,
605 uint32_t refresh, uint32_t retry, uint32_t expire, uint32_t minimum)
640 unsigned update, uint32_t t, uint32_t* soa_serial)
642 ldns_rr_type type = LDNS_RR_TYPE_SOA;
643 uint16_t mname_pos = 0;
644 uint16_t rname_pos = 0;
647 uint32_t refresh = 0;
650 uint32_t minimum = 0;
663 if (type != LDNS_RR_TYPE_SOA) {
665 xfrd_str, (
unsigned) type);
698 *soa_serial = serial;
701 xfrd_update_soa(xfrd, buffer, ttl, mname_pos, rname_pos,
702 refresh, retry, expire, minimum);
717 ldns_rr_type type = 0;
740 if (type == LDNS_RR_TYPE_SOA) {
741 if (!xfrd_parse_soa(xfrd, buffer, 1, 0, ttl, &serial)) {
784 uint16_t qdcount = 0;
785 uint16_t ancount = 0;
786 uint16_t ancount_todo = 0;
787 uint16_t rrcount = 0;
800 ods_log_error(
"[%s] unable to parse packet: zone %s received bad "
801 "packet from %s (too small)", xfrd_str, zone->
name,
807 ods_log_error(
"[%s] bad packet: zone %s received bad query id "
808 "%u from %s (expected %u)", xfrd_str, zone->
name,
814 ods_log_error(
"[%s] bad packet: zone %s received error code %s from %s",
824 if (!xfrd_tsig_process(xfrd, buffer)) {
832 for (rrcount = 0; rrcount < qdcount; rrcount++) {
835 "question section from %s (bad rr)", xfrd_str, zone->
name,
848 ods_log_error(
"[%s] bad packet: zone %s received bad xfr packet "
853 ancount_todo = ancount;
857 !xfrd_parse_soa(xfrd, buffer, 0, 1, 0, &serial)) {
859 "packet from %s (bad soa)", xfrd_str, zone->
name,
867 "serial %u from %s", xfrd_str, zone->
name, serial,
891 "(have %u)", xfrd_str, zone->
name, serial,
911 ancount_todo = ancount - 1;
919 if (xfrd->
tcp_conn == -1 && ancount < 2) {
921 ods_log_debug(
"[%s] zone %s received too short udp reply from %s, "
925 status = xfrd_parse_rrs(xfrd, buffer, ancount_todo, &done);
927 ods_log_error(
"[%s] bad packet: zone %s received bad xfr packet "
932 if (xfrd->
tcp_conn == -1 && !done) {
933 ods_log_error(
"[%s] bad packet: zone %s received bad xfr packet "
934 "(xfr over udp incomplete)", xfrd_str, zone->
name,
960 res = xfrd_parse_packet(xfrd, buffer);
984 xfrd_dump_packet(xfrd, buffer);
995 xfrd_commit_packet(xfrd);
999 ods_log_debug(
"[%s] zone %s notify acquired %u, serial on disk %u, "
1000 "notify serial %u", xfrd_str, zone->
name,
1006 ods_log_debug(
"[%s] zone %s reset notify acquired", xfrd_str,
1050 len =
sizeof(error);
1051 if (getsockopt(tcp->
fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
1054 if (error == EINPROGRESS || error == EWOULDBLOCK) {
1055 ods_log_debug(
"[%s] zone %s zero write, write again later (%s)",
1056 xfrd_str, zone->
name, strerror(error));
1063 xfrd_tcp_release(xfrd, set);
1072 xfrd_tcp_release(xfrd, set);
1077 xfrd_str, zone->
name);
1081 ods_log_debug(
"[%s] zone %s done writing, get ready for reading",
1082 xfrd_str, zone->
name);
1086 xfrd_tcp_read(xfrd, set);
1098 int fd, family, conn;
1099 struct sockaddr_storage to;
1111 ods_log_debug(
"[%s] zone %s open tcp connection to %s", xfrd_str,
1121 fd = socket(family, SOCK_STREAM, IPPROTO_TCP);
1124 ods_log_error(
"[%s] zone %s cannot create tcp socket to %s: %s",
1127 xfrd_tcp_release(xfrd, set);
1130 if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
1131 ods_log_error(
"[%s] zone %s cannot fcntl tcp socket to %s: %s",
1134 xfrd_tcp_release(xfrd, set);
1140 conn = connect(fd, (
struct sockaddr*)&to, to_len);
1141 if (conn == -1 && errno != EINPROGRESS) {
1142 ods_log_error(
"[%s] zone %s cannot connect tcp socket to %s: %s",
1145 xfrd_tcp_release(xfrd, set);
1182 xfrd_udp_release(xfrd);
1184 if (!xfrd_tcp_open(xfrd, set)) {
1187 xfrd_tcp_xfr(xfrd, set);
1192 xfrd_str, TCPSET_MAX);
1194 xfrd_unset_timer(xfrd);
1232 xfrd_write_soa(xfrd, tcp->
packet);
1241 xfrd_tsig_sign(xfrd, tcp->
packet);
1244 ods_log_debug(
"[%s] zone %s sending tcp query id=%d", xfrd_str,
1268 xfrd_tcp_release(xfrd, set);
1276 ret = xfrd_handle_packet(xfrd, tcp->
packet);
1283 ods_log_debug(
"[%s] tcp read %s: release connection", xfrd_str,
1285 xfrd_tcp_release(xfrd, set);
1290 ods_log_debug(
"[%s] disable ixfr requests for %s from now (%u)",
1295 ods_log_debug(
"[%s] tcp read %s: release connection", xfrd_str,
1297 xfrd_tcp_release(xfrd, set);
1298 xfrd_make_request(xfrd);
1322 ods_log_debug(
"[%s] zone %s release tcp connection to %s", xfrd_str,
1349 struct sockaddr_storage to;
1350 socklen_t to_len = 0;
1365 fd = socket(family, SOCK_DGRAM, IPPROTO_UDP);
1378 (
struct sockaddr*)&to, to_len);
1395 xfrd_udp_send_request_ixfr(
xfrd_type* xfrd)
1408 ods_log_error(
"[%s] unable to transfer zone %s: tried to send "
1409 "udp while tcp obtained", xfrd_str, zone->
name);
1424 xfrd_write_soa(xfrd, xfrhandler->
packet);
1425 xfrd_tsig_sign(xfrd, xfrhandler->
packet);
1428 ods_log_debug(
"[%s] zone %s sending udp query id=%d qtype=IXFR to %s",
1430 if((fd = xfrd_udp_send(xfrd, xfrhandler->
packet)) == -1) {
1450 xfrd_tcp_release(xfrd, xfrhandler->
tcp_set);
1454 xfrd->
handler.
fd = xfrd_udp_send_request_ixfr(xfrd);
1470 xfrd_unset_timer(xfrd);
1483 ssize_t received = 0;
1491 if (received == -1) {
1492 ods_log_error(
"[%s] unable to read packet: recvfrom() failed fd %d "
1493 "(%s)", xfrd_str, xfrd->
handler.
fd, strerror(errno));
1517 if (!xfrd_udp_read_packet(xfrd)) {
1519 "xfrd_udp_read_packet() failed", xfrd_str, zone->
name);
1520 xfrd_udp_release(xfrd);
1525 res = xfrd_handle_packet(xfrd, xfrhandler->
packet);
1530 xfrd_udp_release(xfrd);
1532 xfrd_tcp_obtain(xfrd, xfrhandler->
tcp_set);
1540 xfrd_udp_release(xfrd);
1544 ods_log_debug(
"[%s] disable ixfr requests for %s from now (%u)",
1551 xfrd_udp_release(xfrd);
1552 xfrd_make_request(xfrd);
1588 wf->
handler.
fd = xfrd_udp_send_request_ixfr(wf);
1653 xfrd_str, zone->
name);
1658 ods_log_debug(
"[%s] unable to make request for zone %s: no master",
1659 xfrd_str, zone->
name);
1670 ods_log_debug(
"[%s] clear negative caching calc: %u + %u <= %u",
1676 ods_log_debug(
"[%s] zone %s make request round %d master %s:%u",
1681 xfrd_udp_obtain(xfrd);
1687 xfrd_tcp_obtain(xfrd, xfrhandler->
tcp_set);
1698 xfrd_handle_zone(
netio_type* ATTR_UNUSED(netio),
1720 xfrd_tcp_read(xfrd, xfrhandler->
tcp_set);
1726 xfrd_tcp_write(xfrd, xfrhandler->
tcp_set);
1732 xfrd_tcp_release(xfrd, xfrhandler->
tcp_set);
1738 if (event_types & NETIO_EVENT_READ) {
1743 xfrd_udp_read(xfrd);
1749 if (handler->
fd != -1) {
1751 xfrd_udp_release(xfrd);
1755 xfrd_str, zone->
name);
1756 xfrd_unset_timer(xfrd);
1761 xfrd_str, zone->
name);
1762 xfrd_unset_timer(xfrd);
1766 xfrd_make_request(xfrd);
#define XFRD_TSIG_MAX_UNSIGNED
void tsig_rr_update(tsig_rr_type *trr, buffer_type *buffer, size_t length)
void engine_wakeup_workers(engine_type *engine)
xfrd_type * udp_waiting_first
xfrd_type * udp_waiting_last
void ods_log_debug(const char *format,...)
xfrd_type * tcp_waiting_next
void xfrd_set_timer_refresh(xfrd_type *xfrd)
#define lock_basic_destroy(lock)
uint16_t buffer_pkt_arcount(buffer_type *buffer)
#define BUFFER_PKT_HEADER_SIZE
void * allocator_alloc(allocator_type *allocator, size_t size)
const char * tsig_strerror(uint16_t error)
time_t serial_xfr_acquired
uint16_t buffer_pkt_qdcount(buffer_type *buffer)
void buffer_skip(buffer_type *buffer, ssize_t count)
uint16_t buffer_read_u16(buffer_type *buffer)
int buffer_skip_rr(buffer_type *buffer, unsigned qrr)
void buffer_flip(buffer_type *buffer)
#define XFRD_NO_IXFR_CACHE
void buffer_clear(buffer_type *buffer)
void ods_log_info(const char *format,...)
time_t serial_notify_acquired
allocator_type * allocator
uint8_t mname[MAXDOMAINLEN+2]
enum ods_enum_status ods_status
enum netio_events_enum netio_events_type
lock_basic_type zone_lock
socklen_t xfrd_acl_sockaddr_to(acl_type *acl, struct sockaddr_storage *to)
tsig_algo_type * tsig_lookup_algo(const char *name)
tcp_conn_type * tcp_conn[TCPSET_MAX]
xfrd_type * tcp_waiting_first
void ods_log_error(const char *format,...)
const char * ods_status2str(ods_status status)
int tcp_conn_write(tcp_conn_type *tcp)
union acl_addr_storage addr
void tsig_rr_reset(tsig_rr_type *trr, tsig_algo_type *algo, tsig_key_type *key)
void tsig_rr_append(tsig_rr_type *trr, buffer_type *buffer)
size_t update_since_last_prepare
void buffer_write(buffer_type *buffer, const void *data, size_t count)
uint16_t buffer_pkt_id(buffer_type *buffer)
lock_basic_type serial_lock
uint8_t * buffer_current(buffer_type *buffer)
FILE * ods_fopen(const char *file, const char *dir, const char *mode)
int util_serial_gt(uint32_t serial_new, uint32_t serial_old)
uint16_t buffer_pkt_ancount(buffer_type *buffer)
size_t buffer_limit(buffer_type *buffer)
xfrd_type * udp_waiting_next
void tsig_rr_prepare(tsig_rr_type *trr)
void ods_log_crit(const char *format,...)
time_t xfrhandler_time(xfrhandler_type *xfrhandler)
#define lock_basic_lock(lock)
void buffer_pkt_set_nscount(buffer_type *buffer, uint16_t count)
void buffer_set_limit(buffer_type *buffer, size_t limit)
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
netio_event_handler_type event_handler
void tsig_rr_cleanup(tsig_rr_type *trr)
void xfrd_set_timer_retry(xfrd_type *xfrd)
int buffer_skip_dname(buffer_type *buffer)
void log_dname(ldns_rdf *rdf, const char *pre, int level)
uint32_t buffer_read_u32(buffer_type *buffer)
void buffer_pkt_query(buffer_type *buffer, ldns_rdf *qname, ldns_rr_type qtype, ldns_rr_class qclass)
int tsig_rr_verify(tsig_rr_type *trr)
void buffer_write_u16(buffer_type *buffer, uint16_t data)
size_t buffer_read_dname(buffer_type *buffer, uint8_t *dname, unsigned allow_pointers)
void buffer_write_u32(buffer_type *buffer, uint32_t data)
void xfrd_cleanup(xfrd_type *xfrd)
ods_status zone_reschedule_task(zone_type *zone, schedule_type *taskq, task_id what)
tsig_rr_type * tsig_rr_create(allocator_type *allocator)
char * ods_build_path(const char *file, const char *suffix, int dir, int no_slash)
uint8_t rname[MAXDOMAINLEN+2]
int tcp_conn_read(tcp_conn_type *tcp)
void ods_log_verbose(const char *format,...)
void buffer_write_u16_at(buffer_type *buffer, size_t at, uint16_t data)
void buffer_set_position(buffer_type *buffer, size_t pos)
#define lock_basic_init(lock)
int tsig_rr_find(tsig_rr_type *trr, buffer_type *buffer)
void ods_fclose(FILE *fd)
void xfrd_set_timer_now(xfrd_type *xfrd)
netio_events_type event_types
int buffer_available(buffer_type *buffer, size_t count)
void allocator_cleanup(allocator_type *allocator)
size_t buffer_remaining(buffer_type *buffer)
void ods_log_deeebug(const char *format,...)
void buffer_write_rdf(buffer_type *buffer, ldns_rdf *rdf)
void tsig_rr_sign(tsig_rr_type *trr)
void allocator_deallocate(allocator_type *allocator, void *data)
void tcp_conn_ready(tcp_conn_type *tcp)
size_t buffer_position(buffer_type *buffer)
void buffer_pkt_set_arcount(buffer_type *buffer, uint16_t count)
struct timespec * timeout
#define ods_log_assert(x)
netio_handler_type handler
xfrd_type * xfrd_create(void *xfrhandler, void *zone)
#define lock_basic_unlock(lock)
uint16_t original_query_id
enum xfrd_pkt_enum xfrd_pkt_status
time_t serial_disk_acquired
uint8_t * buffer_begin(buffer_type *buffer)
ldns_pkt_rcode buffer_pkt_rcode(buffer_type *buffer)
int buffer_pkt_tc(buffer_type *buffer)