[Opendnssec-commits] [svn.opendnssec.org/svn/dnssec] r6046 - in branches/OpenDNSSEC-enforcer-ng/signer: . doc src src/adapter src/daemon src/scheduler src/signer src/wire

matthijs at nlnetlabs.nl matthijs at nlnetlabs.nl
Mon Jan 9 16:28:29 CET 2012


Author: matthijs
Date: 2012-01-09 16:28:29 +0100 (Mon, 09 Jan 2012)
New Revision: 6046

Modified:
   branches/OpenDNSSEC-enforcer-ng/signer/
   branches/OpenDNSSEC-enforcer-ng/signer/doc/Changelog
   branches/OpenDNSSEC-enforcer-ng/signer/src/adapter/adapi.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/adapter/addns.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/daemon/engine.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/daemon/worker.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/ods-signerd.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/scheduler/fifoq.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/scheduler/fifoq.h
   branches/OpenDNSSEC-enforcer-ng/signer/src/signer/ixfr.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/signer/ixfr.h
   branches/OpenDNSSEC-enforcer-ng/signer/src/signer/namedb.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/signer/zone.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/wire/axfr.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/wire/axfr.h
   branches/OpenDNSSEC-enforcer-ng/signer/src/wire/netio.h
   branches/OpenDNSSEC-enforcer-ng/signer/src/wire/notify.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/wire/query.c
   branches/OpenDNSSEC-enforcer-ng/signer/src/wire/query.h
   branches/OpenDNSSEC-enforcer-ng/signer/src/wire/sock.c
Log:
merge with trunk




Property changes on: branches/OpenDNSSEC-enforcer-ng/signer
___________________________________________________________________
Added: svn:mergeinfo
   + /branches/OpenDNSSEC-sion/signer:3411-3767
/trunk/OpenDNSSEC/signer:4293-6034

