Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
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
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
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
00212
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
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 }