[Opendnssec-commits] [svn.opendnssec.org/svn/dnssec] r5482 - in branches/OpenDNSSEC-adapters/signer/src: daemon signer

matthijs at nlnetlabs.nl matthijs at nlnetlabs.nl
Thu Aug 25 15:30:17 CEST 2011


Author: matthijs
Date: 2011-08-25 15:30:17 +0200 (Thu, 25 Aug 2011)
New Revision: 5482

Modified:
   branches/OpenDNSSEC-adapters/signer/src/daemon/cmdhandler.c
   branches/OpenDNSSEC-adapters/signer/src/daemon/worker.c
   branches/OpenDNSSEC-adapters/signer/src/signer/denial.c
   branches/OpenDNSSEC-adapters/signer/src/signer/denial.h
   branches/OpenDNSSEC-adapters/signer/src/signer/domain.c
   branches/OpenDNSSEC-adapters/signer/src/signer/domain.h
   branches/OpenDNSSEC-adapters/signer/src/signer/namedb.c
   branches/OpenDNSSEC-adapters/signer/src/signer/namedb.h
   branches/OpenDNSSEC-adapters/signer/src/signer/rrset.c
   branches/OpenDNSSEC-adapters/signer/src/signer/rrset.h
   branches/OpenDNSSEC-adapters/signer/src/signer/tools.c
   branches/OpenDNSSEC-adapters/signer/src/signer/zone.c
Log:
rbtree for rrsets is overkill, no need for ordering anyway
change rrset structure
remove another overkill: add/cur/del rrsets



Modified: branches/OpenDNSSEC-adapters/signer/src/daemon/cmdhandler.c
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/daemon/cmdhandler.c	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/daemon/cmdhandler.c	2011-08-25 13:30:17 UTC (rev 5482)
@@ -425,12 +425,7 @@
             ods_log_warning("[%s] unable to restore DNSKEY RRset for zone %s,"
                 " reloading signconf", cmdh_str, zone->name);
         }
-        if (status == ODS_STATUS_OK) {
-            status = namedb_commit(zone->db);
-        } else {
-            ods_log_warning("[%s] unable to restore NSEC3PARAM RRset for "
-                " zone %s d1reloading signconf", cmdh_str, zone->name);
-        }
+        namedb_diff(zone->db, NULL);
 
         task = (task_type*) zone->task;
         task->what = TASK_READ;

Modified: branches/OpenDNSSEC-adapters/signer/src/daemon/worker.c
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/daemon/worker.c	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/daemon/worker.c	2011-08-25 13:30:17 UTC (rev 5482)
@@ -203,9 +203,8 @@
                 status = zone_publish_nsec3param(zone, 0);
             }
             if (status == ODS_STATUS_OK) {
-                status = namedb_commit(zone->db);
+                namedb_diff(zone->db, NULL);
             }
-
             if (status == ODS_STATUS_OK) {
                 zone->prepared = 1;
                 task->interrupt = TASK_NONE;

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/denial.c
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/denial.c	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/denial.c	2011-08-25 13:30:17 UTC (rev 5482)
@@ -36,7 +36,6 @@
 #include "shared/log.h"
 #include "signer/denial.h"
 #include "signer/domain.h"
-#include "signer/nsec3params.h"
 #include "signer/zone.h"
 
 #include <ldns/ldns.h>
@@ -83,7 +82,6 @@
 denial_create_bitmap(denial_type* denial, ldns_rr_type types[],
     size_t* types_count)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
     domain_type* domain = NULL;
     rrset_type* rrset = NULL;
 
@@ -91,13 +89,11 @@
     ods_log_assert(denial->domain);
 
     domain = (domain_type*) denial->domain;
-    node = ldns_rbtree_first(domain->rrsets);
-
-    while (node && node != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) node->data;
+    rrset = domain->rrsets;
+    while (rrset) {
         types[*types_count] = rrset->rrtype;
         *types_count = *types_count + 1;
-        node = ldns_rbtree_next(node);
+        rrset = rrset->next;
     }
     return;
 }
@@ -127,7 +123,6 @@
             denial_str);
         return NULL;
     }
-    ods_log_assert(nsec_rr);
 
     ldns_rr_set_type(nsec_rr, LDNS_RR_TYPE_NSEC);
     rdf = ldns_rdf_clone(denial->dname);
@@ -211,29 +206,14 @@
                 "create NSEC RR", denial_str);
             return ODS_STATUS_ERR;
         }
-        /* delete old NSEC RR(s)... */
-        status = rrset_wipe_out(denial->rrset);
-        if (status != ODS_STATUS_OK) {
-            ods_log_alert("[%s] unable to nsecify: failed to "
-                "wipe out NSEC RRset", denial_str);
-            ldns_rr_free(nsec_rr);
-            return status;
-        }
-        /* ...and add the new one */
+        /* add the new one */
         if (!rrset_add_rr(denial->rrset, nsec_rr)) {
             ods_log_alert("[%s] unable to nsecify: failed to "
                 "add NSEC to RRset", denial_str);
             ldns_rr_free(nsec_rr);
             return ODS_STATUS_ERR;
         }
-        /* commit */
-        status = rrset_commit(denial->rrset);
-        if (status != ODS_STATUS_OK) {
-            ods_log_alert("[%s] unable to nsecify: failed to "
-                "commit the NSEC RRset", denial_str);
-            return status;
-        }
-
+        rrset_diff(denial->rrset, NULL);
         /* ok */
         denial->bitmap_changed = 0;
         denial->nxt_changed = 0;
@@ -391,13 +371,6 @@
             return ODS_STATUS_ERR;
         }
         ods_log_assert(nsec_rr);
-        /* delete old NSEC RR(s) */
-        status = rrset_wipe_out(denial->rrset);
-        if (status != ODS_STATUS_OK) {
-            ods_log_alert("[%s] unable to nsecify3: failed to "
-                "wipe out NSEC3 RRset", denial_str);
-            return status;
-        }
        /* add the new one */
         if (!rrset_add_rr(denial->rrset, nsec_rr)) {
             ods_log_alert("[%s] unable to nsecify3: failed to "
@@ -405,12 +378,7 @@
             return ODS_STATUS_ERR;
         }
         /* commit */
-        status = rrset_commit(denial->rrset);
-        if (status != ODS_STATUS_OK) {
-            ods_log_alert("[%s] unable to nsecify3: failed to "
-                "commit the NSEC3 RRset", denial_str);
-            return status;
-        }
+        rrset_diff(denial->rrset, NULL);
         /* ok */
         denial->bitmap_changed = 0;
         denial->nxt_changed = 0;

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/denial.h
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/denial.h	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/denial.h	2011-08-25 13:30:17 UTC (rev 5482)
@@ -51,8 +51,8 @@
     void* domain;
     ldns_rdf* dname;
     rrset_type* rrset;
-    uint8_t bitmap_changed;
-    uint8_t nxt_changed;
+    unsigned bitmap_changed : 1;
+    unsigned nxt_changed : 1;
 };
 
 /**

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/domain.c
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/domain.c	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/domain.c	2011-08-25 13:30:17 UTC (rev 5482)
@@ -40,7 +40,6 @@
 #include "signer/backup.h"
 #include "signer/denial.h"
 #include "signer/domain.h"
-#include "signer/rrset.h"
 #include "signer/zone.h"
 
 #include <ldns/ldns.h>
@@ -90,19 +89,6 @@
 
 
 /**
- * Compare RRsets.
- *
- */
-static int
-rrset_compare(const void* a, const void* b)
-{
-    ldns_rr_type* x = (ldns_rr_type*)a;
-    ldns_rr_type* y = (ldns_rr_type*)b;
-    return (*x)-(*y);
-}
-
-
-/**
  * Create domain.
  *
  */
@@ -131,14 +117,36 @@
     }
     domain->zone = zoneptr;
     domain->denial = NULL; /* no reference yet */
-    domain->dstatus = DOMAIN_STATUS_NONE;
+    domain->rrsets = NULL;
     domain->parent = NULL;
-    domain->rrsets = ldns_rbtree_create(rrset_compare);
+    domain->dstatus = DOMAIN_STATUS_NONE;
     return domain;
 }
 
 
 /**
+ * Count the number of RRsets at this domain.
+ *
+ */
+size_t
+domain_count_rrset(domain_type* domain)
+{
+    rrset_type* rrset = NULL;
+    size_t count = 0;
+
+    if (!domain) {
+        return 0;
+    }
+    rrset = domain->rrsets;
+    while (rrset) {
+        count++; /* rr_count may be zero */
+        rrset = rrset->next;
+    }
+    return count;
+}
+
+
+/**
  * Recover domain from backup.
  *
  */
@@ -232,11 +240,7 @@
                 ldns_rr_free(rr);
                 goto recover_dname_error;
             }
-            /* commit */
-            if (rrset_commit(denial->rrset) != ODS_STATUS_OK) {
-                ods_log_error("[%s] unable to recover denial", dname_str);
-                goto recover_dname_error;
-            }
+            rrset_diff(denial->rrset, NULL);
             /* denial done */
             rr = NULL;
 