Modified: branches/OpenDNSSEC-enforcer-ng/signer/doc/Changelog
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/doc/Changelog	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/doc/Changelog	2012-01-09 15:28:29 UTC (rev 6046)
@@ -1,3 +1,10 @@
+2 Jan 2012: Matthijs
+- OPENDNSSEC-174: --config option not caught
+- Define PF_INET and PF_INET6 if undeclared
+
+30 November 2011: Matthijs
+- Zonefetcher deprecated
+
 29 November 2011: Matthijs
 - OPENDNSSEC-156: Always update the new addns config
 - OPENDNSSEC-163: better ixfr handling

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/adapter/adapi.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/adapter/adapi.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/adapter/adapi.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -409,9 +409,18 @@
 void
 adapi_printixfr(FILE* fd, zone_type* zone)
 {
-    if (!fd || !zone || !zone->ixfr) {
+    rrset_type* rrset = NULL;
+    if (!fd || !zone || !zone->db || !zone->ixfr) {
         return;
     }
+    if (!zone->db->is_initialized) {
+        /* no ixfr yet */
+        return;
+    }
+    rrset = zone_lookup_rrset(zone, zone->apex, LDNS_RR_TYPE_SOA);
+    ods_log_assert(rrset);
+    rrset_print(fd, rrset, 1);
     ixfr_print(fd, zone->ixfr);
+    rrset_print(fd, rrset, 1);
     return;
 }

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/adapter/addns.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/adapter/addns.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/adapter/addns.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -639,15 +639,17 @@
     adapi_printaxfr(fd, z);
     ods_fclose(fd);
 
-    itmpfile = ods_build_path(z->name, ".ixfr.tmp", 0);
-    fd = ods_fopen(itmpfile, NULL, "w");
-    if (!fd) {
-        free((void*) atmpfile);
-        free((void*) itmpfile);
-        return ODS_STATUS_FOPEN_ERR;
+    if (z->db->is_initialized) {
+        itmpfile = ods_build_path(z->name, ".ixfr.tmp", 0);
+        fd = ods_fopen(itmpfile, NULL, "w");
+        if (!fd) {
+            free((void*) atmpfile);
+            free((void*) itmpfile);
+            return ODS_STATUS_FOPEN_ERR;
+        }
+        adapi_printixfr(fd, z);
+        ods_fclose(fd);
     }
-    adapi_printixfr(fd, z);
-    ods_fclose(fd);
 
     /* lock and move */
     axfrfile = ods_build_path(z->name, ".axfr", 0);
@@ -664,18 +666,21 @@
     }
     free((void*) atmpfile);
     free((void*) axfrfile);
-    ixfrfile = ods_build_path(z->name, ".ixfr", 0);
-    ret = rename(itmpfile, ixfrfile);
-    if (ret != 0) {
-        ods_log_error("[%s] unable to rename file %s to %s: %s", adapter_str,
-            itmpfile, ixfrfile, strerror(errno));
-        lock_basic_unlock(&z->xfr_lock);
+
+    if (z->db->is_initialized) {
+        ixfrfile = ods_build_path(z->name, ".ixfr", 0);
+        ret = rename(itmpfile, ixfrfile);
+        if (ret != 0) {
+            ods_log_error("[%s] unable to rename file %s to %s: %s",
+                adapter_str, itmpfile, ixfrfile, strerror(errno));
+            lock_basic_unlock(&z->xfr_lock);
+            free((void*) itmpfile);
+            free((void*) ixfrfile);
+            return ODS_STATUS_RENAME_ERR;
+        }
         free((void*) itmpfile);
         free((void*) ixfrfile);
-        return ODS_STATUS_RENAME_ERR;
     }
-    free((void*) itmpfile);
-    free((void*) ixfrfile);
     lock_basic_unlock(&z->xfr_lock);
 
     dnsout_send_notify(zone);

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/daemon/engine.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/daemon/engine.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/daemon/engine.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -704,6 +704,8 @@
             ods_log_assert(zone->xfrd);
             netio_add_handler(engine->xfrhandler->netio,
                 &zone->xfrd->handler);
+        } else if (!zone->xfrd->serial_disk_acquired) {
+            xfrd_set_timer_now(zone->xfrd);
         }
     } else if (zone->xfrd) {
         netio_remove_handler(engine->xfrhandler->netio,

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/daemon/worker.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/daemon/worker.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/daemon/worker.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -155,16 +155,25 @@
 worker_queue_rrset(worker_type* worker, fifoq_type* q, rrset_type* rrset)
 {
     ods_status status = ODS_STATUS_UNCHANGED;
+    int tries = 0;
     ods_log_assert(worker);
     ods_log_assert(q);
     ods_log_assert(rrset);
     while (status == ODS_STATUS_UNCHANGED) {
+        tries++;
         lock_basic_lock(&q->q_lock);
-        status = fifoq_push(q, (void*) rrset, worker);
+        status = fifoq_push(q, (void*) rrset, worker, &tries);
         lock_basic_unlock(&q->q_lock);
         if (worker->need_to_exit) {
             return;
         }
+        /**
+         * If tries are 0 they we have tries FIFOQ_TRIES_COUNT times,
+         * lets take a small break to not hog CPU.
+         */
+        if (status == ODS_STATUS_UNCHANGED && !tries) {
+            usleep(10000);
+        }
     }
     ods_log_assert(status == ODS_STATUS_OK);
     lock_basic_lock(&worker->worker_lock);

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/ods-signerd.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/ods-signerd.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/ods-signerd.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -117,6 +117,9 @@
             case '1':
                 single_run = 1;
                 break;
+            case 'c':
+                cfgfile = optarg;
+                break;
             case 'd':
                 daemonize = 0;
                 break;

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/scheduler/fifoq.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/scheduler/fifoq.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/scheduler/fifoq.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -111,7 +111,7 @@
  *
  */
 ods_status
-fifoq_push(fifoq_type* q, void* item, worker_type* worker)
+fifoq_push(fifoq_type* q, void* item, worker_type* worker, int* tries)
 {
     size_t count = 0;
     if (!q || !item || !worker) {
@@ -120,6 +120,14 @@
     if (q->count >= FIFOQ_MAX_COUNT) {
         ods_log_deeebug("[%s] unable to push item: max cap reached",
             fifoq_str);
+        /* #262 if drudgers remain on hold, do additional broadcast */
+        if (*tries > FIFOQ_TRIES_COUNT) {
+            lock_basic_broadcast(&q->q_threshold);
+            ods_log_debug("[%s] max cap reached, but drudgers seem to be "
+                "on hold, notify drudgers again", fifoq_str);
+            /* reset tries */
+            *tries = 0;
+        }
         return ODS_STATUS_UNCHANGED;
     }
     count = q->count;

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/scheduler/fifoq.h
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/scheduler/fifoq.h	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/scheduler/fifoq.h	2012-01-09 15:28:29 UTC (rev 6046)
@@ -53,6 +53,7 @@
 #include <ldns/ldns.h>
 
 #define FIFOQ_MAX_COUNT 1000
+#define FIFOQ_TRIES_COUNT 100
 
 /**
  * FIFO Queue.
@@ -97,10 +98,12 @@
  * \param[in] q queue
  * \param[in] item item
  * \param[in] worker owner of item
+ * \param[out] tries number of tries
  * \return ods_status status
  *
  */
-ods_status fifoq_push(fifoq_type* q, void* item, worker_type* worker);
+ods_status fifoq_push(fifoq_type* q, void* item, worker_type* worker,
+    int* tries);
 
 /**
  * Clean up queue.

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/signer/ixfr.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/signer/ixfr.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/signer/ixfr.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -55,7 +55,8 @@
             "allocator_alloc() failed", ixfr_str);
         return NULL;
     }
-
+    part->soaplus = NULL;
+    part->soamin = NULL;
     part->plus = ldns_rr_list_new();
     if (!part->plus) {
         ods_log_error("[%s] unable to create ixfr part: "
@@ -91,6 +92,7 @@
     return;
 }
 
+
 /**
  * Create a new ixfr journal.
  *
@@ -115,13 +117,6 @@
     for (i=0; i < IXFR_MAX_PARTS; i++) {
         xfr->part[i] = NULL;
     }
-    xfr->part[0] = part_create(z->allocator);
-    if (!xfr->part[0]) {
-        ods_log_error("[%s] unable to create ixfr for zone %s: "
-            "allocator_alloc() failed", ixfr_str, z->name);
-        allocator_deallocate(z->allocator, (void*) xfr);
-        return NULL;
-    }
     xfr->zone = zone;
     return xfr;
 }
@@ -134,9 +129,17 @@
 void
 ixfr_add_rr(ixfr_type* ixfr, ldns_rr* rr)
 {
+    zone_type* zone = NULL;
     if (!ixfr || !rr) {
         return;
     }
+    zone = (zone_type*) ixfr->zone;
+    ods_log_assert(zone);
+    ods_log_assert(zone->db);
+    if (!zone->db->is_initialized) {
+        /* no ixfr yet */
+        return;
+    }
     ods_log_assert(ixfr->part[0]);
     ods_log_assert(ixfr->part[0]->plus);
     if (!ldns_rr_list_push_rr(ixfr->part[0]->plus, rr)) {
@@ -144,6 +147,9 @@
             ixfr_str);
         exit(1);
     }
+    if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
+        ixfr->part[0]->soaplus = rr;
+    }
     return;
 }
 
@@ -155,9 +161,17 @@
 void
 ixfr_del_rr(ixfr_type* ixfr, ldns_rr* rr)
 {
+    zone_type* zone = NULL;
     if (!ixfr || !rr) {
         return;
     }
+    zone = (zone_type*) ixfr->zone;
+    ods_log_assert(zone);
+    ods_log_assert(zone->db);
+    if (!zone->db->is_initialized) {
+        /* no ixfr yet */
+        return;
+    }
     ods_log_assert(ixfr->part[0]);
     ods_log_assert(ixfr->part[0]->min);
     if (!ldns_rr_list_push_rr(ixfr->part[0]->min, rr)) {
@@ -165,11 +179,56 @@
             ixfr_str);
         exit(1);
     }
+    if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
+        ixfr->part[0]->soamin = rr;
+    }
     return;
 }
 
 
 /**
+ * Print all RRs in list, except SOA RRs.
+ *
+ */
+static void
+part_rr_list_print_nonsoa(FILE* fd, ldns_rr_list* list)
+{
+    size_t i = 0;
+    if (!list || !fd) {
+        return;
+    }
+    for (i = 0; i < ldns_rr_list_rr_count(list); i++) {
+        if (ldns_rr_get_type(ldns_rr_list_rr(list, i)) != LDNS_RR_TYPE_SOA) {
+            ldns_rr_print(fd, ldns_rr_list_rr(list, i));
+        }
+    }
+    return;
+}
+
+
+/**
+ * Print part of the ixfr journal.
+ *
+ */
+static void
+part_print(FILE* fd, part_type* part)
+{
+    if (!part || !fd) {
+        return;
+    }
+    ods_log_assert(part->min);
+    ods_log_assert(part->plus);
+    ods_log_assert(part->soamin);
+    ods_log_assert(part->soaplus);
+    ldns_rr_print(fd, part->soamin);
+    part_rr_list_print_nonsoa(fd, part->min);
+    ldns_rr_print(fd, part->soaplus);
+    part_rr_list_print_nonsoa(fd, part->plus);
+    return;
+}
+
+
+/**
  * Print the ixfr journal.
  *
  */
