OpenDNSSEC-signer 1.3.0rc3
|
00001 /* 00002 * $Id: util.c 5227 2011-06-12 08:51:24Z 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 "shared/file.h" 00036 #include "shared/log.h" 00037 #include "shared/util.h" 00038 00039 #include <time.h> 00040 #include <ldns/ldns.h> 00041 00042 static const char* util_str = "util"; 00043 00044 00049 int 00050 util_is_dnssec_rr(ldns_rr* rr) 00051 { 00052 ldns_rr_type type = 0; 00053 00054 if (!rr) { 00055 return 0; 00056 } 00057 00058 type = ldns_rr_get_type(rr); 00059 return (type == LDNS_RR_TYPE_RRSIG || 00060 type == LDNS_RR_TYPE_NSEC || 00061 type == LDNS_RR_TYPE_NSEC3 || 00062 type == LDNS_RR_TYPE_NSEC3PARAMS); 00063 } 00064 00065 00070 int 00071 util_soa_compare_rdata(ldns_rr* rr1, ldns_rr* rr2) 00072 { 00073 size_t i = 0; 00074 size_t rdata_count = SE_SOA_RDATA_MINIMUM; 00075 00076 for (i = 0; i <= rdata_count; i++) { 00077 if (i != SE_SOA_RDATA_SERIAL && 00078 ldns_rdf_compare(ldns_rr_rdf(rr1, i), ldns_rr_rdf(rr2, i)) != 0) { 00079 return 1; 00080 } 00081 } 00082 return 0; 00083 } 00084 00085 00090 int 00091 util_soa_compare(ldns_rr* rr1, ldns_rr* rr2) 00092 { 00093 size_t rr1_len = 0; 00094 size_t rr2_len = 0; 00095 size_t offset = 0; 00096 00097 if (!rr1 || !rr2) { 00098 return 1; 00099 } 00100 00101 rr1_len = ldns_rr_uncompressed_size(rr1); 00102 rr2_len = ldns_rr_uncompressed_size(rr2); 00103 if (ldns_dname_compare(ldns_rr_owner(rr1), ldns_rr_owner(rr2)) != 0) { 00104 return 1; 00105 } 00106 if (ldns_rr_get_class(rr1) != ldns_rr_get_class(rr2)) { 00107 return 1; 00108 } 00109 if (ldns_rr_get_type(rr1) != LDNS_RR_TYPE_SOA) { 00110 return 1; 00111 } 00112 if (ldns_rr_get_type(rr1) != ldns_rr_get_type(rr2)) { 00113 return 1; 00114 } 00115 if (offset > rr1_len || offset > rr2_len) { 00116 if (rr1_len == rr2_len) { 00117 return util_soa_compare_rdata(rr1, rr2); 00118 } 00119 return 1; 00120 } 00121 00122 return util_soa_compare_rdata(rr1, rr2); 00123 } 00124 00125 00126 00131 ldns_status 00132 util_dnssec_rrs_compare(ldns_rr* rr1, ldns_rr* rr2, int* cmp) 00133 { 00134 ldns_status status = LDNS_STATUS_OK; 00135 size_t rr1_len; 00136 size_t rr2_len; 00137 ldns_buffer* rr1_buf; 00138 ldns_buffer* rr2_buf; 00139 00140 if (!rr1 || !rr2) { 00141 return LDNS_STATUS_ERR; 00142 } 00143 00144 rr1_len = ldns_rr_uncompressed_size(rr1); 00145 rr2_len = ldns_rr_uncompressed_size(rr2); 00146 rr1_buf = ldns_buffer_new(rr1_len); 00147 rr2_buf = ldns_buffer_new(rr2_len); 00148 00149 /* name, class and type should already be equal */ 00150 status = ldns_rr2buffer_wire_canonical(rr1_buf, rr1, LDNS_SECTION_ANY); 00151 if (status != LDNS_STATUS_OK) { 00152 ldns_buffer_free(rr1_buf); 00153 ldns_buffer_free(rr2_buf); 00154 /* critical */ 00155 return status; 00156 } 00157 status = ldns_rr2buffer_wire_canonical(rr2_buf, rr2, LDNS_SECTION_ANY); 00158 if (status != LDNS_STATUS_OK) { 00159 ldns_buffer_free(rr1_buf); 00160 ldns_buffer_free(rr2_buf); 00161 /* critical */ 00162 return status; 00163 } 00164 *cmp = ldns_rr_compare_wire(rr1_buf, rr2_buf); 00165 ldns_buffer_free(rr1_buf); 00166 ldns_buffer_free(rr2_buf); 00167 return LDNS_STATUS_OK; 00168 } 00169 00170 00175 ldns_status 00176 util_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr) 00177 { 00178 int cmp = 0; 00179 ldns_dnssec_rrs *new_rrs = NULL; 00180 ldns_status status = LDNS_STATUS_OK; 00181 uint32_t rr_ttl = 0; 00182 uint32_t default_ttl = 0; 00183 00184 if (!rrs || !rrs->rr || !rr) { 00185 return LDNS_STATUS_ERR; 00186 } 00187 00188 rr_ttl = ldns_rr_ttl(rr); 00189 status = util_dnssec_rrs_compare(rrs->rr, rr, &cmp); 00190 if (status != LDNS_STATUS_OK) { 00191 /* critical */ 00192 return status; 00193 } 00194 00195 if (cmp < 0) { 00196 if (rrs->next) { 00197 return util_dnssec_rrs_add_rr(rrs->next, rr); 00198 } else { 00199 new_rrs = ldns_dnssec_rrs_new(); 00200 new_rrs->rr = rr; 00201 rrs->next = new_rrs; 00202 default_ttl = ldns_rr_ttl(rrs->rr); 00203 if (rr_ttl < default_ttl) { 00204 ldns_rr_set_ttl(rrs->rr, rr_ttl); 00205 } else { 00206 ldns_rr_set_ttl(new_rrs->rr, default_ttl); 00207 } 00208 return LDNS_STATUS_OK; 00209 } 00210 } else if (cmp > 0) { 00211 /* put the current old rr in the new next, put the new 00212 rr in the current container */ 00213 new_rrs = ldns_dnssec_rrs_new(); 00214 new_rrs->rr = rrs->rr; 00215 new_rrs->next = rrs->next; 00216 00217 rrs->rr = rr; 00218 rrs->next = new_rrs; 00219 00220 default_ttl = ldns_rr_ttl(new_rrs->rr); 00221 if (rr_ttl < default_ttl) { 00222 ldns_rr_set_ttl(new_rrs->rr, rr_ttl); 00223 } else { 00224 ldns_rr_set_ttl(rrs->rr, default_ttl); 00225 } 00226 00227 return LDNS_STATUS_OK; 00228 } else { 00229 /* should we error on equal? or free memory of rr */ 00230 ods_log_warning("[%s] adding duplicate RR?", util_str); 00231 return LDNS_STATUS_NO_DATA; 00232 } 00233 return LDNS_STATUS_OK; 00234 } 00235 00236 00241 int 00242 util_write_pidfile(const char* pidfile, pid_t pid) 00243 { 00244 FILE* fd; 00245 char pidbuf[32]; 00246 size_t result = 0, size = 0; 00247 00248 ods_log_assert(pidfile); 00249 ods_log_assert(pid); 00250 ods_log_debug("[%s] writing pid %lu to pidfile %s", util_str, 00251 (unsigned long) pid, pidfile); 00252 snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long) pid); 00253 fd = ods_fopen(pidfile, NULL, "w"); 00254 if (!fd) { 00255 return -1; 00256 } 00257 size = strlen(pidbuf); 00258 if (size == 0) { 00259 result = 1; 00260 } else { 00261 result = fwrite((const void*) pidbuf, 1, size, fd); 00262 } 00263 if (result == 0) { 00264 ods_log_error("[%s] write to pidfile %s failed: %s", util_str, 00265 pidfile, strerror(errno)); 00266 } else if (result < size) { 00267 ods_log_error("[%s] short write to pidfile %s: disk full?", util_str, 00268 pidfile); 00269 result = 0; 00270 } else { 00271 result = 1; 00272 } 00273 ods_fclose(fd); 00274 if (!result) { 00275 return -1; 00276 } 00277 return 0; 00278 }