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);