@@ -183,18 +242,7 @@
     ods_log_debug("[%s] print ixfr", ixfr_str);
 
     for (i = IXFR_MAX_PARTS - 1; i >= 0; i--) {
-        if (ixfr->part[i]) {
-            ods_log_assert(ixfr->part[i]->plus);
-            ods_log_assert(ixfr->part[i]->min);
-
-            ods_log_deeebug("[%s] print ixfr part #%d", ixfr_str, i);
-
-            fprintf(fd, ";; IXFR part #%d -RR\n", i);
-            ldns_rr_list_print(fd, ixfr->part[i]->min);
-            fprintf(fd, ";; IXFR part #%d +RR\n", i);
-            ldns_rr_list_print(fd, ixfr->part[i]->plus);
-            fprintf(fd, "\n");
-        }
+        part_print(fd, ixfr->part[i]);
     }
     return;
 }

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/signer/ixfr.h
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/signer/ixfr.h	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/signer/ixfr.h	2012-01-09 15:28:29 UTC (rev 6046)
@@ -46,8 +46,10 @@
  */
 typedef struct part_struct part_type;
 struct part_struct {
+    ldns_rr* soamin;
+    ldns_rr_list* min;
+    ldns_rr* soaplus;
     ldns_rr_list* plus;
-    ldns_rr_list* min;
 };
 
 /**

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/signer/namedb.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/signer/namedb.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/signer/namedb.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -1019,6 +1019,10 @@
 
     if (db && db->denials) {
         zone = (zone_type*) db->zone;
+        ods_log_assert(zone);
+        ods_log_assert(zone->name);
+        ods_log_debug("[%s] wipe denial of existence space zone %s", db_str,
+            zone->name);
         node = ldns_rbtree_first(db->denials);
         while (node && node != LDNS_RBTREE_NULL) {
             denial = (denial_type*) node->data;

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/signer/zone.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/signer/zone.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/signer/zone.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -1000,6 +1000,7 @@
         /* all ok */
         namedb_diff(zone->db, 0);
         zone->db->is_initialized = 1;
