OpenDNSSEC-signer 1.2.1
|
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 }