OpenDNSSEC-signer 1.2.1

/build/buildd-opendnssec_1.2.1.dfsg-1-ia64-j6OroR/opendnssec-1.2.1.dfsg/signer/src/util/util.c

Go to the documentation of this file.
00001 /*
00002  * $Id: util.c 4294 2011-01-13 19:58:29Z jakob $
00003  *
00004  * Copyright (c) 2009 NLNet Labs. All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  * 1. Redistributions of source code must retain the above copyright
00010  *    notice, this list of conditions and the following disclaimer.
00011  * 2. Redistributions in binary form must reproduce the above copyright
00012  *    notice, this list of conditions and the following disclaimer in the
00013  *    documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00017  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
00019  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00020  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00021  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00023  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00024  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
00025  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  */
00028 
00034 #include "config.h"
00035 #include "util/log.h"
00036 #include "util/util.h"
00037 
00038 #include <ldns/ldns.h> /* ldns_*() */
00039 
00040 
00045 int
00046 util_is_dnssec_rr(ldns_rr* rr)
00047 {
00048     ldns_rr_type type = 0;
00049     se_log_assert(rr);
00050 
00051     type = ldns_rr_get_type(rr);
00052     return (type == LDNS_RR_TYPE_RRSIG ||
00053             type == LDNS_RR_TYPE_NSEC ||
00054             type == LDNS_RR_TYPE_NSEC3 ||
00055             type == LDNS_RR_TYPE_NSEC3PARAMS);
00056 }
00057 
00058 
00063 int
00064 util_soa_compare_rdata(ldns_rr* rr1, ldns_rr* rr2)
00065 {
00066     size_t i = 0;
00067     size_t rdata_count = SE_SOA_RDATA_MINIMUM;
00068 
00069     for (i = 0; i <= rdata_count; i++) {
00070         if (i != SE_SOA_RDATA_SERIAL &&
00071             ldns_rdf_compare(ldns_rr_rdf(rr1, i), ldns_rr_rdf(rr2, i)) != 0) {
00072                 return 1;
00073         }
00074     }
00075     return 0;
00076 }
00077 
00078 
00083 int
00084 util_soa_compare(ldns_rr* rr1, ldns_rr* rr2)
00085 {
00086     size_t rr1_len = 0;
00087     size_t rr2_len = 0;
00088     size_t offset = 0;
00089 
00090     se_log_assert(rr1);
00091     se_log_assert(rr2);
00092 
00093     rr1_len = ldns_rr_uncompressed_size(rr1);
00094     rr2_len = ldns_rr_uncompressed_size(rr2);
00095     if (ldns_dname_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)) != 0) {
00096         return 1;
00097     }
00098     if (ldns_rr_get_class(rr1) != ldns_rr_get_class(rr2)) {
00099         return 1;
00100     }
00101     if (ldns_rr_get_type(rr1) != LDNS_RR_TYPE_SOA) {
00102         return 1;
00103     }
00104     if (ldns_rr_get_type(rr1) != ldns_rr_get_type(rr2)) {
00105         return 1;
00106     }
00107     if (offset > rr1_len || offset > rr2_len) {
00108         if (rr1_len == rr2_len) {
00109             return util_soa_compare_rdata(rr1, rr2);
00110         }
00111         return 1;
00112     }
00113 
00114     return util_soa_compare_rdata(rr1, rr2);
00115 }
00116 
00117 
00118 
00123 ldns_status
00124 util_dnssec_rrs_compare(ldns_rr* rr1, ldns_rr* rr2, int* cmp)
00125 {
00126     ldns_status status = LDNS_STATUS_OK;
00127     size_t rr1_len = ldns_rr_uncompressed_size(rr1);
00128     size_t rr2_len = ldns_rr_uncompressed_size(rr2);
00129     ldns_buffer* rr1_buf = ldns_buffer_new(rr1_len);
00130     ldns_buffer* rr2_buf = ldns_buffer_new(rr2_len);
00131 
00132     /* name, class and type should already be equal */
00133     status = ldns_rr2buffer_wire_canonical(rr1_buf, rr1, LDNS_SECTION_ANY);
00134     if (status != LDNS_STATUS_OK) {
00135         ldns_buffer_free(rr1_buf);
00136         ldns_buffer_free(rr2_buf);
00137         /* critical */
00138         return status;
00139     }
00140     status = ldns_rr2buffer_wire_canonical(rr2_buf, rr2, LDNS_SECTION_ANY);
00141     if (status != LDNS_STATUS_OK) {
00142         ldns_buffer_free(rr1_buf);
00143         ldns_buffer_free(rr2_buf);
00144         /* critical */
00145         return status;
00146     }
00147     *cmp = ldns_rr_compare_wire(rr1_buf, rr2_buf);
00148     ldns_buffer_free(rr1_buf);
00149     ldns_buffer_free(rr2_buf);
00150     return LDNS_STATUS_OK;
00151 }
00152 
00153 
00158 ldns_status
00159 util_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr)
00160 {
00161     int cmp = 0;
00162     ldns_dnssec_rrs *new_rrs = NULL;
00163     ldns_status status = LDNS_STATUS_OK;
00164     uint32_t rr_ttl = 0;
00165     uint32_t default_ttl = 0;
00166 
00167     se_log_assert(rrs);
00168     se_log_assert(rrs->rr);
00169     se_log_assert(rr);
00170 
00171     rr_ttl = ldns_rr_ttl(rr);
00172     status = util_dnssec_rrs_compare(rrs->rr, rr, &cmp);
00173     if (status != LDNS_STATUS_OK) {
00174         /* critical */
00175         return status;
00176     }
00177 
00178     if (cmp < 0) {
00179         if (rrs->next) {
00180             return util_dnssec_rrs_add_rr(rrs->next, rr);
00181         } else {
00182             new_rrs = ldns_dnssec_rrs_new();
00183             new_rrs->rr = rr;
00184             rrs->next = new_rrs;
00185             default_ttl = ldns_rr_ttl(rrs->rr);
00186             if (rr_ttl < default_ttl) {
00187                 ldns_rr_set_ttl(rrs->rr, rr_ttl);
00188             } else {
00189                 ldns_rr_set_ttl(new_rrs->rr, default_ttl);
00190             }
00191             return LDNS_STATUS_OK;
00192         }
00193     } else if (cmp > 0) {
00194         /* put the current old rr in the new next, put the new
00195            rr in the current container */
00196         new_rrs = ldns_dnssec_rrs_new();
00197         new_rrs->rr = rrs->rr;
00198         new_rrs->next = rrs->next;
00199 
00200         rrs->rr = rr;
00201         rrs->next = new_rrs;
00202 
00203         default_ttl = ldns_rr_ttl(new_rrs->rr);
00204         if (rr_ttl < default_ttl) {
00205             ldns_rr_set_ttl(new_rrs->rr, rr_ttl);
00206         } else {
00207             ldns_rr_set_ttl(rrs->rr, default_ttl);
00208         }
00209 
00210         return LDNS_STATUS_OK;
00211     } else {
00212         /* should we error on equal? or free memory of rr */
00213         se_log_warning("adding duplicate RR?");
00214         return LDNS_STATUS_NO_DATA;
00215     }
00216     return LDNS_STATUS_OK;
00217 }