+        ixfr_purge(zone->ixfr);
         if (zone->stats) {
             lock_basic_lock(&zone->stats->stats_lock);
             stats_clear(zone->stats);

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/wire/axfr.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/wire/axfr.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/wire/axfr.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -60,13 +60,12 @@
     uint32_t ttl = 0;
     ldns_status status = LDNS_STATUS_OK;
     char line[SE_ADFILE_MAXLINE];
-    unsigned soa_seen = 0;
     unsigned l = 0;
     long fpos = 0;
-
+    size_t bufpos = 0;
     ods_log_assert(q);
+    ods_log_assert(q->buffer);
     ods_log_assert(engine);
-
     if (q->axfr_is_done) {
         return QUERY_PROCESSED;
     }
@@ -88,13 +87,14 @@
         /* start axfr */
         xfrfile = ods_build_path(q->zone->name, ".axfr", 0);
         q->axfr_fd = ods_fopen(xfrfile, NULL, "r");
-        free((void*)xfrfile);
         if (!q->axfr_fd) {
             ods_log_error("[%s] unable to open axfr file %s for zone %s",
                 axfr_str, xfrfile, q->zone->name);
+            free((void*)xfrfile);
             buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
             return QUERY_PROCESSED;
         }
+        free((void*)xfrfile);
         if (q->tsig_rr->status == TSIG_OK) {
             q->tsig_sign_it = 1; /* sign first packet in stream */
         }
@@ -109,6 +109,8 @@
             ods_log_error("[%s] bad axfr zone %s, corrupted file",
                 axfr_str, q->zone->name);
             buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+            ods_fclose(q->axfr_fd);
+            q->axfr_fd = NULL;
             return QUERY_PROCESSED;
         }
         if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
@@ -116,22 +118,33 @@
                 axfr_str, q->zone->name);
             ldns_rr_free(rr);
             buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+            ods_fclose(q->axfr_fd);
+            q->axfr_fd = NULL;
             return QUERY_PROCESSED;
         }
         /* does it fit? */
         if (buffer_write_rr(q->buffer, rr)) {
+            ods_log_debug("[%s] set soa in axfr zone %s", axfr_str,
+                q->zone->name);
             buffer_pkt_set_ancount(q->buffer, buffer_pkt_ancount(q->buffer)+1);
             total_added++;
             ldns_rr_free(rr);
             rr = NULL;
+            bufpos = buffer_position(q->buffer);
         } else {
+            ods_log_error("[%s] soa does not fit in axfr zone %s",
+                axfr_str, q->zone->name);
             ldns_rr_free(rr);
             rr = NULL;
             buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+            ods_fclose(q->axfr_fd);
+            q->axfr_fd = NULL;
             return QUERY_PROCESSED;
         }