@@ -308,53 +312,21 @@
 
 
 /**
- * Convert RRset to a tree node.
- *
- */
-static ldns_rbnode_t*
-rrset2node(rrset_type* rrset)
-{
-    ldns_rbnode_t* node = (ldns_rbnode_t*) malloc(sizeof(ldns_rbnode_t));
-    if (!node) {
-        return NULL;
-    }
-    node->key = (const void*) &(rrset->rrtype);
-    node->data = rrset;
-    return node;
-}
-
-
-/**
- * Internal lookup RRset function.
- *
- */
-static rrset_type*
-domain_rrset_search(ldns_rbtree_t* tree, ldns_rr_type rrtype)
-{
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
-
-    if (!tree || !rrtype) {
-        return NULL;
-    }
-    node = ldns_rbtree_search(tree, (const void*) &rrtype);
-    if (node && node != LDNS_RBTREE_NULL) {
-        return (rrset_type*) node->data;
-    }
-    return NULL;
-}
-
-
-/**
  * Look up RRset at this domain.
  *
  */
 rrset_type*
 domain_lookup_rrset(domain_type* domain, ldns_rr_type rrtype)
 {
-    if (!domain || !rrtype) {
+    rrset_type* rrset = NULL;
+    if (!domain || !domain->rrsets || !rrtype) {
         return NULL;
     }
-    return domain_rrset_search(domain->rrsets, rrtype);
+    rrset = domain->rrsets;
+    while (rrset && rrset->rrtype != rrtype) {
+        rrset = rrset->next;
+    }
+    return rrset;
 }
 
 
@@ -365,26 +337,24 @@
 rrset_type*
 domain_add_rrset(domain_type* domain, rrset_type* rrset)
 {
-    ldns_rbnode_t* new_node = LDNS_RBTREE_NULL;
-
-    if (!rrset) {
-        ods_log_error("[%s] unable to add RRset: no RRset", dname_str);
-        return NULL;
-    }
+    rrset_type** p = NULL;
+    denial_type* denial = NULL;
+    ods_log_assert(domain);
     ods_log_assert(rrset);
-
-    if (!domain || !domain->rrsets) {
-        ods_log_error("[%s] unable to add RRset: no storage", dname_str);
-        return NULL;
+    if (!domain->rrsets) {
+        domain->rrsets = rrset;
+    } else {
+        p = &domain->rrsets;
+        while(*p) {
+            p = &((*p)->next);
+        }
+        *p = rrset;
+        rrset->next = NULL;
     }
-    ods_log_assert(domain);
-    ods_log_assert(domain->rrsets);
-
-    new_node = rrset2node(rrset);
-    if (ldns_rbtree_insert(domain->rrsets, new_node) == NULL) {
-        ods_log_error("[%s] unable to add RRset: already present", dname_str);
-        free((void*)new_node);
-        return NULL;
+    log_rrset(domain->dname, rrset->rrtype, "+RRSET", LOG_DEBUG);
+    if (domain->denial) {
+        denial = (denial_type*) domain->denial;
+        denial->bitmap_changed = 1;
     }
     return rrset;
 }
@@ -395,93 +365,173 @@
  *
  */
 rrset_type*
-domain_del_rrset(domain_type* domain, rrset_type* rrset)
+domain_del_rrset(domain_type* domain, ldns_rr_type rrtype)
 {
-    ldns_rbnode_t* del_node = LDNS_RBTREE_NULL;
-    rrset_type* del_rrset = NULL;
-
-    if (!rrset) {
-        ods_log_error("[%s] unable to delete RRset: no RRset", dname_str);
+    rrset_type* cur = NULL;
+    denial_type* denial = NULL;
+    if (!domain || !rrtype) {
         return NULL;
     }
-    ods_log_assert(rrset);
-
-    if (!domain || !domain->rrsets) {
-        ods_log_error("[%s] unable to delete RRset: no storage", dname_str);
-        return rrset;
-    }
-    ods_log_assert(domain);
-    ods_log_assert(domain->rrsets);
-
-    del_node = ldns_rbtree_search(domain->rrsets,
-        (const void*) &(rrset->rrtype));
-    if (del_node) {
-        del_node = ldns_rbtree_delete(domain->rrsets,
-            (const void*) &(rrset->rrtype));
-        del_rrset = (rrset_type*) del_node->data;
-        rrset_cleanup(del_rrset);
-        free((void*)del_node);
+    if (!domain->rrsets) {
+        ods_log_error("[%s] unable to delete RRset: RRset with RRtype %s "
+            "does not exist", dname_str, rrset_type2str(rrtype));
         return NULL;
     }
-    return rrset;
+    if (domain->rrsets->rrtype == rrtype) {
+        cur = domain->rrsets;
+        domain->rrsets = cur->next;
+        cur->domain = NULL;
+        cur->next = NULL;
+        log_rrset(domain->dname, rrtype, "-RRSET", LOG_DEBUG);
+        if (domain->denial) {
+            denial = (denial_type*) domain->denial;
+            denial->bitmap_changed = 1;
+        }
+        return cur;
+    }
+    cur = domain->rrsets;
+    while (cur) {
+        if (!cur->next) {
+            ods_log_error("[%s] unable to delete RRset: RRset with RRtype %s "
+                "does not exist", dname_str, rrset_type2str(rrtype));
+            return NULL;
+        }
+        ods_log_assert(cur->next);
+        if (cur->next->rrtype != rrtype) {
+            cur = cur->next;
+        } else {
+            ods_log_assert(cur->next->rrtype == rrtype);
+            cur->next = cur->next->next;
+            cur = cur->next;
+            cur->domain = NULL;
+            cur->next = NULL;
+            log_rrset(domain->dname, rrtype, "-RRSET", LOG_DEBUG);
+            if (domain->denial) {
+                denial = (denial_type*) domain->denial;
+                denial->bitmap_changed = 1;
+            }
+            return cur;
+        }
+    }
+    ods_log_error("[%s] unable to delete RRset: RRset with RRtype %s "
+        "does not exist", dname_str, rrset_type2str(rrtype));
+    return NULL;
 }
 
 
 /**
- * Count the number of RRsets at this domain.
+ * Apply differences at domain.
  *
  */
-size_t
-domain_count_rrset(domain_type* domain)
+void
+domain_diff(domain_type* domain, keylist_type* kl)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
+    denial_type* denial = NULL;
     rrset_type* rrset = NULL;
-    size_t count = 0;
+    rrset_type* prev_rrset = NULL;
 
-    if (!domain || !domain->rrsets) {
-        return 0;
+    if (!domain) {
+        return;
     }
-
-    if (domain->rrsets->root != LDNS_RBTREE_NULL) {
-        node = ldns_rbtree_first(domain->rrsets);
-    }
-    while (node && node != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) node->data;
-        if (rrset_count_rr(rrset, COUNT_RR) > 0) {
-            count++;
+    rrset = domain->rrsets;
+    while (rrset) {
+        /* special cases */
+        if (rrset->rrtype == LDNS_RR_TYPE_NSEC3PARAMS) {
+            rrset = rrset->next;
+            continue;
         }
-        node = ldns_rbtree_next(node);
+        /* normal cases */
+        rrset_diff(rrset, kl);
+        if (rrset->rr_count <= 0) {
+            /* delete entire rrset */
+            if (!prev_rrset) {
+                domain->rrsets = rrset->next;
+            } else {
+                prev_rrset->next = rrset->next;
+            }
+            rrset->next = NULL;
+            log_rrset(domain->dname, rrset->rrtype, "-RRSET", LOG_DEBUG);
+            rrset_cleanup(rrset);
+            if (!prev_rrset) {
+                rrset = domain->rrsets;
+            } else {
+                rrset = prev_rrset->next;
+            }
+            if (domain->denial) {
+                denial = (denial_type*) domain->denial;
+                denial->bitmap_changed = 1;
+            }
+        } else {
+            /* just go to next rrset */
+            prev_rrset = rrset;
+            rrset = rrset->next;
+        }
     }
-    return count;
+    return;
 }
 
 
 /**
- * Apply differences at domain.
+ * Rollback differences at domain.
  *
  */
 void
-domain_diff(domain_type* domain, keylist_type* kl)
+domain_rollback(domain_type* domain)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
+    denial_type* denial = NULL;
     rrset_type* rrset = NULL;
+    rrset_type* prev_rrset = NULL;
+    ldns_rr* del_rr = NULL;
+    int del_rrset = 0;
+    uint16_t i = 0;
 
-    if (!domain || !domain->rrsets) {
+    if (!domain) {
         return;
     }
-    if (domain->rrsets->root != LDNS_RBTREE_NULL) {
-        node = ldns_rbtree_first(domain->rrsets);
-    }
-    while (node && node != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) node->data;
-        /* special cases */
-        if (rrset->rrtype == LDNS_RR_TYPE_NSEC3PARAMS) {
-            node = ldns_rbtree_next(node);
-            continue;
+    rrset = domain->rrsets;
+    while (rrset) {
+        /* walk rrs */
+        for (i=0; i < rrset->rr_count; i++) {
+            rrset->rrs[i].is_added = 0;
+            rrset->rrs[i].is_removed = 0;
+            if (!rrset->rrs[i].exists) {
+                /* can we delete the RRset? */
+                if(rrset->rr_count == 1) {
+                    del_rrset = 1;
+                }
+                del_rr = rrset->rrs[i].rr;
+                rrset_del_rr(rrset, i);
+                ldns_rr_free(del_rr);
+                del_rr = NULL;
+                i--;
+            }
         }
-        /* normal cases */
-        rrset_diff(rrset, kl);
-        node = ldns_rbtree_next(node);
+        /* next rrset */
+        if (del_rrset) {
+            /* delete entire rrset */
+            if (!prev_rrset) {
+                domain->rrsets = rrset->next;
+            } else {
+                prev_rrset->next = rrset->next;
+            }
+            rrset->next = NULL;
+            log_rrset(domain->dname, rrset->rrtype, "-RRSET", LOG_DEBUG);
+            rrset_cleanup(rrset);
+            if (!prev_rrset) {
+                rrset = domain->rrsets;
+            } else {
+                rrset = prev_rrset->next;
+            }
+            if (domain->denial) {
+                denial = (denial_type*) domain->denial;
+                denial->bitmap_changed = 0;
+            }
+            del_rrset = 0;
+        } else {
+            /* just go to next rrset */
+            prev_rrset = rrset;
+            rrset = rrset->next;
+        }
     }
     return;
 }
@@ -495,20 +545,20 @@
 domain_examine_data_exists(domain_type* domain, ldns_rr_type rrtype,
     int skip_glue)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
     rrset_type* rrset = NULL;
+    uint16_t i = 0;
 
     if (!domain) {
         return 0;
     }
-    ods_log_assert(domain);
-
-    if (domain->rrsets->root != LDNS_RBTREE_NULL) {
-        node = ldns_rbtree_first(domain->rrsets);
-    }
-    while (node && node != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) node->data;
-        if (rrset_count_RR(rrset) > 0) {
+    rrset = domain->rrsets;
+    while (rrset) {
+        /* walk rrs */
+        for (i=0; i < rrset->rr_count; i++) {
+            if (!rrset->rrs[i].exists) {
+                rrset = rrset->next;
+                continue;
+            }
             if (rrtype) {
                 /* looking for a specific RRset */
                 if (rrset->rrtype == rrtype) {
@@ -521,7 +571,6 @@
                 return 1;
             }
         }
-        node = ldns_rbtree_next(node);
     }
     return 0;
 }
@@ -534,58 +583,29 @@
 int
 domain_examine_rrset_is_alone(domain_type* domain, ldns_rr_type rrtype)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
     rrset_type* rrset = NULL;
-    ldns_dnssec_rrs* rrs = NULL;
-    char* str_name = NULL;
-    char* str_type = NULL;
     size_t count = 0;
 
     if (!domain || !rrtype) {
         return 1;
     }
-    ods_log_assert(domain);
-    ods_log_assert(rrtype);
-
     rrset = domain_lookup_rrset(domain, rrtype);
     if (rrset) {
-        count = rrset_count_RR(rrset);
+        count = rrset->rr_count;
     }
     if (count) {
         if (domain_count_rrset(domain) < 2) {
             /* one or zero, that's ok */
             return 1;
         }
-        /* make sure all other RRsets become empty */
-        if (domain->rrsets->root != LDNS_RBTREE_NULL) {
-            node = ldns_rbtree_first(domain->rrsets);
-        }
-        while (node && node != LDNS_RBTREE_NULL) {
-            rrset = (rrset_type*) node->data;
-            if (rrset->rrtype != rrtype && rrset_count_RR(rrset) > 0) {
+        rrset = domain->rrsets;
+        while (rrset) {
+            if (rrset->rrtype != rrtype && rrset->rr_count > 0) {
                 /* found other data next to rrtype */
-                str_name = ldns_rdf2str(domain->dname);
-                str_type = ldns_rr_type2str(rrtype);
-                ods_log_error("[%s] other data next to %s %s", dname_str, str_name, str_type);
-                rrs = rrset->rrs;
-                while (rrs) {
-                    if (rrs->rr) {
-                        log_rr(rrs->rr, "next-to-CNAME: ", LOG_ERR);
-                    }
-                    rrs = rrs->next;
-                }
-                rrs = rrset->add;
-                while (rrs) {
-                    if (rrs->rr) {
-                        log_rr(rrs->rr, "next-to-CNAME: ", LOG_ERR);
-                    }
-                    rrs = rrs->next;
-                }
-                free((void*)str_name);
-                free((void*)str_type);
+                log_dname(domain->dname, "other data next to RRset", LOG_ERR);
                 return 0;
             }
-            node = ldns_rbtree_next(node);
+            rrset = rrset->next;;
         }
     }
     return 1;
@@ -599,32 +619,25 @@
 int
 domain_examine_valid_zonecut(domain_type* domain)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
     rrset_type* rrset = NULL;
     size_t count = 0;
 
     if (!domain) {
         return 1;
     }
-    ods_log_assert(domain);
-
     rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_NS);
     if (rrset) {
-        count = rrset_count_RR(rrset);
+        count = rrset->rr_count;
     }
-
     if (count) {
         /* make sure all other RRsets become empty (except DS, glue) */
-        if (domain->rrsets->root != LDNS_RBTREE_NULL) {
-            node = ldns_rbtree_first(domain->rrsets);
-        }
-        while (node && node != LDNS_RBTREE_NULL) {
-            rrset = (rrset_type*) node->data;
+        rrset = domain->rrsets;
+        while (rrset) {
             if (rrset->rrtype != LDNS_RR_TYPE_DS &&
                 rrset->rrtype != LDNS_RR_TYPE_NS &&
                 rrset->rrtype != LDNS_RR_TYPE_A &&
                 rrset->rrtype != LDNS_RR_TYPE_AAAA &&
-                rrset_count_RR(rrset) > 0) {
+                rrset->rr_count > 0) {
                 /* found occluded data next to delegation */
                 ods_log_error("[%s] occluded glue data at zonecut, RRtype=%u",
                     dname_str, rrset->rrtype);
@@ -633,15 +646,15 @@
                 rrset->rrtype == LDNS_RR_TYPE_AAAA) {
                 /* check if glue is allowed at the delegation */
 /* TODO: allow for now (root zone has it)
-                if (rrset_count_RR(rrset) > 0 &&
+                if (rrset->rr_count > 0 &&
                     !domain_examine_ns_rdata(domain, domain->dname)) {
                     ods_log_error("[%s] occluded glue data at zonecut, #RR=%u",
-                        dname_str, rrset_count_RR(rrset));
+                        dname_str, rrset->rr_count);
                     return 0;
                 }
 */
             }
-            node = ldns_rbtree_next(node);
+            rrset = rrset->next;
         }
     }
     return 0;
@@ -656,29 +669,19 @@
 domain_examine_rrset_is_singleton(domain_type* domain, ldns_rr_type rrtype)
 {
     rrset_type* rrset = NULL;
-    char* str_name = NULL;
-    char* str_type = NULL;
     size_t count = 0;
 
     if (!domain || !rrtype) {
         return 1;
     }
-    ods_log_assert(domain);
-    ods_log_assert(rrtype);
-
     rrset = domain_lookup_rrset(domain, rrtype);
     if (rrset) {
-        count = rrset_count_RR(rrset);
+        count = rrset->rr_count;
     }
-
     if (count > 1) {
         /* multiple RRs in the RRset for singleton RRtype*/
-        str_name = ldns_rdf2str(domain->dname);
-        str_type = ldns_rr_type2str(rrtype);
-        ods_log_error("[%s] multiple records for singleton type at %s %s",
-            dname_str, str_name, str_type);
-        free((void*)str_name);
-        free((void*)str_type);
+        log_dname(domain->dname, "multiple records for singleton type",
+            LOG_ERR);
         return 0;
     }
     return 1;
@@ -686,89 +689,6 @@
 
 
 /**
- * Commit updates to domain.
- *
- */
-ods_status
-domain_commit(domain_type* domain)
-{
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
-    rrset_type* rrset = NULL;
-    denial_type* denial = NULL;
-    ods_status status = ODS_STATUS_OK;
-    size_t numadd = 0;
-    size_t numdel = 0;
-    size_t numrrs = 0;
-    size_t numnew = 0;
-
-    if (!domain || !domain->rrsets) {
-        return ODS_STATUS_OK;
-    }
-    if (domain->rrsets->root != LDNS_RBTREE_NULL) {
-        node = ldns_rbtree_first(domain->rrsets);
-    }
-    denial = (denial_type*) domain->denial;
-    while (node && node != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) node->data;
-        numrrs = rrset_count_rr(rrset, COUNT_RR);
-        numadd = rrset_count_rr(rrset, COUNT_ADD);
-        numdel = rrset_count_rr(rrset, COUNT_DEL);
-
-        if (rrset->rrtype == LDNS_RR_TYPE_SOA && rrset->rrs &&
-            rrset->rrs->rr) {
-            rrset->needs_signing = 1;
-        }
-        status = rrset_commit(rrset);
-        if (status != ODS_STATUS_OK) {
-            return status;
-        }
-        node = ldns_rbtree_next(node);
-        numnew = rrset_count_rr(rrset, COUNT_RR);
-        if (numrrs > 0 && numnew <= 0) {
-            if (domain_del_rrset(domain, rrset) != NULL) {
-                ods_log_warning("[%s] unable to commit: failed ",
-                    "to delete RRset", dname_str);
-                return ODS_STATUS_UNCHANGED;
-            }
-            if (denial) {
-                denial->bitmap_changed = 1;
-            }
-        } else if (numrrs <= 0 && numnew == numadd) {
-            if (denial) {
-                denial->bitmap_changed = 1;
-            }
-        }
-    }
-    return status;
-}
-
-
-/**
- * Rollback updates from domain.
- *
- */
-void
-domain_rollback(domain_type* domain)
-{
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
-    rrset_type* rrset = NULL;
-
-    if (!domain || !domain->rrsets) {
-        return;
-    }
-    if (domain->rrsets->root != LDNS_RBTREE_NULL) {
-        node = ldns_rbtree_first(domain->rrsets);
-    }
-    while (node && node != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) node->data;
-        rrset_rollback(rrset);
-        node = ldns_rbtree_next(node);
-    }
-    return;
-}
-
-
-/**
  * Set domain status.
  *
  */
@@ -820,7 +740,6 @@
 ods_status
 domain_queue(domain_type* domain, fifoq_type* q, worker_type* worker)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
     rrset_type* rrset = NULL;
     denial_type* denial = NULL;
     ods_status status = ODS_STATUS_OK;
@@ -834,16 +753,12 @@
     }
 
     denial = (denial_type*) domain->denial;
-    if (domain->rrsets->root != LDNS_RBTREE_NULL) {
-        node = ldns_rbtree_first(domain->rrsets);
-    }
-    while (node && node != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) node->data;
-
+    rrset = domain->rrsets;
+    while (rrset) {
         /* skip delegation RRsets */
         if (domain->dstatus != DOMAIN_STATUS_APEX &&
             rrset->rrtype == LDNS_RR_TYPE_NS) {
-            node = ldns_rbtree_next(node);
+            rrset = rrset->next;
             continue;
         }
         /* skip glue at the delegation */
@@ -851,7 +766,7 @@
              domain->dstatus == DOMAIN_STATUS_NS) &&
             (rrset->rrtype == LDNS_RR_TYPE_A ||
              rrset->rrtype == LDNS_RR_TYPE_AAAA)) {
-            node = ldns_rbtree_next(node);
+            rrset = rrset->next;
             continue;
         }
         /* queue RRset for signing */
@@ -859,9 +774,8 @@
         if (status != ODS_STATUS_OK) {
             return status;
         }
-        node = ldns_rbtree_next(node);
+        rrset = rrset->next;
     }
-
     /* queue NSEC(3) RRset for signing */
     if (denial && denial->rrset) {
         status = rrset_queue(denial->rrset, q, worker);
@@ -878,7 +792,6 @@
 domain_examine_ns_rdata(domain_type* domain, ldns_rdf* nsdname)
 {
     rrset_type* rrset = NULL;
-
     if (!domain || !nsdname) {
        return 0;
     }
@@ -899,7 +812,6 @@
 void
 domain_print(FILE* fd, domain_type* domain)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
     int print_glue = 0;
     rrset_type* rrset = NULL;
     rrset_type* soa_rrset = NULL;
@@ -909,12 +821,7 @@
     if (!domain || !fd) {
         return;
     }
-    ods_log_assert(fd);
-    ods_log_assert(domain);
-
-    if (domain->rrsets) {
-        node = ldns_rbtree_first(domain->rrsets);
-    }
+    rrset = domain->rrsets;
     /* no other data may accompany a CNAME */
     cname_rrset = domain_lookup_rrset(domain, LDNS_RR_TYPE_CNAME);
     if (cname_rrset) {
@@ -928,8 +835,7 @@
             }
         }
         /* print other RRsets */
-        while (node && node != LDNS_RBTREE_NULL) {
-            rrset = (rrset_type*) node->data;
+        while (rrset) {
             /* skip SOA RRset */
             if (rrset->rrtype != LDNS_RR_TYPE_SOA) {
                 if (domain->dstatus == DOMAIN_STATUS_OCCLUDED) {
@@ -953,7 +859,7 @@
                     rrset_print(fd, rrset, 0);
                 }
             }
-            node = ldns_rbtree_next(node);
+            rrset = rrset->next;
         }
     }
     /* denial of existence */
@@ -966,27 +872,6 @@
 
 
 /**
- * Clean up RRsets at the domain.
- *
- */
-static void
-rrset_delfunc(ldns_rbnode_t* elem)
-{
-    rrset_type* rrset;
-
-    if (elem && elem != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) elem->data;
-        rrset_delfunc(elem->left);
-        rrset_delfunc(elem->right);
-
-        rrset_cleanup(rrset);
-        free(elem);
-    }
-    return;
-}
-
-
-/**
  * Clean up domain.
  *
  */
@@ -999,11 +884,7 @@
     }
     zone = (zone_type*) domain->zone;
     ldns_rdf_deep_free(domain->dname);
-    if (domain->rrsets) {
-        rrset_delfunc(domain->rrsets->root);
-        ldns_rbtree_free(domain->rrsets);
-        domain->rrsets = NULL;
-    }
+    rrset_cleanup(domain->rrsets);
     allocator_deallocate(zone->allocator, (void*)domain);
     return;
 }
@@ -1016,28 +897,20 @@
 void
 domain_backup(FILE* fd, domain_type* domain)
 {
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
     char* str = NULL;
     rrset_type* rrset = NULL;
     denial_type* denial = NULL;
-
     if (!domain || !fd) {
         return;
     }
-
     str = ldns_rdf2str(domain->dname);
-    if (domain->rrsets) {
-        node = ldns_rbtree_first(domain->rrsets);
-    }
-
     fprintf(fd, ";;Domain: name %s status %i\n", str, (int) domain->dstatus);
-    while (node && node != LDNS_RBTREE_NULL) {
-        rrset = (rrset_type*) node->data;
+    rrset = domain->rrsets;
+    while (rrset) {
         rrset_backup(fd, rrset);
-        node = ldns_rbtree_next(node);
+        rrset = rrset->next;;
     }
     free((void*)str);
-
     /* denial of existence */
     denial = (denial_type*) domain->denial;
     if (denial) {
@@ -1045,7 +918,6 @@
         rrset_print(fd, denial->rrset, 1);
         rrset_backup(fd, denial->rrset);
     }
-
     fprintf(fd, ";;Domaindone\n");
     return;
 }

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/domain.h
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/domain.h	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/domain.h	2011-08-25 13:30:17 UTC (rev 5482)
@@ -74,7 +74,7 @@
     ldns_rdf* dname;
     domain_status dstatus;
     domain_type* parent;
-    ldns_rbtree_t* rrsets;
+    rrset_type* rrsets;
 };
 
 /**
@@ -161,11 +161,11 @@
 /**
  * Delete RRset from domain.
  * \param[in] domain domain
- * \param[in] rrset RRset
- * \return rrset_type* RRset if failed
+ * \param[in] rrtype RRtype of RRset
+ * \return rrset_type* deleted RRset
  *
  */
-rrset_type* domain_del_rrset(domain_type* domain, rrset_type* rrset);
+rrset_type* domain_del_rrset(domain_type* domain, ldns_rr_type rrtype);
 
 /**
  * Apply differences at domain.
@@ -222,14 +222,6 @@
 int domain_examine_rrset_is_singleton(domain_type* domain, ldns_rr_type rrtype);
 
 /**
- * Commit updates to domain.
- * \param[in] domain the domain
- * \return ods_status status
- *
- */
-ods_status domain_commit(domain_type* domain);
-
-/**
  * Rollback updates from domain.
  * \param[in] domain the domain
  *

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/namedb.c
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/namedb.c	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/namedb.c	2011-08-25 13:30:17 UTC (rev 5482)
@@ -669,18 +669,7 @@
 
         /* delete old NSEC RR(s) */
         if (denial->rrset) {
-            status = rrset_wipe_out(denial->rrset);
-            if (status != ODS_STATUS_OK) {
-                ods_log_alert("[%s] unable to del denial of existence data "
-                    "point: failed to wipe out NSEC RRset", db_str);
-                return denial;
-            }
-            status = rrset_commit(denial->rrset);
-            if (status != ODS_STATUS_OK) {
-                ods_log_alert("[%s] unable to del denial of existence data "
-                    "point: failed to commit NSEC RRset", db_str);
-                return denial;
-            }
+            rrset_diff(denial->rrset, NULL);
         }
 
         del_node = ldns_rbtree_delete(tree, (const void*)denial->dname);
@@ -748,60 +737,6 @@
 
 
 /**
- * Commit updates to zone data.
- *
- */
-ods_status
-namedb_commit(namedb_type* db)
-{
-    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
-    ldns_rbnode_t* nxtnode = LDNS_RBTREE_NULL;
-    ldns_rbnode_t* tmpnode = LDNS_RBTREE_NULL;
-    domain_type* domain = NULL;
-    domain_type* nxtdomain = NULL;
-    ods_status status = ODS_STATUS_OK;
-    size_t oldnum = 0;
-
-    if (!db || !db->domains) {
-        return ODS_STATUS_OK;
-    }
-    if (db->domains->root != LDNS_RBTREE_NULL) {
-        node = ldns_rbtree_last(db->domains);
-    }
-    while (node && node != LDNS_RBTREE_NULL) {
-        domain = (domain_type*) node->data;
-        oldnum = domain_count_rrset(domain);
-        status = domain_commit(domain);
-        if (status != ODS_STATUS_OK) {
-            return status;
-        }
-        tmpnode = node;
-        node = ldns_rbtree_previous(node);
-
-        /* delete memory if empty leaf domain */
-        if (domain_count_rrset(domain) <= 0) {
-            /* empty domain */
-            nxtnode = ldns_rbtree_next(tmpnode);
-            nxtdomain = NULL;
-            if (nxtnode && nxtnode != LDNS_RBTREE_NULL) {
-                nxtdomain = (domain_type*) nxtnode->data;
-            }
-            if (!nxtdomain ||
-                !ldns_dname_is_subdomain(nxtdomain->dname, domain->dname)) {
-                /* leaf domain */
-                if (namedb_del_domain(db, domain) != NULL) {
-                    ods_log_warning("[%s] unable to delete obsoleted "
-                        "domain", db_str);
-                    return ODS_STATUS_ERR;
-                }
-            }
-        } /* if (domain_count_rrset(domain) <= 0) */
-    }
-    return status;
-}
-
-
-/**
  * Rollback updates from zone data.
  *
  */

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/namedb.h
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/namedb.h	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/namedb.h	2011-08-25 13:30:17 UTC (rev 5482)
@@ -178,14 +178,6 @@
 void namedb_diff(namedb_type* db, keylist_type* kl);
 
 /**
- * Commit updates to zone data.
- * \param[in] zd zone data
- * \return ods_status status
- *
- */
-ods_status namedb_commit(namedb_type* zd);
-
-/**
  * Rollback differences in db.
  * \param[in] db namedb
  *

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/rrset.c
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/rrset.c	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/rrset.c	2011-08-25 13:30:17 UTC (rev 5482)
@@ -193,17 +193,15 @@
             "failed", rrset_str, (unsigned) type);
         return NULL;
     }
+    rrset->next = NULL;
+    rrset->rrs = NULL;
+    rrset->rrsigs = NULL;
+    rrset->domain = NULL;
     rrset->zone = zoneptr;
     rrset->rrtype = type;
     rrset->rr_count = 0;
-    rrset->add_count = 0;
-    rrset->del_count = 0;
     rrset->rrsig_count = 0;
     rrset->needs_signing = 0;
-    rrset->rrs = ldns_dnssec_rrs_new();
-    rrset->add = NULL;
-    rrset->del = NULL;
-    rrset->rrsigs = NULL;
     return rrset;
 }
 
@@ -216,54 +214,48 @@
 rrset_recover(rrset_type* rrset, ldns_rr* rrsig, const char* locator,
     uint32_t flags)
 {
-    ods_status status = ODS_STATUS_OK;
-
+    rrsig_type* sig = NULL;
     ods_log_assert(rrset);
     ods_log_assert(rrsig);
     ods_log_assert(locator);
     ods_log_assert(flags);
-
-    if (!rrset->rrsigs) {
-        rrset->rrsigs = rrsigs_create();
-    }
-
-    status = rrsigs_add_sig(rrset->rrsigs, rrsig, locator, flags);
-    if (status != ODS_STATUS_OK) {
+    sig = rrset_add_rrsig(rrset, rrsig, locator, flags);
+    if (!sig) {
         ods_log_error("[%s] unable to recover RRSIG", rrset_str);
         log_rr(rrsig, "+RRSIG", LOG_ERR);
-    } else {
-        rrset->rrsig_count += 1;
-        /**
-         * This RRset was recovered, no need for signing.
-         * If the signature is about to expire, the recycle logic will
-         * catch that.
-         */
-        rrset->needs_signing = 0;
+        return ODS_STATUS_ERR;
     }
-    return status;
+    rrset->needs_signing = 0;
+    return ODS_STATUS_OK;
 }
 
 
 /**
- * Examine NS RRs and verify its RDATA.
+ * Lookup RR in RRset.
  *
  */
-static int
-rrs_examine_ns_rdata(ldns_dnssec_rrs* rrs, ldns_rdf* nsdname)
+rr_type*
+rrset_lookup_rr(rrset_type* rrset, ldns_rr* rr)
 {
-    ldns_dnssec_rrs* walk = NULL;
-    if (!rrs || !nsdname) {
-        return 0;
+    ldns_status lstatus = LDNS_STATUS_OK;
+    int cmp = 0;
+    size_t i = 0;
+
+    if (!rrset || !rr || rrset->rr_count <= 0) {
+       return NULL;
     }
-    walk = rrs;
-    while (walk) {
-        if (walk->rr &&
-            ldns_dname_compare(ldns_rr_rdf(walk->rr, 0), nsdname) == 0) {
-            return 1;
+    for (i=0; i < rrset->rr_count; i++) {
+        lstatus = util_dnssec_rrs_compare(rrset->rrs[i].rr, rr, &cmp);
+        if (lstatus != LDNS_STATUS_OK) {
+            ods_log_error("[%s] unable to lookup RR: compare failed (%s)",
+                rrset_str, ldns_get_errorstr_by_id(lstatus));
+            return NULL;
         }
-        walk = walk->next;
+        if (!cmp) { /* equal */
+            return &rrset->rrs[i];
+        }
     }
-    return 0;
+    return NULL;
 }
 
 
@@ -274,51 +266,29 @@
 int
 rrset_examine_ns_rdata(rrset_type* rrset, ldns_rdf* nsdname)
 {
+    uint16_t i = 0;
     if (!rrset || !nsdname || rrset->rrtype != LDNS_RR_TYPE_NS) {
         return 0;
     }
-    if (rrs_examine_ns_rdata(rrset->add, nsdname)) {
-        return 1;
+    for (i=0; i < rrset->rr_count; i++) {
+        if (ldns_dname_compare(ldns_rr_rdf(rrset->rrs[i].rr, 0), nsdname) == 0) {
+            return 1;
+        }
     }
-    if (rrs_examine_ns_rdata(rrset->del, nsdname)) {
-        return 0;
-    }
-    return rrs_examine_ns_rdata(rrset->rrs, nsdname);
+    return 0;
 }
 
 
 /**
- * Return the number of RRs in RRset after an update.
- *
- */
-size_t
-rrset_count_RR(rrset_type* rrset)
-{
-    ods_log_assert(rrset);
-    return ((rrset->rr_count + rrset->add_count) - rrset->del_count);
-}
-
-
-/**
  * Count the number of RRs in this RRset.
  *
  */
 size_t
-rrset_count_rr(rrset_type* rrset, int which)
+rrset_count_rr(rrset_type* rrset)
 {
     if (!rrset) {
         return 0;
     }
-    switch (which) {
-        case COUNT_ADD:
-            return rrset->add_count;
-        case COUNT_DEL:
-            return rrset->del_count;
-        case COUNT_RR:
-        default:
-            return rrset->rr_count;
-    }
-    /* not reached */
     return rrset->rr_count;
 }
 
@@ -330,56 +300,34 @@
 ldns_rr*
 rrset_add_rr(rrset_type* rrset, ldns_rr* rr)
 {
-    ldns_status status = LDNS_STATUS_OK;
+    rr_type* rrs_old = NULL;
+    zone_type* zone = NULL;
 
-    if (!rr) {
-        ods_log_error("[%s] unable to add RR: no RR", rrset_str);
-        return NULL;
-    }
+    ods_log_assert(rrset);
     ods_log_assert(rr);
+    ods_log_assert(rrset->rrtype == ldns_rr_get_type(rr));
 
-    if (!rrset) {
-        ods_log_error("[%s] unable to add RR: no storage", rrset_str);
-        return NULL;
+    zone = (zone_type*) rrset->zone;
+    rrs_old = rrset->rrs;
+    rrset->rrs = (rr_type*) allocator_alloc(zone->allocator,
+        (rrset->rr_count + 1) * sizeof(rr_type));
+    if (!rrset->rrs) {
+        ods_log_error("[%s] unable to add RR: allocator_alloc() failed",
+            rrset_str);
+        exit(1);
     }
-    ods_log_assert(rrset);
-
-    if (rrset->rrtype != ldns_rr_get_type(rr)) {
-        ods_log_error("[%s] unable to add RR: RRtype mismatch", rrset_str);
-        return NULL;
+    if (rrs_old) {
+        memcpy(rrset->rrs, rrs_old, (rrset->rr_count) * sizeof(rr_type));
     }
-
-    if (!rrset->add) {
-        rrset->add = ldns_dnssec_rrs_new();
-    }
-
-    if (!rrset->add->rr) {
-        rrset->add->rr = rr;
-        rrset->add_count = 1;
-        log_rr(rr, "+rr", LOG_DEEEBUG);
-    } else {
-        status = util_dnssec_rrs_add_rr(rrset->add, rr);
-        if (status != LDNS_STATUS_OK) {
-            if (status == LDNS_STATUS_NO_DATA) {
-                ods_log_warning("[%s] unable to add RR to RRset (%i): "
-                      "duplicate", rrset_str, rrset->rrtype);
-                log_rr(rr, "+rr", LOG_WARNING);
-                /* filter out duplicates */
-                return rr;
-            } else {
-                ods_log_error("[%s] unable to add RR to RRset (%i): %s",
-                    rrset_str, rrset->rrtype,
-                    ldns_get_errorstr_by_id(status));
-                log_rr(rr, "+rr", LOG_ERR);
-                ldns_dnssec_rrs_deep_free(rrset->add);
-                rrset->add = NULL;
-                rrset->add_count = 0;
-                return NULL;
-            }
-        }
-        rrset->add_count += 1;
-        log_rr(rr, "+rr", LOG_DEEEBUG);
-    }
+    allocator_deallocate(zone->allocator, (void*) rrs_old);
+    rrset->rr_count++;
+    rrset->rrs[rrset->rr_count - 1].owner = rrset->domain;
+    rrset->rrs[rrset->rr_count - 1].rr = rr;
+    rrset->rrs[rrset->rr_count - 1].exists = 0;
+    rrset->rrs[rrset->rr_count - 1].is_added = 1;
+    rrset->rrs[rrset->rr_count - 1].is_removed = 0;
+    rrset->needs_signing = 1;
+    log_rr(rr, "+RR", LOG_DEBUG);
     return rr;
 }
 
@@ -388,399 +336,142 @@
  * Delete RR from RRset.
  *
  */
-ldns_rr*
-rrset_del_rr(rrset_type* rrset, ldns_rr* rr, int dupallowed)
+void
+rrset_del_rr(rrset_type* rrset, uint16_t rrnum)
 {
-    ldns_status status = LDNS_STATUS_OK;
+    rr_type* rrs_orig = NULL;
+    zone_type* zone = NULL;
 
-    if (!rr) {
-        ods_log_error("[%s] unable to delete RR: no RR", rrset_str);
-        return NULL;
-    }
-    ods_log_assert(rr);
-
-    if (!rrset) {
-        ods_log_error("[%s] unable to delete RR: no storage", rrset_str);
-        return NULL;
-    }
     ods_log_assert(rrset);
+    ods_log_assert(rrnum < rrset->rr_count);
 
-    if (rrset->rrtype != ldns_rr_get_type(rr)) {
-        ods_log_error("[%s] unable to delete RR: RRtype mismatch", rrset_str);
-        return NULL;
+    zone = (zone_type*) rrset->zone;
+    log_rr(rrset->rrs[rrnum].rr, "-RR", LOG_DEBUG);
+    rrset->rrs[rrnum].owner = NULL;
+    rrset->rrs[rrnum].rr = NULL;
+    while (rrnum < rrset->rr_count-1) {
+        rrset->rrs[rrnum] = rrset->rrs[rrnum+1];
+        rrnum++;
     }
-
-    if (!rrset->del) {
-        rrset->del = ldns_dnssec_rrs_new();
+    memset(&rrset->rrs[rrset->rr_count-1], 0, sizeof(rr_type));
+    rrs_orig = rrset->rrs;
+    rrset->rrs = (rr_type*) allocator_alloc(zone->allocator,
+        (rrset->rr_count - 1) * sizeof(rr_type));
+    if(!rrset->rrs) {
+        ods_log_error("[%s] unable to delete RR: allocator_alloc() failed",
+            rrset_str);
+        exit(1);
     }
-
-    if (!rrset->del->rr) {
-        rrset->del->rr = rr;
-        rrset->del_count = 1;
-        log_rr(rr, "-rr", LOG_DEEEBUG);
-    } else {
-        status = util_dnssec_rrs_add_rr(rrset->del, rr);
-        if (status != LDNS_STATUS_OK) {
-            if (status == LDNS_STATUS_NO_DATA) {
-                if (dupallowed) {
-                    return rr;
-                }
-                ods_log_warning("[%s] unable to delete RR from RRset (%i): "
-                    "duplicate", rrset_str, rrset->rrtype);
-                log_rr(rr, "-rr", LOG_WARNING);
-                /* filter out duplicates */
-                return rr;
-            } else {
-                ods_log_error("[%s] unable to delete RR from RRset (%i): %s",
-                   rrset_str, rrset->rrtype,
-                   ldns_get_errorstr_by_id(status));
-                log_rr(rr, "-rr", LOG_ERR);
-                ldns_dnssec_rrs_deep_free(rrset->del);
-                rrset->del = NULL;
-                rrset->del_count = 0;
-                return NULL;
-            }
-        }
-        rrset->del_count += 1;
-        log_rr(rr, "-rr", LOG_DEEEBUG);
+    if (rrs_orig) {
+        memcpy(rrset->rrs, rrs_orig, (rrset->rr_count -1) * sizeof(rr_type));
     }
-    return rr;
+    allocator_deallocate(zone->allocator, (void*) rrs_orig);
+    rrset->rr_count--;
+    rrset->needs_signing = 1;
+    return;
 }
 
 
 /**
- * Wipe out current RRs in RRset.
- *
- */
-ods_status
-rrset_wipe_out(rrset_type* rrset)
-{
-    ldns_dnssec_rrs* rrs = NULL;
-    ldns_rr* del_rr = NULL;
-    int error = 0;
-
-    if (rrset) {
-        rrs = rrset->rrs;
-    }
-
-    while (rrs) {
-        if (rrs->rr) {
-            del_rr = ldns_rr_clone(rrs->rr);
-            if (rrset_del_rr(rrset, del_rr,
-                (ldns_rr_get_type(del_rr) == LDNS_RR_TYPE_DNSKEY)) == NULL) {
-                ods_log_error("[%s] unable to wipe RR from RRset (%i)",
-                    rrset_str, rrset->rrtype);
-                ldns_rr_free(del_rr);
-                error = 1;
-            }
-            del_rr = NULL;
-        }
-        rrs = rrs->next;
-    }
-
-    if (error) {
-        return ODS_STATUS_ERR;
-    }
-    return ODS_STATUS_OK;
-}
-
-
-/**
  * Apply differences at RRset.
  *
  */
 void
 rrset_diff(rrset_type* rrset, keylist_type* kl)
 {
-    ldns_status lstatus = LDNS_STATUS_OK;
-    ldns_dnssec_rrs* current = NULL;
-    ldns_dnssec_rrs* pending = NULL;
-    ldns_dnssec_rrs* prev = NULL;
-    ldns_rr* rr = NULL;
-    int cmp = 0;
-
+    uint16_t i = 0;
     if (!rrset) {
         return;
     }
-
-    current = rrset->rrs;
-    pending = rrset->add;
-
-    if (!current || !current->rr) {
-        current = NULL;
-    }
-    if (!pending || !pending->rr) {
-        pending = NULL;
-    }
-
-    while (current && pending) {
-        lstatus = util_dnssec_rrs_compare(current->rr, pending->rr, &cmp);
-        if (lstatus != LDNS_STATUS_OK) {
-                ods_log_error("[%s] diff failed: compare failed (%s)",
-                    rrset_str, ldns_get_errorstr_by_id(lstatus));
-                return;
+    for (i=0; i < rrset->rr_count; i++) {
+        if (rrset->rrs[i].is_added) {
+            rrset->rrs[i].exists = 1;
+            rrset->rrs[i].is_added = 0;
+        } else if (rrset->rrs[i].is_removed) {
+            rrset->rrs[i].exists = 0;
+            rrset_del_rr(rrset, i);
+            i--;
         }
-
-        if (cmp > 0) {
-            prev = pending;
-            pending = pending->next;
-        } else if (cmp < 0) {
-            /* pend current RR to be removed */
-            if (rrset->rrtype != LDNS_RR_TYPE_DNSKEY ||
-                !keylist_lookup_by_dnskey(kl, current->rr)) {
-
-                rr = ldns_rr_clone(current->rr);
-                rr = rrset_del_rr(rrset, rr,
-                    (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY));
-                if (!rr) {
-                    ods_log_error("[%s] diff failed: failed to delete RR",
-                        rrset_str);
-                    return;
-                }
-            }
-
-            current = current->next;
-        } else { /* equal RRs */
-            /* remove pending RR */
-            if (!prev) {
-                rrset->add = pending->next;
-            } else {
-                prev->next = pending->next;
-            }
-            pending->next = NULL;
-            rrset->add_count -= 1;
-
-            ldns_dnssec_rrs_deep_free(pending);
-            pending = NULL;
-
-            current = current->next;
-            if (!prev) {
-                pending = rrset->add;
-            } else {
-                pending = prev->next;
-            }
-        }
     }
-
-    if (pending) {
-        ods_log_assert(!current);
-        /* all newly added RRs */
-    }
-
-    if (current) {
-        ods_log_assert(!pending);
-        while (current) {
-            /* pend current RR to be removed */
-            if (rrset->rrtype != LDNS_RR_TYPE_DNSKEY ||
-                !keylist_lookup_by_dnskey(kl, current->rr)) {
-
-                rr = ldns_rr_clone(current->rr);
-                rr = rrset_del_rr(rrset, rr,
-                    (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY));
-                if (!rr) {
-                    ods_log_error("[%s] diff failed: failed to delete RR",
-                        rrset_str);
-                    return;
-                }
-            }
-            current = current->next;
-        }
-    }
     return;
 }
 
 
 /**
- * Commit deletion.
+ * Add RRSIG to RRset.
  *
  */
-static ods_status
-rrset_commit_del(rrset_type* rrset, ldns_rr* rr)
+rrsig_type*
+rrset_add_rrsig(rrset_type* rrset, ldns_rr* rr,
+    const char* locator, uint32_t flags)
 {
-    ldns_status status = LDNS_STATUS_OK;
-    ldns_dnssec_rrs* rrs = NULL;
-    ldns_dnssec_rrs* prev_rrs = NULL;
-    int cmp = 0;
+    rrsig_type* rrsigs_old = NULL;
+    zone_type* zone = NULL;
 
-    if (!rr) {
-        ods_log_error("[%s] unable to commit del RR: no RR", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
-    ods_log_assert(rr);
-    if (!rrset) {
-        ods_log_error("[%s] unable to commit del RR: no storage", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
     ods_log_assert(rrset);
-
-    rrs = rrset->rrs;
-    while (rrs) {
-        status = util_dnssec_rrs_compare(rrs->rr, rr, &cmp);
-        if (status != LDNS_STATUS_OK) {
-            ods_log_error("[%s] unable to commit del RR: compare failed",
-                rrset_str);
-            return ODS_STATUS_ERR;
-        }
-
-        if (cmp == 0) {
-            /* this is it */
-            if (prev_rrs) {
-                prev_rrs->next = rrs->next;
-            } else {
-                rrset->rrs = rrs->next;
-            }
-            rrs->next = NULL;
-            ldns_dnssec_rrs_deep_free(rrs);
-            rrs = NULL;
-
-            rrset->rr_count -= 1;
-            rrset->del_count -= 1;
-            log_rr(rr, "-RR", LOG_DEBUG);
-            return ODS_STATUS_OK;
-        }
-
-        /* keep looking */
-        prev_rrs = rrs;
-        rrs = rrs->next;
-    }
-
-    ods_log_warning("[%s] unable to commit del RR: no such RR", rrset_str);
-    log_rr(rr, "-RR", LOG_ERR);
-    return ODS_STATUS_UNCHANGED;
-}
-
-
-/**
- * Commit addition.
- *
- */
-static ods_status
-rrset_commit_add(rrset_type* rrset, ldns_rr* rr)
-{
-    ldns_status status = LDNS_STATUS_OK;
-
-    if (!rr) {
-        ods_log_error("[%s] unable to commit add RR: no RR", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
     ods_log_assert(rr);
-    if (!rrset) {
-        ods_log_error("[%s] unable to commit add RR: no storage", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
-    ods_log_assert(rrset);
+    ods_log_assert(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG);
 
-    if (!rrset->rrs) {
-        rrset->rrs = ldns_dnssec_rrs_new();
+    zone = (zone_type*) rrset->zone;
+    rrsigs_old = rrset->rrsigs;
+    rrset->rrsigs = (rrsig_type*) allocator_alloc(zone->allocator,
+        (rrset->rrsig_count + 1) * sizeof(rrsig_type));
+    if (!rrset->rrsigs) {
+        ods_log_error("[%s] unable to add RRSIG: allocator_alloc() failed",
+            rrset_str);
+        exit(1);
     }
-
-    if (!rrset->rrs->rr) {
-        rrset->rrs->rr = rr;
-        rrset->rr_count += 1;
-        rrset->add_count -= 1;
-        log_rr(rr, "+RR", LOG_DEBUG);
-        return ODS_STATUS_OK;
-    } else {
-        status = util_dnssec_rrs_add_rr(rrset->rrs, rr);
-        if (status != LDNS_STATUS_OK) {
-            if (status == LDNS_STATUS_NO_DATA) {
-                ods_log_warning("[%s] unable to commit add RR: duplicate",
-                    rrset_str);
-                log_rr(rr, "+RR", LOG_WARNING);
-                return ODS_STATUS_UNCHANGED;
-            } else {
-                ods_log_error("[%s] unable to commit add RR: %s",
-                    rrset_str, ldns_get_errorstr_by_id(status));
-                log_rr(rr, "+RR", LOG_ERR);
-                return ODS_STATUS_ERR;
-            }
-        }
-        log_rr(rr, "+RR", LOG_DEBUG);
-        rrset->rr_count += 1;
-        rrset->add_count -= 1;
-        return ODS_STATUS_OK;
+    if (rrsigs_old) {
+        memcpy(rrset->rrsigs, rrsigs_old,
+            (rrset->rrsig_count) * sizeof(rrsig_type));
     }
-    /* not reached */
-    return ODS_STATUS_ERR;
+    allocator_deallocate(zone->allocator, (void*) rrsigs_old);
+    rrset->rrsig_count++;
+    rrset->rrsigs[rrset->rrsig_count - 1].owner = rrset->domain;
+    rrset->rrsigs[rrset->rrsig_count - 1].rr = rr;
+    rrset->rrsigs[rrset->rrsig_count - 1].key_locator = locator;
+    rrset->rrsigs[rrset->rrsig_count - 1].key_flags = flags;
+    log_rr(rr, "+RRSIG", LOG_DEBUG);
+    return &rrset->rrsigs[rrset->rrsig_count -1];
 }
 
 
 /**
- * Commit updates from RRset.
+ * Delete RRSIG from RRset.
  *
  */
-ods_status
-rrset_commit(rrset_type* rrset)
+void
+rrset_del_rrsig(rrset_type* rrset, uint16_t rrnum)
 {
-    ldns_dnssec_rrs* rrs = NULL;
-    ods_status status = ODS_STATUS_OK;
+    rrsig_type* rrsigs_orig = NULL;
+    zone_type* zone = NULL;
 
-    if (!rrset) {
-        return ODS_STATUS_ASSERT_ERR;
-    }
     ods_log_assert(rrset);
+    ods_log_assert(rrnum < rrset->rrsig_count);
 
-    if (rrset->del_count || rrset->add_count) {
-        rrset->needs_signing = 1;
+    zone = (zone_type*) rrset->zone;
+    log_rr(rrset->rrsigs[rrnum].rr, "-RRSIG", LOG_DEBUG);
+    rrset->rrsigs[rrnum].owner = NULL;
+    rrset->rrsigs[rrnum].rr = NULL;
+    while (rrnum < rrset->rrsig_count-1) {
+        rrset->rrsigs[rrnum] = rrset->rrsigs[rrnum+1];
+        rrnum++;
     }
-
-    /* delete RRs */
-    rrs = rrset->del;
-    while (rrs) {
-        status = rrset_commit_del(rrset, rrs->rr);
-        if (status != ODS_STATUS_OK) {
-            ods_log_alert("[%s] commit RRset (%i) failed: %s", rrset_str,
-                rrset->rrtype, ods_status2str(status));
-            return status;
-        }
-        rrs = rrs->next;
+    memset(&rrset->rrsigs[rrset->rrsig_count-1], 0, sizeof(rrsig_type));
+    rrsigs_orig = rrset->rrsigs;
+    rrset->rrsigs = (rrsig_type*) allocator_alloc(zone->allocator,
+        (rrset->rrsig_count - 1) * sizeof(rrsig_type));
+    if(!rrset->rrsigs) {
+        ods_log_error("[%s] unable to delete RRSIG: allocator_alloc() failed",
+            rrset_str);
+        exit(1);
     }
-    ldns_dnssec_rrs_deep_free(rrset->del);
-    rrset->del = NULL;
-    rrset->del_count = 0;
-
-    /* add RRs */
-    rrs = rrset->add;
-    while (rrs) {
-        status = rrset_commit_add(rrset, rrs->rr);
-        if (status != ODS_STATUS_OK) {
-            ods_log_alert("[%s] commit RRset (%i) failed: %s", rrset_str,
-                rrset->rrtype, ods_status2str(status));
-            return status;
-        }
-        rrs = rrs->next;
+    if (rrsigs_orig) {
+        memcpy(rrset->rrsigs, rrsigs_orig,
+            (rrset->rrsig_count -1) * sizeof(rrsig_type));
     }
-    ldns_dnssec_rrs_free(rrset->add);
-    rrset->add = NULL;
-    rrset->add_count = 0;
-
-    /* update serial */
-
-    return ODS_STATUS_OK;
-}
-
-
-/**
- * Rollback updates from RRset.
- *
- */
-void
-rrset_rollback(rrset_type* rrset)
-{
-    if (!rrset) {
-        return;
-    }
-
-    if (rrset->add) {
-        ldns_dnssec_rrs_deep_free(rrset->add);
-        rrset->add = NULL;
-        rrset->add_count = 0;
-    }
-    if (rrset->del) {
-        ldns_dnssec_rrs_deep_free(rrset->del);
-        rrset->del = NULL;
-        rrset->del_count = 0;
-    }
+    allocator_deallocate(zone->allocator, (void*) rrsigs_orig);
+    rrset->rrsig_count--;
     return;
 }
 
@@ -792,134 +483,83 @@
 static uint32_t
 rrset_recycle(rrset_type* rrset, signconf_type* sc, time_t signtime)
 {
-    rrsigs_type* rrsigs = NULL;
-    rrsigs_type* prev_rrsigs = NULL;
-    rrsigs_type* next_rrsigs = NULL;
     uint32_t refresh = 0;
     uint32_t expiration = 0;
     uint32_t inception = 0;
     uint32_t reusedsigs = 0;
-    int drop_sig = 0;
+    unsigned drop_sig = 0;
+    size_t i = 0;
     key_type* key = NULL;
 
+    if (!rrset) {
+        return 0;
+    }
     /* Calculate the Refresh Window = Signing time + Refresh */
     if (sc && sc->sig_refresh_interval) {
         refresh = (uint32_t) (signtime +
             duration2time(sc->sig_refresh_interval));
     }
-
-    /* 1. If the RRset has changed, drop all signatures */
-    /* 2. If Refresh is disabled, drop all signatures */
-    if (rrset->needs_signing || !refresh) {
-        ods_log_debug("[%s] drop signatures for RRset[%i]", rrset_str,
-            rrset->rrtype);
-        if (rrset->rrsigs) {
-            rrsigs_cleanup(rrset->rrsigs);
-            rrset->rrsigs = NULL;
+    /* Check every signature if it matches the recycling logic. */
+    for (i=0; i < rrset->rrsig_count; i++) {
+        drop_sig = 0;
+        /* 1. If the RRset has changed, drop all signatures */
+        /* 2. If Refresh is disabled, drop all signatures */
+        if (rrset->needs_signing || !refresh) {
+            drop_sig = 1;
+            goto recycle_drop_sig;
         }
-        rrset->rrsig_count = 0;
-        rrset->needs_signing = 0;
-        return 0;
-    }
-
-    /* 3. Check every signature if it matches the recycling logic. */
-    rrsigs = rrset->rrsigs;
-    while (rrsigs) {
-        if (!rrsigs->rr) {
-          ods_log_warning("[%s] signature set has no RRSIG record: "
-                "drop signatures for RRset[%i]", rrset_str, rrset->rrtype);
-            rrsigs_cleanup(rrset->rrsigs);
-            rrset->rrsigs = NULL;
-            rrset->rrsig_count = 0;
-            rrset->needs_signing = 0;
-            return 0;
-        }
-
+        /* 3. Expiration - Refresh has passed */
         expiration = ldns_rdf2native_int32(
-            ldns_rr_rrsig_expiration(rrsigs->rr));
-        inception = ldns_rdf2native_int32(
-            ldns_rr_rrsig_inception(rrsigs->rr));
-
+            ldns_rr_rrsig_expiration(rrset->rrsigs[i].rr));
         if (expiration < refresh) {
-            /* 3a. Expiration - Refresh has passed */
             drop_sig = 1;
-            ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
-                "expiration minus refresh has passed: %u - %u < (signtime)",
-                rrset_str, rrset->rrtype, expiration, refresh,
-                (uint32_t) signtime);
-        } else if (inception > (uint32_t) signtime) {
-            /* 3b. Inception has not yet passed */
+            goto recycle_drop_sig;
+        }
+        /* 4. Inception has not yet passed */
+        inception = ldns_rdf2native_int32(
+            ldns_rr_rrsig_inception(rrset->rrsigs[i].rr));
+        if (inception > (uint32_t) signtime) {
             drop_sig = 1;
-            ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
-                "inception has not passed: %u < %u (signtime)", rrset_str,
-                rrset->rrtype, inception, (uint32_t) signtime);
-        } else {
-            /* 3c. Corresponding key is dead (key is locator+flags) */
-            key = keylist_lookup_by_locator(sc->keys, rrsigs->key_locator);
-            if (!key) {
-                drop_sig = 1;
-                ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
-                "key %s %u is dead", rrset_str,
-                rrset->rrtype, rrsigs->key_locator, rrsigs->key_flags);
-            } else if (key->flags != rrsigs->key_flags) {
-                drop_sig = 1;
-                ods_log_deeebug("[%s] refresh signature for RRset[%i]: "
-                "key %s %u flags mismatch", rrset_str,
-                rrset->rrtype, rrsigs->key_locator, rrsigs->key_flags);
-            }
+            goto recycle_drop_sig;
         }
+        /* 5. Corresponding key is dead (key is locator+flags) */
+        key = keylist_lookup_by_locator(sc->keys,
+            rrset->rrsigs[i].key_locator);
+        if (!key || key->flags != rrset->rrsigs[i].key_flags) {
+            drop_sig = 1;
+        }
 
-        next_rrsigs = rrsigs->next;
+recycle_drop_sig:
         if (drop_sig) {
             /* A rule mismatched, refresh signature */
-            if (prev_rrsigs) {
-                prev_rrsigs->next = rrsigs->next;
-            } else {
-                rrset->rrsigs = rrsigs->next;
-            }
-            log_rr(rrsigs->rr, "-RRSIG", LOG_DEBUG);
-            rrset->rrsig_count -= 1;
-            rrsigs->next = NULL;
-            rrsigs_cleanup(rrsigs);
+            rrset_del_rrsig(rrset, i);
+            i--;
         } else {
             /* All rules ok, recycle signature */
-            ods_log_deeebug("[%s] recycle signature for RRset[%i] "
-                "(refresh=%u, signtime=%u, inception=%u, expiration=%u)",
-                rrset_str, rrset->rrtype, refresh, (uint32_t) signtime,
-                inception, expiration);
-            log_rr(rrsigs->rr, "*RRSIG", LOG_DEEEBUG);
             reusedsigs += 1;
-            prev_rrsigs = rrsigs;
         }
-        drop_sig = 0;
-        rrsigs = next_rrsigs;
     }
     return reusedsigs;
 }
 
 
 /**
- * See if there exists a signature with this algorithm.
+ * Is the RRset signed with this algorithm?
  *
  */
 static int
-rrset_signed_with_algorithm(rrset_type* rrset, uint8_t algorithm)
+rrset_sigalgo(rrset_type* rrset, uint8_t algorithm)
 {
-    rrsigs_type* rrsigs = NULL;
-
-    if (!rrset || !algorithm) {
+    size_t i = 0;
+    if (!rrset) {
         return 0;
     }
-
-    rrsigs = rrset->rrsigs;
-    while (rrsigs) {
-        if (rrsigs->rr && algorithm ==
-            ldns_rdf2native_int8(ldns_rr_rrsig_algorithm(rrsigs->rr))) {
+    for (i=0; i < rrset->rrsig_count; i++) {
+        if (algorithm == ldns_rdf2native_int8(
+                ldns_rr_rrsig_algorithm(rrset->rrsigs[i].rr))) {
             return 1;
         }
-        rrsigs = rrsigs->next;
     }
-
     return 0;
 }
 
@@ -931,15 +571,15 @@
 static ldns_rr_list*
 rrset2rrlist(rrset_type* rrset)
 {
-    ldns_dnssec_rrs* rrs = NULL;
     ldns_rr_list* rr_list = NULL;
-    int error = 0;
-
+    int ret = 0;
+    size_t i = 0;
     rr_list = ldns_rr_list_new();
-    rrs = rrset->rrs;
-    while (rrs && rrs->rr) {
-        error = (int) ldns_rr_list_push_rr(rr_list, rrs->rr);
-        if (!error) {
+    for (i=0; i < rrset->rr_count; i++) {
+        /* clone if you want to keep the original format in the signed zone */
+        ldns_rr2canonical(rrset->rrs[i].rr);
+        ret = (int) ldns_rr_list_push_rr(rr_list, rrset->rrs[i].rr);
+        if (!ret) {
             ldns_rr_list_free(rr_list);
             return NULL;
         }
@@ -948,8 +588,8 @@
             /* singleton types */
             return rr_list;
         }
-        rrs = rrs->next;
     }
+    ldns_rr_list_sort(rr_list);
     return rr_list;
 }
 
@@ -966,11 +606,9 @@
     time_t offset = 0;
     time_t validity = 0;
     time_t random_jitter = 0;
-
     if (!sc || !rrtype || !signtime) {
         return;
     }
-
     jitter = duration2time(sc->sig_jitter);
     if (jitter) {
         random_jitter = ods_rand(jitter*2);
@@ -1022,137 +660,80 @@
     uint32_t reusedsigs = 0;
     ldns_rr* rrsig = NULL;
     ldns_rr_list* rr_list = NULL;
-    rrsigs_type* new_rrsigs = NULL;
-    rrsigs_type* walk_rrsigs = NULL;
+    rrsig_type* signature = NULL;
     key_type* key = NULL;
+    const char* locator = NULL;
     time_t inception = 0;
     time_t expiration = 0;
     uint16_t i = 0;
 
-    if (!rrset) {
-        ods_log_error("[%s] unable to sign RRset: no RRset", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
+    ods_log_assert(ctx);
     ods_log_assert(rrset);
-
-    if (!owner) {
-        ods_log_error("[%s] unable to sign RRset: no owner", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
+    ods_log_assert(sc);
     ods_log_assert(owner);
+    ods_log_assert(stats);
 
-    if (!sc) {
-        ods_log_error("[%s] unable to sign RRset: no signconf", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
-    ods_log_assert(sc);
-
-    /* recycle signatures */
+    /* Recycle signatures */
     reusedsigs = rrset_recycle(rrset, sc, signtime);
+    rrset->needs_signing = 0;
 
-    /* transmogrify the RRset */
+    /* Transmogrify rrset */
     rr_list = rrset2rrlist(rrset);
     if (!rr_list) {
-        ods_log_error("[%s] unable to sign RRset[%i]: to RRlist failed",
+        ods_log_error("[%s] unable to sign RRset[%i]: rrset2rrlist() failed",
             rrset_str, rrset->rrtype);
         return ODS_STATUS_ERR;
     }
     if (ldns_rr_list_rr_count(rr_list) <= 0) {
-        /* empty RRset, no signatures needed */
+        /* Empty RRset, no signatures needed */
         ldns_rr_list_free(rr_list);
         return ODS_STATUS_OK;
     }
-
-    /* prepare for signing */
-    new_rrsigs = rrsigs_create();
-    if (!rrset->rrsigs) {
-        rrset->rrsigs = rrsigs_create();
-    }
+    /* Calculate signature validity */
     rrset_sigvalid_period(sc, rrset->rrtype, signtime,
          &inception, &expiration);
     /* Walk keys */
     for (i=0; i < sc->keys->count; i++) {
         key = &sc->keys->keys[i];
-        /* ksk or zsk ? */
+        /* ZSKs don't sign DNSKEY RRset */
         if (!key->zsk && rrset->rrtype != LDNS_RR_TYPE_DNSKEY) {
             ods_log_deeebug("[%s] skipping key %s for signing RRset[%i]: no "
                 "active ZSK", rrset_str, key->locator, rrset->rrtype);
             continue;
         }
+        /* KSKs only sign DNSKEY RRset */
         if (!key->ksk && rrset->rrtype == LDNS_RR_TYPE_DNSKEY) {
             ods_log_deeebug("[%s] skipping key %s for signing RRset[%i]: no "
                 "active KSK", rrset_str, key->locator, rrset->rrtype);
             continue;
         }
-
-        /* is there a signature with this algorithm already? */
-        if (rrset_signed_with_algorithm(rrset, key->algorithm)) {
+        /* Additional rules for signatures */
+        if (rrset_sigalgo(rrset, key->algorithm)) {
             ods_log_deeebug("skipping key %s for signing: RRset[%i] "
                 "already has signature with same algorithm", key->locator);
             continue;
         }
-
         /**
          * currently, there is no rule that the number of signatures
          * over this RRset equals the number of active keys.
          */
-
-        /* sign the RRset with current key */
+        /* Sign the RRset with this key */
         ods_log_deeebug("[%s] signing RRset[%i] with key %s", rrset_str,
             rrset->rrtype, key->locator);
         rrsig = lhsm_sign(ctx, rr_list, key, owner, inception, expiration);
         if (!rrsig) {
-            ods_log_error("[%s] unable to sign RRset[%i]: error creating "
-                "RRSIG RR", rrset_str, rrset->rrtype);
-            ldns_rr_list_free(rr_list);
-            rrsigs_cleanup(new_rrsigs);
+            ods_log_crit("[%s] unable to sign RRset[%i]: lhsm_sign() failed",
+                rrset_str, rrset->rrtype);
             return ODS_STATUS_ERR;
         }
-        /* add the signature to the set of new signatures */
-        ods_log_deeebug("[%s] new signature created for RRset[%i]", rrset_str,
-            rrset->rrtype);
-        log_rr(rrsig, "+rrsig", LOG_DEEEBUG);
-        status = rrsigs_add_sig(new_rrsigs, rrsig, key->locator, key->flags);
-        if (status != ODS_STATUS_OK) {
-            ods_log_error("[%s] unable to sign RRset[%i]: error adding RRSIG",
-                rrset_str, rrset->rrtype);
-                log_rr(rrsig, "+RRSIG", LOG_ERR);
-                ldns_rr_list_free(rr_list);
-                rrsigs_cleanup(new_rrsigs);
-            return status;
-        }
-        /* next key */
+        /* Add signature */
+        locator = strdup(sc->keys->keys[i].locator);
+        signature = rrset_add_rrsig(rrset, rrsig, locator,
+            sc->keys->keys[i].flags);
+        newsigs++;
     }
-
-    /* signing completed, add the signatures to the right RRset */
-    walk_rrsigs = new_rrsigs;
-    while (walk_rrsigs) {
-        if (walk_rrsigs->rr) {
-            ods_log_deeebug("[%s] adding signature to RRset[%i]", rrset_str,
-                    rrset->rrtype);
-            status = rrsigs_add_sig(rrset->rrsigs,
-                ldns_rr_clone(walk_rrsigs->rr),
-                walk_rrsigs->key_locator, walk_rrsigs->key_flags);
-            if (status != ODS_STATUS_OK) {
-                ods_log_error("[%s] unable to sign RRset[%i]: error adding "
-                    "RRSIG to RRset[%i]", rrset_str, rrset->rrtype,
-                    rrset->rrtype);
-                log_rr(walk_rrsigs->rr, "+RRSIG", LOG_ERR);
-                ldns_rr_list_free(rr_list);
-                rrsigs_cleanup(new_rrsigs);
-                return status;
-            }
-            rrset->rrsig_count += 1;
-            newsigs++;
-            log_rr(walk_rrsigs->rr, "+RRSIG", LOG_DEBUG);
-        }
-        walk_rrsigs = walk_rrsigs->next;
-    }
-
-    /* clean up */
-    rrsigs_cleanup(new_rrsigs);
+    /* RRset signing completed */
     ldns_rr_list_free(rr_list);
-
     lock_basic_lock(&stats->stats_lock);
     if (rrset->rrtype == LDNS_RR_TYPE_SOA) {
         stats->sig_soa_count += newsigs;
@@ -1172,23 +753,9 @@
 rrset_queue(rrset_type* rrset, fifoq_type* q, worker_type* worker)
 {
     ods_status status = ODS_STATUS_UNCHANGED;
-
-    if (!rrset) {
-        ods_log_error("[%s] unable to queue RRset: no RRset", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
     ods_log_assert(rrset);
-    if (!worker) {
-        ods_log_error("[%s] unable to queue RRset: no worker", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
     ods_log_assert(worker);
-    if (!q) {
-        ods_log_error("[%s] unable to queue RRset: no queue", rrset_str);
-        return ODS_STATUS_ASSERT_ERR;
-    }
     ods_log_assert(q);
-
     while (status == ODS_STATUS_UNCHANGED && !worker->need_to_exit) {
         lock_basic_lock(&q->q_lock);
         status = fifoq_push(q, (void*) rrset, worker);
@@ -1196,9 +763,7 @@
     }
     if (status == ODS_STATUS_OK) {
         lock_basic_lock(&worker->worker_lock);
-        /* [LOCK] worker */
         worker->jobs_appointed += 1;
-        /* [UNLOCK] worker */
         lock_basic_unlock(&worker->worker_lock);
     }
     return status;
@@ -1212,26 +777,24 @@
 void
 rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs)
 {
+    uint16_t i = 0;
     if (!rrset || !fd) {
         return;
     }
-    ods_log_assert(fd);
-    ods_log_assert(rrset);
-
-    if (rrset->rrs) {
+    for (i=0; i < rrset->rr_count; i++) {
+        ldns_rr_print(fd, rrset->rrs[i].rr);
         if (rrset->rrtype == LDNS_RR_TYPE_CNAME ||
             rrset->rrtype == LDNS_RR_TYPE_DNAME) {
             /* singleton types */
-            if (rrset->rrs->rr) {
-                ldns_rr_print(fd, rrset->rrs->rr);
-            }
-        } else {
-            ldns_dnssec_rrs_print(fd, rrset->rrs);
+            break;
         }
     }
-    if (rrset->rrsigs && !skip_rrsigs) {
-        rrsigs_print(fd, rrset->rrsigs, 0);
+    if (skip_rrsigs || !rrset->rrsig_count) {
+        return;
     }
+    for (i=0; i < rrset->rrsig_count; i++) {
+        ldns_rr_print(fd, rrset->rrsigs[i].rr);
+    }
     return;
 }
 
@@ -1243,12 +806,16 @@
 void
 rrset_backup(FILE* fd, rrset_type* rrset)
 {
+    uint16_t i = 0;
     if (!rrset || !fd) {
         return;
     }
-    if (rrset->rrsigs) {
-        rrsigs_print(fd, rrset->rrsigs, 1);
+    if (!rrset || !fd) {
+        return;
     }
+    for (i=0; i < rrset->rrsig_count; i++) {
+        ldns_rr_print(fd, rrset->rrsigs[i].rr);
+    }
     return;
 }
 
@@ -1260,27 +827,27 @@
 void
 rrset_cleanup(rrset_type* rrset)
 {
+    uint16_t i = 0;
     zone_type* zone = NULL;
     if (!rrset) {
-        return;
+       return;
     }
+    rrset_cleanup(rrset->next);
+    rrset->next = NULL;
+    rrset->domain = NULL;
     zone = (zone_type*) rrset->zone;
-    if (rrset->rrs) {
-        ldns_dnssec_rrs_deep_free(rrset->rrs);
-        rrset->rrs = NULL;
+    for (i=0; i < rrset->rr_count; i++) {
+        ldns_rr_free(rrset->rrs[i].rr);
+        rrset->rrs[i].owner = NULL;
     }
-    if (rrset->add) {
-        ldns_dnssec_rrs_deep_free(rrset->add);
-        rrset->add = NULL;
+    for (i=0; i < rrset->rrsig_count; i++) {
+        allocator_deallocate(zone->allocator,
+            (void*)rrset->rrsigs[i].key_locator);
+        ldns_rr_free(rrset->rrsigs[i].rr);
+        rrset->rrsigs[i].owner = NULL;
     }
-    if (rrset->del) {
-        ldns_dnssec_rrs_deep_free(rrset->del);
-        rrset->del = NULL;
-    }
-    if (rrset->rrsigs) {
-        rrsigs_cleanup(rrset->rrsigs);
-        rrset->rrsigs = NULL;
-    }
+    allocator_deallocate(zone->allocator, (void*) rrset->rrs);
+    allocator_deallocate(zone->allocator, (void*) rrset->rrsigs);
     allocator_deallocate(zone->allocator, (void*) rrset);
     return;
 }

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/rrset.h
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/rrset.h	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/rrset.h	2011-08-25 13:30:17 UTC (rev 5482)
@@ -48,10 +48,6 @@
 
 #include <ldns/ldns.h>
 
-#define COUNT_RR  0
-#define COUNT_ADD 1
-#define COUNT_DEL 2
-
 /**
  * RRSIG.
  *
@@ -83,17 +79,15 @@
  */
 typedef struct rrset_struct rrset_type;
 struct rrset_struct {
+    rrset_type* next;
     void* zone;
+    void* domain;
     ldns_rr_type rrtype;
-    uint32_t rr_count;
-    uint32_t add_count;
-    uint32_t del_count;
-    uint32_t rrsig_count;
+    rr_type* rrs;
+    rrsig_type* rrsigs;
+    size_t rr_count;
+    size_t rrsig_count;
     int needs_signing;
-    ldns_dnssec_rrs* rrs;
-    ldns_dnssec_rrs* add;
-    ldns_dnssec_rrs* del;
-    rrsigs_type* rrsigs;
 };
 
 /**
@@ -145,21 +139,21 @@
     const char* locator, uint32_t flags);
 
 /**
- * Count the number of RRs in this RRset.
+ * Lookup RR in RRset.
  * \param[in] rrset RRset
- * \param[in] which which RRset to be counted
- * \return size_t number of RRs
+ * \param[in] rr RR
+ * \return rr_type* RR if found
  *
  */
-size_t rrset_count_rr(rrset_type* rrset, int which);
+rr_type* rrset_lookup_rr(rrset_type* rrset, ldns_rr* rr);
 
 /**
- * Return the number of RRs in RRset after an update.
+ * Count the number of RRs in this RRset.
  * \param[in] rrset RRset
- * \return size_t number of RRs after an update
+ * \return size_t number of RRs
  *
  */
-size_t rrset_count_RR(rrset_type* rrset);
+size_t rrset_count_rr(rrset_type* rrset);
 
 /**
  * Add RR to RRset.
@@ -173,45 +167,40 @@
 /**
  * Delete RR from RRset.
  * \param[in] rrset RRset
- * \param[in] rr RR
- * \param[in] dupallowed if true, allow duplicate deletions
- * \return ldns_rr* RR if failed
+ * \param[in] rrnum position of RR
  *
  */
-ldns_rr* rrset_del_rr(rrset_type* rrset, ldns_rr* rr, int dupallowed);
+void rrset_del_rr(rrset_type* rrset, uint16_t rrnum);
 
 /**
- * Wipe out current RRs in RRset.
+ * Add RRSIG to RRset.
  * \param[in] rrset RRset
- * \return ods_status status
+ * \param[in] rr RRSIG
+ * \param[in] locator key locator
+ * \param[in] flags key flags
+ * \return rr_type* added RRSIG
  *
  */
-ods_status rrset_wipe_out(rrset_type* rrset);
+rrsig_type* rrset_add_rrsig(rrset_type* rrset, ldns_rr* rr,
+    const char* locator, uint32_t flags);
 
 /**
- * Apply differences at RRset.
+ * Delete RRSIG from RRset.
  * \param[in] rrset RRset
- * \param[in] kl current key list
+ * \param[in] rrnum position of RRSIG
  *
  */
-void rrset_diff(rrset_type* rrset, keylist_type* kl);
+void rrset_del_rrsig(rrset_type* rrset, uint16_t rrnum);
 
 /**
- * Commit updates from RRset.
+ * Apply differences at RRset.
  * \param[in] rrset RRset
- * \return ods_status status
+ * \param[in] kl current key list
  *
  */
-ods_status rrset_commit(rrset_type* rrset);
+void rrset_diff(rrset_type* rrset, keylist_type* kl);
 
 /**
- * Rollback updates from RRset.
- * \param[in] rrset RRset
- *
- */
-void rrset_rollback(rrset_type* rrset);
-
-/**
  * Sign RRset.
  * \param[in] ctx HSM context
  * \param[in] rrset RRset
@@ -245,13 +234,6 @@
 int rrset_examine_ns_rdata(rrset_type* rrset, ldns_rdf* nsdname);
 
 /**
- * Clean up RRset.
- * \param[in] rrset RRset to be cleaned up
- *
- */
-void rrset_cleanup(rrset_type* rrset);
-
-/**
  * Print RRset.
  * \param[in] fd file descriptor
  * \param[in] rrset RRset to be printed
@@ -261,6 +243,13 @@
 void rrset_print(FILE* fd, rrset_type* rrset, int skip_rrsigs);
 
 /**
+ * Clean up RRset.
+ * \param[in] rrset RRset to be cleaned up
+ *
+ */
+void rrset_cleanup(rrset_type* rrset);
+
+/**
  * Backup RRset.
  * \param[in] fd file descriptor
  * \param[in] rrset RRset

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/tools.c
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/tools.c	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/tools.c	2011-08-25 13:30:17 UTC (rev 5482)
@@ -229,7 +229,7 @@
     if (status == ODS_STATUS_OK) {
         ods_log_verbose("[%s] commit updates for zone %s", tools_str,
             zone->name?zone->name:"(null)");
-        status = namedb_commit(zone->db);
+        namedb_diff(zone->db, NULL);
     } else {
         ods_log_warning("[%s] rollback updates for zone %s", tools_str,
             zone->name?zone->name:"(null)");

Modified: branches/OpenDNSSEC-adapters/signer/src/signer/zone.c
===================================================================
--- branches/OpenDNSSEC-adapters/signer/src/signer/zone.c	2011-08-25 11:59:22 UTC (rev 5481)
+++ branches/OpenDNSSEC-adapters/signer/src/signer/zone.c	2011-08-25 13:30:17 UTC (rev 5482)
@@ -127,7 +127,7 @@
     char* datestamp = NULL;
     uint32_t ustamp = 0;
 
-    if (!zone || !zone->name || !zone->signconf || new_signconf) {
+    if (!zone || !zone->name || !zone->signconf) {
         return ODS_STATUS_ASSERT_ERR;
     }
     if (!zone->signconf_filename) {
@@ -317,15 +317,7 @@
         ods_log_assert(apex);
 
         rrset = domain_lookup_rrset(apex, LDNS_RR_TYPE_NSEC3PARAMS);
-        if (rrset) {
-            status = rrset_wipe_out(rrset);
-            if (status != ODS_STATUS_OK) {
-                ods_log_error("[%s] unable to wipe out previous "
-                    "NSEC3PARAM RR from zone %s", zone_str, zone->name);
-                rrset_rollback(rrset);
-                return status;
-            }
-        }
+        rrset_diff(rrset, NULL);
     }
     return status;
 }
@@ -548,6 +540,7 @@
 {
     domain_type* domain = NULL;
     rrset_type* rrset = NULL;
+    rr_type* record = NULL;
 
     if (!rr) {
         ods_log_error("[%s] unable to del RR: no RR", zone_str);
@@ -581,11 +574,14 @@
     ods_log_assert(rrset);
 
     /* del RR */
-    if (rrset_del_rr(rrset, rr, (ldns_rr_get_type(rr) == LDNS_RR_TYPE_DNSKEY))
-            == NULL) {
-        ods_log_error("[%s] unable to del RR: pend RR failed", zone_str);
-        return ODS_STATUS_ERR;
+    record = rrset_lookup_rr(rrset, rr);
+    if (!record) {
+        ods_log_error("[%s] unable to delete RR from zone %s: "
+            "RR not found", zone_str, zone->name);
+        return ODS_STATUS_UNCHANGED;
     }
+    record->is_removed = 1;
+    record->is_added = 0; /* unset is_added */
 
     /* update stats */
     if (do_stats && zone->stats) {
@@ -961,11 +957,7 @@
             zone->task = NULL;
             goto recover_error;
         }
-        status = namedb_commit(zone->db);
-        if (status != ODS_STATUS_OK) {
-            zone->task = NULL;
-            goto recover_error;
-        }
+        namedb_diff(zone->db, NULL);
         status = namedb_entize(zone->db, zone->apex);
         if (status != ODS_STATUS_OK) {
             zone->task = NULL;




More information about the Opendnssec-commits mailing list