34 #include <arpa/inet.h>
41 #include <sys/types.h>
42 #include <sys/socket.h>
44 #include <libxml/tree.h>
45 #include <libxml/parser.h>
46 #include <libxml/xpath.h>
47 #include <libxml/xpathInternals.h>
48 #include <libxml/relaxng.h>
49 #include <libxml/xmlreader.h>
50 #include <libxml/xmlsave.h>
52 #define DNS_SERIAL_GT(a, b) ((int)(((a) - (b)) & 0xFFFFFFFF) > 0)
54 static int sig_quit = 0;
55 static int sig_reload = 0;
62 ldns_status status = LDNS_STATUS_OK;
64 ldns_resolver* xfrd = ldns_resolver_new();
67 ldns_resolver_set_tsig_keyname(xfrd, config->
tsig_name);
68 if (strncmp(config->
tsig_algo,
"hmac-md5", 8) == 0) {
69 ldns_resolver_set_tsig_algorithm(xfrd,
"hmac-md5.sig-alg.reg.int.");
71 ldns_resolver_set_tsig_algorithm(xfrd, config->
tsig_algo);
73 ldns_resolver_set_tsig_keydata(xfrd, config->
tsig_secret);
79 ldns_resolver_set_recursive(xfrd, 0);
83 if (servers->
family == AF_INET6)
84 ns = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, servers->
ipaddr);
86 ns = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, servers->
ipaddr);
88 status = ldns_resolver_push_nameserver(xfrd, ns);
89 ldns_rdf_deep_free(ns);
93 "request: could not parse ip address", servers->
ipaddr);
95 if (status != LDNS_STATUS_OK) {
97 "request: %s", servers->
ipaddr,
98 ldns_get_errorstr_by_id(status));
100 servers = servers->
next;
102 if (ldns_resolver_nameserver_count(xfrd) <= 0) {
112 new_zone(
char* zone_name,
char* input_file)
115 zlt->
name = strdup(zone_name);
116 zlt->
dname = ldns_dname_new_frm_str(zone_name);
129 free((
void*) zlt->
name);
131 ldns_rdf_deep_free(zlt->
dname);
140 new_server(
char* ipv4,
char* ipv6,
char* port)
146 slt->
ipaddr = strdup(ipv4);
150 slt->
ipaddr = strdup(ipv6);
153 slt->
port = strdup(port);
158 if (slt->
family == AF_INET6 && strlen(slt->
ipaddr) > 0) {
160 ods_log_error(
"zone fetcher encountered bad ip address '%s'",
164 else if (slt->
family == AF_INET && strlen(slt->
ipaddr) > 0) {
166 ods_log_error(
"zone fetcher encountered bad ip address '%s'",
179 free_serverlist(slt->
next);
180 if (slt->
port) free((
void*) slt->
port);
219 read_axfr_config(
const char* filename,
config_type* cfg)
221 int ret, i, use_tsig = 0;
222 char* tag_name, *tsig_name, *tsig_algo, *tsig_secret, *ipv4, *ipv6, *port;
226 xmlTextReaderPtr reader = NULL;
227 xmlDocPtr doc = NULL;
228 xmlXPathContextPtr xpathCtx = NULL;
229 xmlXPathObjectPtr xpathObj = NULL;
230 xmlNode *curNode = NULL;
231 xmlChar *tsig_expr = (
unsigned char*)
"//ZoneFetch/Default/TSIG";
232 xmlChar *server_expr = (
unsigned char*)
"//ZoneFetch/Default/RequestTransfer";
233 xmlChar *notify_expr = (
unsigned char*)
"//ZoneFetch/NotifyListen";
235 if (filename == NULL) {
243 reader = xmlNewTextReaderFilename(filename);
244 if (reader != NULL) {
245 ret = xmlTextReaderRead(reader);
247 tag_name = (
char*) xmlTextReaderLocalName(reader);
249 if (strncmp(tag_name,
"ZoneFetch", 8) == 0 &&
250 xmlTextReaderNodeType(reader) == 1) {
253 xmlTextReaderExpand(reader);
254 doc = xmlTextReaderCurrentDoc(reader);
257 "%s", filename?filename:
"(null)");
261 xpathCtx = xmlXPathNewContext(doc);
262 if (xpathCtx == NULL) {
264 "context for %s", filename?filename:
"(null)");
270 xpathObj = xmlXPathEvalExpression(server_expr, xpathCtx);
271 if (xpathObj == NULL || !xpathObj->nodesetval) {
273 "server(s) in %s", filename?filename:
"(null)");
278 for (i=0; i < xpathObj->nodesetval->nodeNr; i++) {
282 curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
284 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"IPv4"))
285 ipv4 = (
char *) xmlNodeGetContent(curNode);
286 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"IPv6"))
287 ipv6 = (
char *) xmlNodeGetContent(curNode);
288 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"Port"))
289 port = (
char *) xmlNodeGetContent(curNode);
290 curNode = curNode->next;
293 if (serverlist == NULL) {
294 serverlist = new_server(ipv4, ipv6, port);
298 serverlist->
next = new_server(ipv4, ipv6, port);
299 serverlist = serverlist->
next;
303 if (ipv4) free((
void*) ipv4);
304 if (ipv6) free((
void*) ipv6);
305 if (port) free((
void*) port);
307 xmlXPathFreeObject(xpathObj);
311 xpathObj = xmlXPathEvalExpression(notify_expr, xpathCtx);
312 if (xpathObj != NULL && xpathObj->nodesetval) {
313 for (i=0; i < xpathObj->nodesetval->nodeNr; i++) {
317 curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
319 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"IPv4"))
320 ipv4 = (
char *) xmlNodeGetContent(curNode);
321 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"IPv6"))
322 ipv6 = (
char *) xmlNodeGetContent(curNode);
323 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"Port"))
324 port = (
char *) xmlNodeGetContent(curNode);
325 curNode = curNode->next;
327 if (ipv4 || ipv6 || port) {
328 if (!ipv4 && !ipv6) {
329 if (notifylist == NULL) {
330 notifylist = new_server(NULL,
"", port);
333 notifylist->
next = new_server(
"", NULL, port);
334 notifylist = notifylist->
next;
337 notifylist->
next = new_server(
"", NULL, port);
338 notifylist = notifylist->
next;
340 notifylist->
next = new_server(NULL,
"", port);
341 notifylist = notifylist->
next;
344 else if (notifylist == NULL) {
345 notifylist = new_server(ipv4, ipv6, port);
349 notifylist->
next = new_server(ipv4, ipv6, port);
350 notifylist = notifylist->
next;
354 if (ipv4) free((
void*) ipv4);
355 if (ipv6) free((
void*) ipv6);
356 if (port) free((
void*) port);
358 xmlXPathFreeObject(xpathObj);
362 xpathObj = xmlXPathEvalExpression(tsig_expr, xpathCtx);
363 if (xpathObj != NULL && xpathObj->nodesetval) {
364 for (i=0; i < xpathObj->nodesetval->nodeNr; i++) {
368 curNode = xpathObj->nodesetval->nodeTab[i]->xmlChildrenNode;
370 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"Name"))
371 tsig_name = (
char *) xmlNodeGetContent(curNode);
372 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"Algorithm"))
373 tsig_algo = (
char *) xmlNodeGetContent(curNode);
374 if (xmlStrEqual(curNode->name, (
const xmlChar *)
"Secret"))
375 tsig_secret = (
char *) xmlNodeGetContent(curNode);
376 curNode = curNode->next;
378 if (tsig_name && tsig_algo && tsig_secret) {
394 free((
void*) tsig_name);
397 free((
void*) tsig_algo);
400 free((
void*) tsig_secret);
403 xmlXPathFreeObject(xpathObj);
405 xmlXPathFreeContext(xpathCtx);
409 ret = xmlTextReaderRead(reader);
410 free((
void*) tag_name);
412 xmlFreeTextReader(reader);
416 filename?filename:
"(null)");
421 ods_log_error(
"zone fetcher was unable to open config file %s",
422 filename?filename:
"(null)");
432 read_zonelist(
const char* filename)
435 char* tag_name, *zone_name, *input_file;
438 xmlTextReaderPtr reader = NULL;
439 xmlDocPtr doc = NULL;
440 xmlXPathContextPtr xpathCtx = NULL;
441 xmlXPathObjectPtr xpathObj = NULL;
442 xmlChar *name_expr = (
unsigned char*)
"name";
443 xmlChar *adapter_expr = (
unsigned char*)
"//Zone/Adapters/Input/File";
445 if (filename == NULL) {
452 reader = xmlNewTextReaderFilename(filename);
453 if (reader != NULL) {
454 ret = xmlTextReaderRead(reader);
456 tag_name = (
char*) xmlTextReaderLocalName(reader);
458 if (strncmp(tag_name,
"Zone", 4) == 0 &&
459 strncmp(tag_name,
"ZoneList", 8) != 0 &&
460 xmlTextReaderNodeType(reader) == 1) {
462 zone_name = (
char*) xmlTextReaderGetAttribute(reader, name_expr);
464 if (zone_name == NULL) {
467 "name from %s", filename?filename:
"(null)");
469 ret = xmlTextReaderRead(reader);
473 xmlTextReaderExpand(reader);
474 doc = xmlTextReaderCurrentDoc(reader);
477 "%s; skipping", zone_name);
479 ret = xmlTextReaderRead(reader);
482 xpathCtx = xmlXPathNewContext(doc);
483 if (xpathCtx == NULL) {
485 "context for %s; skipping zone", zone_name);
487 ret = xmlTextReaderRead(reader);
492 xpathObj = xmlXPathEvalExpression(adapter_expr, xpathCtx);
493 if (xpathObj == NULL || !xpathObj->nodesetval) {
495 "xpath expression: %s; skipping zone", adapter_expr);
497 ret = xmlTextReaderRead(reader);
500 input_file = (
char*) xmlXPathCastToString(xpathObj);
501 xmlXPathFreeObject(xpathObj);
503 if (zonelist == NULL) {
504 zonelist = new_zone(zone_name, input_file);
505 zonelist_start = zonelist;
508 zonelist->
next = new_zone(zone_name, input_file);
509 zonelist = zonelist->
next;
511 free((
void*) zone_name);
512 free((
void*) input_file);
514 xmlXPathFreeContext(xpathCtx);
518 ret = xmlTextReaderRead(reader);
519 free((
void*) tag_name);
521 xmlFreeTextReader(reader);
525 filename?filename:
"(null)");
531 filename?filename:
"(null)");
536 return zonelist_start;
541 writepid(
char* pidfile, pid_t pid)
545 size_t result = 0, size = 0;
547 snprintf(pidbuf,
sizeof(pidbuf),
"%lu\n", (
unsigned long) pid);
548 if ((fd = fopen(pidfile,
"w")) == NULL ) {
550 "writing: %s", pidfile?pidfile:
"(null)", strerror(errno));
553 size = strlen(pidbuf);
556 result = fwrite((
const void*) pidbuf, 1, size, fd);
560 }
else if (result < size) {
568 pidfile?pidfile:
"(null)", strerror(errno));
597 int ret = 0, r, ip6_support = 1, on = 0;
602 const char* node = NULL;
603 const char* port = NULL;
604 #if defined(SO_REUSEADDR) || defined(IPV6_V6ONLY)
609 memset(&hints[i], 0,
sizeof(hints[i]));
610 hints[i].ai_family = AF_UNSPEC;
611 hints[i].ai_flags = AI_PASSIVE;
612 sockets->
udp[i].
s = -1;
613 sockets->
tcp[i].
s = -1;
620 hints[0].ai_family = AF_INET6;
621 hints[1].ai_family = AF_INET;
622 new_list = new_server(NULL,
"", NULL);
623 new_list->
next = new_server(
"", NULL, NULL);
625 hints[0].ai_family = AF_INET6;
626 new_list = new_server(NULL,
"", NULL);
633 node = strlen(walk->ipaddr) > 0 ? walk->
ipaddr : NULL;
636 hints[i].ai_flags |= AI_NUMERICHOST;
638 hints[i].ai_family = walk->family;
640 hints[i].ai_socktype = SOCK_DGRAM;
642 if ((r = getaddrinfo(node, port, &hints[i],
643 &(sockets->
udp[i].
addr))) != 0) {
644 if (hints[i].ai_family == AF_INET6 && errno == EAFNOSUPPORT) {
651 "getaddrinfo (%i): %s %s", node?node:
"(null)",
652 port?port:
"(null)", walk->family,
653 gai_strerror(r), r==EAI_SYSTEM?strerror(errno):
"");
657 if ((sockets->
udp[i].
s = socket(sockets->
udp[i].
addr->ai_family,
658 SOCK_DGRAM, 0)) == -1) {
659 if (sockets->
udp[i].
addr->ai_family == AF_INET6 && errno == EAFNOSUPPORT) {
666 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
673 if (sockets->
udp[i].
addr->ai_family == AF_INET) {
674 if (fcntl(sockets->
udp[i].
s, F_SETFL,
677 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
680 if (bind(sockets->
udp[i].
s,
681 (
struct sockaddr *) sockets->
udp[i].
addr->ai_addr,
682 sockets->
udp[i].
addr->ai_addrlen) != 0)
685 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
691 else if (ip6_support) {
693 #if defined(IPPROTO_IPV6)
695 if (setsockopt(sockets->
udp[i].
s, IPPROTO_IPV6, IPV6_V6ONLY, &on,
700 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
707 if (fcntl(sockets->
udp[i].
s, F_SETFL, O_NONBLOCK) == -1) {
709 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
712 if (bind(sockets->
udp[i].
s,
713 (
struct sockaddr *) sockets->
udp[i].
addr->ai_addr,
714 sockets->
udp[i].
addr->ai_addrlen) != 0) {
716 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
724 hints[i].ai_socktype = SOCK_STREAM;
726 if ((r = getaddrinfo(node, port, &hints[i],
727 &(sockets->
tcp[i].
addr))) != 0) {
728 if (hints[i].ai_family == AF_INET6 && errno == EAFNOSUPPORT) {
735 "getaddrinfo (%i): %s %s", node?node:
"(null)",
736 port?port:
"(null)", walk->family,
737 gai_strerror(r), r==EAI_SYSTEM?strerror(errno):
"");
740 if ((sockets->
tcp[i].
s = socket(sockets->
tcp[i].
addr->ai_family,
741 SOCK_STREAM, 0)) == -1) {
742 if (sockets->
tcp[i].
addr->ai_family == AF_INET6 &&
743 errno == EAFNOSUPPORT) {
750 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
757 if (sockets->
tcp[i].
addr->ai_family == AF_INET) {
758 if (setsockopt(sockets->
tcp[i].
s, SOL_SOCKET, SO_REUSEADDR, &on,
760 ods_log_error(
"zone fetcher setsockopt(..., SO_REUSEADDR, ...) "
762 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
766 if (fcntl(sockets->
tcp[i].
s, F_SETFL, O_NONBLOCK) == -1) {
768 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
772 if (bind(sockets->
tcp[i].
s,
773 (
struct sockaddr *) sockets->
tcp[i].
addr->ai_addr,
774 sockets->
tcp[i].
addr->ai_addrlen) != 0) {
776 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
782 if (listen(sockets->
tcp[i].
s, 5) == -1) {
783 ods_log_error(
"zone fetcher can't listen to tcp/4 socket for "
784 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
789 }
else if (ip6_support) {
791 if (sockets->
tcp[i].
addr->ai_family == AF_INET6 && ip6_support) {
793 #if defined(IPPROTO_IPV6)
794 if (setsockopt(sockets->
tcp[i].
s, IPPROTO_IPV6, IPV6_V6ONLY, &on,
799 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
807 if (setsockopt(sockets->
tcp[i].
s, SOL_SOCKET, SO_REUSEADDR, &on,
809 ods_log_error(
"zone fetcher setsockopt(..., SO_REUSEADDR, ...) "
811 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
815 if (fcntl(sockets->
tcp[i].
s, F_SETFL, O_NONBLOCK) == -1) {
817 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
821 if (bind(sockets->
tcp[i].
s,
822 (
struct sockaddr *) sockets->
tcp[i].
addr->ai_addr,
823 sockets->
tcp[i].
addr->ai_addrlen) != 0) {
825 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
831 if (listen(sockets->
tcp[i].
s, 5) == -1) {
832 ods_log_error(
"zone fetcher can't listen to tcp/6 socket for "
833 "%s:%s (%s)", node?node:
"(null)", port?port:
"(null)",
845 free_serverlist(new_list);
857 if (sockets->
udp[i].
s != -1) {
858 close(sockets->
udp[i].
s);
859 freeaddrinfo((
void*)sockets->
udp[i].
addr);
861 if (sockets->
tcp[i].
s != -1) {
862 close(sockets->
tcp[i].
s);
863 freeaddrinfo((
void*)sockets->
tcp[i].
addr);
871 ldns_status status = LDNS_STATUS_OK;
872 ldns_rr* axfr_rr = NULL, *soa_rr = NULL;
873 uint32_t new_serial = 0;
874 ldns_pkt* qpkt = NULL, *apkt;
877 char axfr_file[MAXPATHLEN];
878 char dest_file[MAXPATHLEN];
879 char lock_file[MAXPATHLEN];
880 char engine_sign_cmd[MAXPATHLEN + 1024];
882 ldns_resolver* xfrd = NULL;
885 if (!zone || !zone->
dname) {
886 ods_log_error(
"zone fetcher failed to provide a zone for AXFR ");
892 qpkt = ldns_pkt_query_new(ldns_rdf_clone(zone->
dname),
893 LDNS_RR_TYPE_SOA, LDNS_RR_CLASS_IN, LDNS_RD);
904 ods_log_error(
"zone fetcher failed to initialise AXFR structure");
908 status = ldns_resolver_send_pkt(&apkt, xfrd, qpkt);
911 if (status != LDNS_STATUS_OK) {
913 ldns_get_errorstr_by_id(status));
914 ldns_resolver_deep_free(xfrd);
917 if (ldns_pkt_ancount(apkt) == 1) {
918 soa_rr = ldns_rr_list_rr(ldns_pkt_answer(apkt), 0);
919 if (soa_rr && ldns_rr_get_type(soa_rr) == LDNS_RR_TYPE_SOA) {
920 new_serial = ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2));
924 ods_log_error(
"zone fetcher saw SOA response with ANCOUNT != 1, "
928 ldns_resolver_deep_free(xfrd);
933 status = ldns_axfr_start(xfrd, zone->
dname, LDNS_RR_CLASS_IN);
934 if (status != LDNS_STATUS_OK) {
936 ldns_get_errorstr_by_id(status));
937 ldns_resolver_deep_free(xfrd);
945 snprintf(lock_ext,
sizeof(lock_ext),
"axfr.%lu",
946 (
unsigned long) getpid());
948 snprintf(axfr_file,
sizeof(axfr_file),
"%s.%s", zone->
input_file, lock_ext);
949 fd = fopen(axfr_file,
"w");
951 ods_log_error(
"zone fetcher cannot store AXFR to file %s", axfr_file);
952 ldns_resolver_deep_free(xfrd);
958 axfr_rr = ldns_axfr_next(xfrd);
964 ldns_resolver_deep_free(xfrd);
969 if (ldns_rr_get_type(axfr_rr) == LDNS_RR_TYPE_SOA) {
972 ldns_rr_print(fd, axfr_rr);
975 ldns_rr_print(fd, axfr_rr);
977 ldns_rr_free(axfr_rr);
978 axfr_rr = ldns_axfr_next(xfrd);
986 if (!ldns_axfr_complete(xfrd)) {
988 ods_log_error(
"zone fetcher AXFR for %s failed, received only a partial zone", zone->
name);
991 ldns_resolver_deep_free(xfrd);
995 ods_log_info(
"zone fetcher transferred zone %s serial %u "
996 "successfully", zone->
name?zone->
name:
"(null)", new_serial);
1002 snprintf(lock_file,
sizeof(lock_file),
"%s.lock",
1006 if (access(lock_file, F_OK) == 0) {
1008 "waiting...", dest_file);
1012 fd = fopen(lock_file,
"w");
1016 ldns_resolver_deep_free(xfrd);
1022 snprintf(dest_file,
sizeof(dest_file),
"%s.axfr",
1024 if(rename(axfr_file, dest_file) == 0) {
1026 (void) unlink(lock_file);
1029 snprintf(engine_sign_cmd,
sizeof(engine_sign_cmd),
1030 "%s sign %s > /dev/null 2>&1",
1031 ODS_SE_CLI, zone->
name?zone->
name:
"--all");
1032 if (system(engine_sign_cmd) != 0) {
1034 "the signer engine to sign zone %s",
1040 (void) unlink(lock_file);
1045 ldns_resolver_deep_free(xfrd);
1049 ods_log_info(
"zone fetcher zone %s is already up to date, "
1050 "serial is %u", zone->
name?zone->
name:
"(null)", serial);
1053 ldns_resolver_deep_free(xfrd);
1058 send_udp(uint8_t* buf,
size_t len,
void* data)
1063 nb = sendto(userdata->
udp_sock, buf, len, 0,
1066 ods_log_error(
"zone fetcher sendto() failed: %s", strerror(errno));
1067 else if ((
size_t)nb != len)
1068 ods_log_error(
"zone fetcher sendto(): only sent %d of %d octets.",
1073 write_n_bytes(
int sock, uint8_t* buf,
size_t sz)
1077 ssize_t nb = send(sock, buf+count, sz-count, 0);
1088 send_tcp(uint8_t* buf,
size_t len,
void* data)
1093 tcplen = htons(len);
1094 write_n_bytes(userdata->
s, (uint8_t*)&tcplen,
sizeof(tcplen));
1095 write_n_bytes(userdata->
s, buf, len);
1099 handle_query(uint8_t* inbuf, ssize_t inlen,
1100 void (*sendfunc)(uint8_t*,
size_t,
void*),
1104 ldns_status status = LDNS_STATUS_OK;
1105 ldns_pkt *query_pkt = NULL;
1106 ldns_rr *query_rr = NULL;
1107 uint32_t serial = 0;
1108 char* owner_name = NULL;
1109 uint8_t *outbuf = NULL;
1110 size_t answer_size = 0;
1111 char dest_file[MAXPATHLEN];
1115 status = ldns_wire2pkt(&query_pkt, inbuf, (
size_t)inlen);
1116 if (status != LDNS_STATUS_OK) {
1118 ldns_get_errorstr_by_id(status));
1121 query_rr = ldns_rr_list_rr(ldns_pkt_question(query_pkt), 0);
1123 if (ldns_pkt_get_opcode(query_pkt) != LDNS_PACKET_NOTIFY ||
1124 ldns_pkt_get_rcode(query_pkt) != LDNS_RCODE_NOERROR ||
1125 ldns_pkt_qr(query_pkt) ||
1126 !ldns_pkt_aa(query_pkt) ||
1127 ldns_pkt_tc(query_pkt) ||
1128 ldns_pkt_rd(query_pkt) ||
1129 ldns_pkt_ra(query_pkt) ||
1130 ldns_pkt_cd(query_pkt) ||
1131 ldns_pkt_ad(query_pkt) ||
1132 ldns_pkt_qdcount(query_pkt) != 1 ||
1133 ldns_pkt_nscount(query_pkt) != 0 ||
1134 ldns_pkt_arcount(query_pkt) != 0 ||
1135 ldns_rr_get_type(query_rr) != LDNS_RR_TYPE_SOA ||
1136 ldns_rr_get_class(query_rr) != LDNS_RR_CLASS_IN)
1146 ldns_pkt_set_qr(query_pkt, 1);
1147 status = ldns_pkt2wire(&outbuf, query_pkt, &answer_size);
1148 if (status != LDNS_STATUS_OK) {
1149 ods_log_error(
"zone fetcher error creating notify response: %s",
1150 ldns_get_errorstr_by_id(status));
1152 sendfunc(outbuf, answer_size, userdata);
1157 if (ldns_dname_compare(ldns_rr_owner(query_rr), zonelist->
dname) == 0)
1159 ods_log_info(
"zone fetcher received NOTIFY for zone %s",
1160 zonelist->
name?zonelist->
name:
"(null)");
1162 snprintf(dest_file,
sizeof(dest_file),
"%s.axfr",
1164 fd = fopen(dest_file,
"r");
1171 if (odd_xfer(zonelist, serial, config, 1) != 0) {
1173 zonelist->
name?zonelist->
name:
"(null)");
1175 ldns_pkt_free(query_pkt);
1179 zonelist = zonelist->
next;
1181 owner_name = ldns_rdf2str(ldns_rr_owner(query_rr));
1183 owner_name?owner_name:
"(null)");
1184 free((
void*)owner_name);
1185 ldns_pkt_free(query_pkt);
1189 read_n_bytes(
int sock, uint8_t* buf,
size_t sz)
1193 ssize_t nb = recv(sock, buf+count, sz-count, 0);
1204 addr2ip(
struct sockaddr_storage addr,
char* remote,
size_t len)
1206 if (addr.ss_family == AF_INET6) {
1207 if (!inet_ntop(AF_INET6, &((
struct sockaddr_in6 *)&addr)->sin6_addr,
1212 if (!inet_ntop(AF_INET, &((
struct sockaddr_in *)&addr)->sin_addr,
1221 acl_matches(
struct sockaddr_storage* addr,
config_type* config)
1227 while (serverlist) {
1228 if (serverlist->
family == AF_INET6) {
1229 struct sockaddr_in6* addr6 = (
struct sockaddr_in6*)addr;
1230 if (serverlist->
family == addr->ss_family &&
1231 memcmp(&addr6->sin6_addr, &serverlist->
addr.
addr6,
1232 sizeof(
struct in6_addr)) == 0)
1238 struct sockaddr_in* addr4 = (
struct sockaddr_in*)addr;
1239 if (serverlist->
family == addr4->sin_family &&
1240 memcmp(&addr4->sin_addr, &serverlist->
addr.
addr,
1241 sizeof(
struct in_addr)) == 0)
1247 serverlist = serverlist->
next;
1262 userdata.hislen = (socklen_t)
sizeof(userdata.addr_him);
1263 nb = recvfrom(udp_sock, inbuf,
INBUF_SIZE, 0,
1264 (
struct sockaddr*) &userdata.addr_him, &userdata.hislen);
1272 if (!acl_matches(&userdata.addr_him, config)) {
1273 remote = (
char*) malloc(
sizeof(
char)*userdata.hislen);
1275 "unauthoritative source: %s",
1276 addr2ip(userdata.addr_him, remote, userdata.hislen));
1277 free((
void*)remote);
1280 handle_query(inbuf, nb, send_udp, &userdata, config);
1287 struct sockaddr_storage addr_him;
1295 hislen = (socklen_t)
sizeof(addr_him);
1296 if((s = accept(tcp_sock, (
struct sockaddr*)&addr_him, &hislen)) < 0) {
1297 ods_log_error(
"zone fetcher accept() failed: %s", strerror(errno));
1303 read_n_bytes(s, (uint8_t*)&tcplen,
sizeof(tcplen));
1304 tcplen = ntohs(tcplen);
1311 read_n_bytes(s, inbuf, tcplen);
1314 if (!acl_matches(&addr_him, config)) {
1315 remote = (
char*) malloc(
sizeof(
char)*hislen);
1317 "unauthoritative source: %s",
1318 addr2ip(addr_him, remote, hislen));
1319 free((
void*)remote);
1323 handle_query(inbuf, (ssize_t) tcplen, send_tcp, &userdata, config);
1336 int added_count = 0, changed_count = 0, kept_count = 0;
1339 ods_log_error(
"zone fetcher is unable to access the zonelist");
1347 while (new_zonelist) {
1351 while (
this && !found) {
1352 found = !strcmp (this->name, new_zonelist->
name);
1360 if (strcmp (new_zonelist->
input_file, this->input_file)) {
1363 new_zonelist->
next = added_zonelist;
1364 added_zonelist = new_zonelist;
1368 new_zonelist->
next = kept_zonelist;
1369 kept_zonelist = new_zonelist;
1374 new_zonelist->
next = added_zonelist;
1375 added_zonelist = new_zonelist;
1377 new_zonelist = next_zonelist;
1385 thisp = &(*thisp)->
next;
1387 *thisp = added_zonelist;
1390 new_zonelist = added_zonelist;
1391 while (new_zonelist) {
1393 if (odd_xfer (new_zonelist, 0, config, 1) != 0) {
1397 new_zonelist = new_zonelist->
next;
1399 ods_log_verbose(
"Reloaded zonelist -- kept %d, changed %d and added %d zones",
1400 kept_count, changed_count, added_count);
1408 fd_set rset, wset, eset;
1409 struct timeval timeout;
1410 int count, maxfd = 0;
1416 timeout.tv_usec = 0;
1419 reload_zonelist(cfg);
1426 if (sockets->
udp[i].
s != -1)
1427 FD_SET(sockets->
udp[i].
s, &rset);
1428 if (sockets->
tcp[i].
s != -1)
1429 FD_SET(sockets->
tcp[i].
s, &rset);
1430 if (sockets->
udp[i].
s > maxfd) maxfd = sockets->
udp[i].
s;
1431 if (sockets->
tcp[i].
s > maxfd) maxfd = sockets->
tcp[i].
s;
1434 if (select(maxfd+1, &rset, &wset, &eset, NULL) < 0) {
1437 ods_log_error(
"zone fetcher select(): %s", strerror(errno));
1441 if (sockets->
udp[i].
s != -1 && FD_ISSET(sockets->
udp[i].
s, &rset))
1442 handle_udp(sockets->
udp[i].
s, cfg);
1443 if (sockets->
tcp[i].
s != -1 && FD_ISSET(sockets->
tcp[i].
s, &rset))
1444 handle_tcp(sockets->
tcp[i].
s, cfg);
1450 list_settings(FILE* out,
config_type* config,
const char* filename)
1456 fprintf(out,
"configuration settings:\n");
1457 fprintf(out,
"filename: %s\n", filename?filename:
"(null)");
1458 fprintf(out,
"pidfile: %s\n",
1460 fprintf(out,
"tsig: %s\n", config->
use_tsig?
"yes":
"no");
1462 fprintf(out,
"tsig name: %s\n",
1464 fprintf(out,
"tsig algorithm: %s\n",
1466 fprintf(out,
"tsig secret: ?\n");
1468 fprintf(out,
"zones: %s\n", config->
zonelist?
"":
"none");
1471 fprintf(out,
"\t%s\n", zones->
name?zones->
name:
"(null)");
1472 zones = zones->
next;
1474 fprintf(out,
"master servers: %s\n", config->
serverlist?
"":
"none");
1477 fprintf(out,
"\t%s\n", servers->
ipaddr?servers->
ipaddr:
"(null)");
1478 servers = servers->
next;
1480 fprintf(out,
"interfaces: %s\n", config->
notifylist?
"":
"none");
1483 fprintf(out,
"\t%s %s:%s\n",
1484 servers->
family==AF_INET6?
"ipv6":
"ipv4",
1486 servers->
port?servers->
port:
"(null)");
1487 servers = servers->
next;
1489 fprintf(out,
"list zone fetcher settings done.\n");
1491 else fprintf(out,
"no config\n");
1496 const char* group,
const char* user,
const char* chroot,
const char* log_file,
1497 int use_syslog,
int verbosity)
1501 uint32_t serial = 0;
1506 struct sigaction action;
1513 config = new_config();
1514 config->
pidfile = strdup(ODS_ZF_PIDFILE);
1517 free_config(config);
1521 c = read_axfr_config(config_file, config);
1522 config->
zonelist = read_zonelist(zonelist_file);
1526 list_settings(stdout, config, config_file);
1530 ods_log_alert(
"zone fetcher error: no master servers configured "
1531 "with <RequestTransfer>");
1532 free_config(config);
1537 action.sa_handler = sig_handler;
1538 sigfillset(&action.sa_mask);
1539 action.sa_flags = 0;
1540 sigaction(SIGHUP, &action, NULL);
1541 sigaction(SIGTERM, &action, NULL);
1544 if (writepid(config->
pidfile, getpid()) != 0) {
1554 while (zonelist != NULL) {
1564 if (odd_xfer(zonelist, serial, config, 1) != 0) {
1566 zonelist->
name?zonelist->
name:
"(null)");
1569 zonelist = zonelist->
next;
1573 c = init_sockets(&sockets, config->
notifylist);
1576 if (unlink(config->
pidfile) == -1) {
1586 error =
privdrop(user, group, chroot, &uid, &gid);
1590 if (unlink(config->
pidfile) == -1) {
1595 free_sockets(&sockets);
1600 xfrd_ns(&sockets, config);
1602 if (unlink(config->
pidfile) == -1) {
1607 free_sockets(&sockets);
1611 free_config(config);
void ods_log_alert(const char *format,...)
void privclose(const char *username, const char *groupname)
void ods_log_debug(const char *format,...)
serverlist_type * notifylist
zfzonelist_type * zonelist
union acl_addr_storage addr
void ods_log_info(const char *format,...)
void ods_log_error(const char *format,...)
struct odd_socket udp[MAX_INTERFACES]
struct odd_socket tcp[MAX_INTERFACES]
ldns_resolver * init_xfrd(config_type *config)
ods_status privdrop(const char *username, const char *groupname, const char *newroot, uid_t *puid, gid_t *pgid)
int tools_zone_fetcher(const char *config_file, const char *zonelist_file, const char *group, const char *user, const char *chroot, const char *log_file, int use_syslog, int verbosity)
void ods_log_verbose(const char *format,...)
const char * zonelist_file
serverlist_type * serverlist
void ods_log_deeebug(const char *format,...)
struct sockaddr_storage addr_him
#define DNS_SERIAL_GT(a, b)
void ods_log_init(const char *filename, int use_syslog, int verbosity)
void ods_log_warning(const char *format,...)