-    } else {
+    } else if (q->tcp) {
         /* subsequent axfr packets */
+        ods_log_debug("[%s] subsequent axfr packet zone %s", axfr_str,
+            q->zone->name);
         buffer_set_limit(q->buffer, BUFFER_PKT_HEADER_SIZE);
         buffer_pkt_set_qdcount(q->buffer, 0);
         query_prepare(q);
@@ -140,38 +153,220 @@
     fpos = ftell(q->axfr_fd);
     while ((rr = addns_read_rr(q->axfr_fd, line, &orig, &prev, &ttl,
         &status, &l)) != NULL) {
+        ods_log_deeebug("[%s] read rr at line %d", axfr_str, l);
         if (status != LDNS_STATUS_OK) {
             ldns_rr_free(rr);
             rr = NULL;
             ods_log_error("[%s] error reading rr at line %i (%s): %s",
                 axfr_str, l, ldns_get_errorstr_by_id(status), line);
             buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+            ods_fclose(q->axfr_fd);
+            q->axfr_fd = NULL;
             return QUERY_PROCESSED;
         }
         /* does it fit? */
         if (buffer_write_rr(q->buffer, rr)) {
+            ods_log_deeebug("[%s] add rr at line %d", axfr_str, l);
             fpos = ftell(q->axfr_fd);
             buffer_pkt_set_ancount(q->buffer, buffer_pkt_ancount(q->buffer)+1);
             total_added++;
             ldns_rr_free(rr);
             rr = NULL;
         } else {
+            ods_log_deeebug("[%s] rr at line %d does not fit", axfr_str, l);
             ldns_rr_free(rr);
             rr = NULL;
             if (fseek(q->axfr_fd, fpos, SEEK_SET) != 0) {
                 ods_log_error("[%s] unable to reset file position in axfr "
                     "file: fseek() failed (%s)", axfr_str, strerror(errno));
                 buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+                ods_fclose(q->axfr_fd);
+                q->axfr_fd = NULL;
                 return QUERY_PROCESSED;
+            } else if (q->tcp) {
+                goto return_axfr;
             } else {
-                goto return_answer;
+                goto udp_overflow;
             }
         }
     }
+    ods_log_debug("[%s] axfr zone %s is done", axfr_str, q->zone->name);
     q->tsig_sign_it = 1; /* sign last packet */
     q->axfr_is_done = 1;
+    ods_fclose(q->axfr_fd);
+    q->axfr_fd = NULL;
 
-return_answer:
+return_axfr:
+    if (q->tcp) {
+        ods_log_debug("[%s] return part axfr zone %s", axfr_str,
+            q->zone->name);
+        buffer_pkt_set_ancount(q->buffer, total_added);
+        buffer_pkt_set_nscount(q->buffer, 0);
+        buffer_pkt_set_arcount(q->buffer, 0);
+        /* check if it needs tsig signatures */
+        if (q->tsig_rr->status == TSIG_OK) {
+            if (q->tsig_rr->update_since_last_prepare >=
+                AXFR_TSIG_SIGN_EVERY_NTH) {
+                q->tsig_sign_it = 1;
+            }
+        }
+        return QUERY_AXFR;
+    }
+udp_overflow:
+    /* UDP Overflow */
+    ods_log_info("[%s] axfr udp overflow zone %s", axfr_str, q->zone->name);
+    buffer_set_position(q->buffer, bufpos);
+    buffer_pkt_set_ancount(q->buffer, 1);
+    buffer_pkt_set_nscount(q->buffer, 0);
+    buffer_pkt_set_arcount(q->buffer, 0);
+    /* check if it needs tsig signatures */
+    if (q->tsig_rr->status == TSIG_OK) {
+        q->tsig_sign_it = 1;
+    }
+    return QUERY_PROCESSED;
+
+}
+
+
+/**
+ * Do IXFR (equal to AXFR for now).
+ *
+ */
+query_state
+ixfr(query_type* q, engine_type* engine)
+{
+    char* xfrfile = NULL;
+    ldns_rr* rr = NULL;
+    ldns_rdf* prev = NULL;
+    ldns_rdf* orig = NULL;
+    uint16_t total_added = 0;
+    uint32_t ttl = 0;
+    ldns_status status = LDNS_STATUS_OK;
+    char line[SE_ADFILE_MAXLINE];
+    unsigned l = 0;
+    long fpos = 0;
+    size_t bufpos = 0;
+    ods_log_assert(q);
+    ods_log_assert(q->buffer);
+    ods_log_assert(engine);
+    if (q->axfr_is_done) {
+        return QUERY_PROCESSED;
+    }
+    if (q->maxlen > AXFR_MAX_MESSAGE_LEN) {
+        q->maxlen = AXFR_MAX_MESSAGE_LEN;
+    }
+    /* prepare tsig */
+    q->tsig_prepare_it = 0;
+    q->tsig_update_it = 1;
+    if (q->tsig_sign_it) {
+        q->tsig_prepare_it = 1;
+        q->tsig_sign_it = 0;
+    }
+    ods_log_assert(q->tsig_rr);
+    ods_log_assert(q->zone);
+    ods_log_assert(q->zone->name);
+    if (q->axfr_fd == NULL) {
+        /* start ixfr */
+        xfrfile = ods_build_path(q->zone->name, ".ixfr", 0);
+        q->axfr_fd = ods_fopen(xfrfile, NULL, "r");
+        if (!q->axfr_fd) {
+            ods_log_error("[%s] unable to open ixfr file %s for zone %s",
+                axfr_str, xfrfile, q->zone->name);
+            ods_log_info("[%s] axfr fallback zone %s", axfr_str,
+                q->zone->name);
+            free((void*)xfrfile);
+            return axfr(q, engine);
+        }
+        free((void*)xfrfile);
+        if (q->tsig_rr->status == TSIG_OK) {
+            q->tsig_sign_it = 1; /* sign first packet in stream */
+        }
+        /* compression? */
+
+        /* add soa rr */
+        fpos = ftell(q->axfr_fd);
+        rr = addns_read_rr(q->axfr_fd, line, &orig, &prev, &ttl, &status,
+            &l);
+        if (!rr) {
+            /* no SOA no transfer */
+            ods_log_error("[%s] bad ixfr zone %s, corrupted file",
+                axfr_str, q->zone->name);
+            buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+            return QUERY_PROCESSED;
+        }
+        if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_SOA) {
+            ods_log_error("[%s] bad ixfr zone %s, first rr is not soa",
+                axfr_str, q->zone->name);
+            ldns_rr_free(rr);
+            buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+            return QUERY_PROCESSED;
+        }
+        /* does it fit? */
+        if (buffer_write_rr(q->buffer, rr)) {
+            ods_log_debug("[%s] set soa in ixfr zone %s", axfr_str,
+                q->zone->name);
+            buffer_pkt_set_ancount(q->buffer, buffer_pkt_ancount(q->buffer)+1);
+            total_added++;
+            ldns_rr_free(rr);
+            rr = NULL;
+            bufpos = buffer_position(q->buffer);
+        } else {
+            ods_log_error("[%s] soa does not fit in ixfr zone %s",
+                axfr_str, q->zone->name);
+            ldns_rr_free(rr);
+            rr = NULL;
+            buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+            return QUERY_PROCESSED;
+        }
+    } else if (q->tcp) {
+        /* subsequent ixfr packets */
+        ods_log_debug("[%s] subsequent ixfr packet zone %s", axfr_str,
+            q->zone->name);
+        buffer_set_limit(q->buffer, BUFFER_PKT_HEADER_SIZE);
+        buffer_pkt_set_qdcount(q->buffer, 0);
+        query_prepare(q);
+    }
+
+    /* add as many records as fit */
+    fpos = ftell(q->axfr_fd);
+    while ((rr = addns_read_rr(q->axfr_fd, line, &orig, &prev, &ttl,
+        &status, &l)) != NULL) {
+        if (status != LDNS_STATUS_OK) {
+            ldns_rr_free(rr);
+            rr = NULL;
+            ods_log_error("[%s] error reading rr at line %i (%s): %s",
+                axfr_str, l, ldns_get_errorstr_by_id(status), line);
+            goto axfr_fallback;
+        }
+        /* does it fit? */
+        if (buffer_write_rr(q->buffer, rr)) {
+            fpos = ftell(q->axfr_fd);
+            buffer_pkt_set_ancount(q->buffer, buffer_pkt_ancount(q->buffer)+1);
+            total_added++;
+            ldns_rr_free(rr);
+            rr = NULL;
+        } else {
+            ldns_rr_free(rr);
+            rr = NULL;
+            if (fseek(q->axfr_fd, fpos, SEEK_SET) != 0) {
+                ods_log_error("[%s] unable to reset file position in axfr "
+                    "file: fseek() failed (%s)", axfr_str, strerror(errno));
+                buffer_pkt_set_rcode(q->buffer, LDNS_RCODE_SERVFAIL);
+                return QUERY_PROCESSED;
+            } else if (q->tcp) {
+                goto return_ixfr;
+            } else {
+                goto axfr_fallback;
+            }
+        }
+    }
+    ods_log_debug("[%s] ixfr zone %s is done", axfr_str, q->zone->name);
+    q->tsig_sign_it = 1; /* sign last packet */
+    q->axfr_is_done = 1;
+    ods_fclose(q->axfr_fd);
+
+return_ixfr:
+    ods_log_debug("[%s] return part ixfr zone %s", axfr_str, q->zone->name);
     buffer_pkt_set_ancount(q->buffer, total_added);
     buffer_pkt_set_nscount(q->buffer, 0);
     buffer_pkt_set_arcount(q->buffer, 0);
@@ -182,5 +377,26 @@
             q->tsig_sign_it = 1;
         }
     }
+    return QUERY_IXFR;
+
+axfr_fallback:
+    if (q->tcp) {
+        ods_log_info("[%s] axfr fallback zone %s", axfr_str, q->zone->name);
+        if (q->axfr_fd) {
+            ods_fclose(q->axfr_fd);
+            q->axfr_fd = NULL;
+        }
+        return axfr(q, engine);
+    }
+    /* UDP Overflow */
+    ods_log_info("[%s] ixfr udp overflow zone %s", axfr_str, q->zone->name);
+    buffer_set_position(q->buffer, bufpos);
+    buffer_pkt_set_ancount(q->buffer, 1);
+    buffer_pkt_set_nscount(q->buffer, 0);
+    buffer_pkt_set_arcount(q->buffer, 0);
+    /* check if it needs tsig signatures */
+    if (q->tsig_rr->status == TSIG_OK) {
+        q->tsig_sign_it = 1;
+    }
     return QUERY_PROCESSED;
 }

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/wire/axfr.h
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/wire/axfr.h	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/wire/axfr.h	2012-01-09 15:28:29 UTC (rev 6046)
@@ -53,4 +53,13 @@
  */
 query_state axfr(query_type* q, engine_type* engine);
 
+/**
+ * Do IXFR.
+ * \param[in] q ixfr request
+ * \param[in] engine signer engine
+ * \return query_state state of the query
+ *
+ */
+query_state ixfr(query_type* q, engine_type* engine);
+
 #endif /* WIRE_AXFR_H */

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/wire/netio.h
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/wire/netio.h	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/wire/netio.h	2012-01-09 15:28:29 UTC (rev 6046)
@@ -56,6 +56,13 @@
 #include "config.h"
 #include "shared/allocator.h"
 
+#ifndef PF_INET
+#define PF_INET AF_INET
+#endif
+#ifndef PF_INET6
+#define PF_INET6 AF_INET6
+#endif
+
 /*
  * The type of events a handler is interested in.
  * These can be OR'ed together to specify multiple event types.

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/wire/notify.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/wire/notify.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/wire/notify.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -38,6 +38,8 @@
 #include "wire/notify.h"
 #include "wire/xfrd.h"
 
+#include <sys/socket.h>
+
 static const char* notify_str = "notify";
 
 static void notify_handle_zone(netio_type* netio,

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/wire/query.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/wire/query.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/wire/query.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -542,6 +542,11 @@
         buffer_pkt_set_flags(q->buffer, 0);
         return query_formerr(q);
     }
+    if (buffer_pkt_ancount(q->buffer) != 0 ||
+        (qtype != LDNS_RR_TYPE_IXFR && buffer_pkt_nscount(q->buffer) != 0)) {
+        buffer_pkt_set_flags(q->buffer, 0);
+        return query_formerr(q);
+    }
     /* acl */
     if (!q->zone->adoutbound || q->zone->adoutbound->type != ADAPTER_DNS) {
         ods_log_error("[%s] zone %s is not configured to have output dns "
@@ -554,15 +559,15 @@
     if (!acl_find(dnsout->provide_xfr, &q->addr, q->tsig_rr)) {
         return query_refused(q);
     }
+    /* prepare */
+    query_prepare(q);
     /* ixfr? */
     if (qtype == LDNS_RR_TYPE_IXFR) {
         ods_log_assert(q->zone->name);
         ods_log_debug("[%s] incoming ixfr request for zone %s",
             query_str, q->zone->name);
-        return query_notimpl(q);
+        return ixfr(q, engine);
     }
-    /* prepare */
-    query_prepare(q);
     /* axfr? */
     if (qtype == LDNS_RR_TYPE_AXFR) {
         ods_log_assert(q->zone->name);

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/wire/query.h
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/wire/query.h	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/wire/query.h	2012-01-09 15:28:29 UTC (rev 6046)
@@ -47,7 +47,8 @@
 enum query_enum {
         QUERY_PROCESSED = 0,
         QUERY_DISCARDED,
-        QUERY_AXFR
+        QUERY_AXFR,
+        QUERY_IXFR
 };
 typedef enum query_enum query_state;
 
@@ -77,8 +78,9 @@
     zone_type* zone;
     /* Compression */
 
-    /* AXFR */
+    /* AXFR IXFR */
     FILE* axfr_fd;
+    uint32_t serial;
     /* Bits */
     unsigned axfr_is_done : 1;
     unsigned tsig_prepare_it : 1;

Modified: branches/OpenDNSSEC-enforcer-ng/signer/src/wire/sock.c
===================================================================
--- branches/OpenDNSSEC-enforcer-ng/signer/src/wire/sock.c	2012-01-09 15:22:43 UTC (rev 6045)
+++ branches/OpenDNSSEC-enforcer-ng/signer/src/wire/sock.c	2012-01-09 15:28:29 UTC (rev 6046)
@@ -81,6 +81,7 @@
     return ODS_STATUS_OK;
 }
 
+
 /**
  * Set socket to v6 only.
  *
@@ -385,64 +386,6 @@
 
 
 /**
- * Handle QUERY.
- *
- */
-/*
-static void
-sock_handle_transfer(ldns_pkt* pkt, ldns_rr* rr, engine_type* engine,
-    zone_type* zone, void (*sendfunc)(uint8_t*, size_t, void*), int is_tcp,
-    void* userdata)
-{
-    if (!pkt || !rr || !engine || !zone) {
-        sock_send_error(pkt, LDNS_RCODE_FORMERR, sendfunc, userdata);
-        return;
-    }
-    if (ldns_pkt_get_rcode(pkt) != LDNS_RCODE_NOERROR ||
-        ldns_pkt_qr(pkt) ||
-        ldns_pkt_aa(pkt) ||
-        ldns_pkt_tc(pkt) ||
-        ldns_pkt_ra(pkt) ||
-        ldns_pkt_qdcount(pkt) != 1 ||
-        ldns_pkt_ancount(pkt) > 1 ||
-        ldns_rr_get_class(rr) != LDNS_RR_CLASS_IN) {
-        sock_send_error(pkt, LDNS_RCODE_FORMERR, sendfunc, userdata);
-        return;
-    }
-    if (ldns_rr_get_type(rr) != LDNS_RR_TYPE_IXFR &&
-        (ldns_pkt_nscount(pkt) != 0 || ldns_pkt_arcount(pkt) != 0)) {
-        sock_send_error(pkt, LDNS_RCODE_FORMERR, sendfunc, userdata);
-        return;
-    }
-
-    switch (ldns_rr_get_type(rr)) {
-        case LDNS_RR_TYPE_AXFR:
-             add axfr to answer section
-            if (is_tcp) {
-                struct tcp_data *ud =
-                    (struct tcp_data*) userdata;
-                query_reset(ud->socket->query, TCP_MAX_MESSAGE_LEN, 1);
-                axfr(ud->socket->query, engine);
-            }
-        case LDNS_RR_TYPE_IXFR:
-            search serial
-            add ixfr to answer section
-        case LDNS_RR_TYPE_SOA:
-            add soa to answer section
-            add ns to auth section
-            add glues to addition section
-        default:
-            sock_send_error(pkt, LDNS_RCODE_NOTIMPL, sendfunc, userdata);
-            return;
-    }
-    default
-    sock_send_error(pkt, LDNS_RCODE_NOTIMPL, sendfunc, userdata);
-    return;
-}
-*/
-
-
-/**
  * Handle incoming udp queries.
  *
  */
@@ -474,6 +417,7 @@
     buffer_flip(q->buffer);
     qstate = query_process(q, data->engine);
     if (qstate != QUERY_DISCARDED) {
+        ods_log_debug("[%s] query processed qstate=%d", sock_str, qstate);
         query_add_tsig(q);
         buffer_flip(q->buffer);
         send_udp(data, q);
@@ -717,6 +661,7 @@
         cleanup_tcp_handler(netio, handler);
         return;
     }
+    ods_log_debug("[%s] query processed qstate=%d", sock_str, qstate);
     /* tsig */
     query_add_tsig(data->query);
     /* switch to tcp write handler. */
@@ -816,10 +761,14 @@
     ods_log_debug("[%s] TCP_WRITE: sizeof tcplen %u", sock_str,
         sizeof(q->tcplen));
     ods_log_assert(data->bytes_transmitted == q->tcplen + sizeof(q->tcplen));
-    if (data->qstate == QUERY_AXFR) {
+    if (data->qstate == QUERY_AXFR || data->qstate == QUERY_IXFR) {
         /* continue processing AXFR and writing back results.  */
         buffer_clear(q->buffer);
-        data->qstate = axfr(q, data->engine);
+        if (data->qstate == QUERY_IXFR) {
+            data->qstate = ixfr(q, data->engine);
+        } else {
+            data->qstate = axfr(q, data->engine);
+        }
         if (data->qstate != QUERY_PROCESSED) {
             /* tsig */
             query_add_tsig(q);




More information about the Opendnssec-commits mailing list