OpenDNSSEC-signer  2.1.7
ixfr.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009 NLNet Labs. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
19  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
21  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
22  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
23  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  */
26 
32 #include "config.h"
33 #include "util.h"
34 #include "signer/ixfr.h"
35 #include "signer/rrset.h"
36 #include "signer/zone.h"
37 
38 static const char* ixfr_str = "journal";
39 
40 
45 static part_type*
46 part_create()
47 {
48  part_type* part = NULL;
49 
50  CHECKALLOC(part = (part_type*) malloc(sizeof(part_type)));
51  part->soaplus = NULL;
52  part->soamin = NULL;
53  part->plus = ldns_rr_list_new();
54  if (!part->plus) {
55  ods_log_error("[%s] unable to create ixfr part: "
56  "ldns_rr_list_new() failed", ixfr_str);
57  free(part);
58  return NULL;
59  }
60  part->min = ldns_rr_list_new();
61  if (!part->min) {
62  ods_log_error("[%s] unable to create ixfr part: "
63  "ldns_rr_list_new() failed", ixfr_str);
64  ldns_rr_list_free(part->plus);
65  free(part);
66  return NULL;
67  }
68  return part;
69 }
70 
71 
76 static void
77 part_free(part_type* part)
78 {
79  if (!part) return;
80  ldns_rr_list_deep_free(part->min);
81  ldns_rr_list_deep_free(part->plus);
82  free(part);
83 }
84 
85 
90 ixfr_type*
92 {
93  size_t i = 0;
94  ixfr_type* xfr;
95 
96  CHECKALLOC(xfr = (ixfr_type*) calloc(1, sizeof(ixfr_type)));
97  pthread_mutex_init(&xfr->ixfr_lock, NULL);
98  return xfr;
99 }
100 
101 
106 void
107 ixfr_add_rr(ixfr_type* ixfr, ldns_rr* rr)
108 {
109  ldns_rr* rr_copy = ldns_rr_clone(rr);
110 
111  ods_log_assert(ixfr)
112  ods_log_assert(rr);
113  ods_log_assert(ixfr->part[0]);
114  ods_log_assert(ixfr->part[0]->plus);
115 
116  if (!ldns_rr_list_push_rr(ixfr->part[0]->plus, rr_copy)) {
117  ldns_rr_free(rr_copy);
118  ods_fatal_exit("[%s] fatal unable to +RR: ldns_rr_list_push_rr() failed",
119  ixfr_str);
120  }
121  if (ldns_rr_get_type(rr_copy) == LDNS_RR_TYPE_SOA) {
122  ixfr->part[0]->soaplus = rr_copy;
123  }
124 }
125 
126 
131 void
132 ixfr_del_rr(ixfr_type* ixfr, ldns_rr* rr)
133 {
134  ldns_rr* rr_copy = ldns_rr_clone(rr);
135 
136  ods_log_assert(ixfr)
137  ods_log_assert(rr);
138  ods_log_assert(ixfr->part[0]);
139  ods_log_assert(ixfr->part[0]->min);
140 
141  if (!ldns_rr_list_push_rr(ixfr->part[0]->min, rr_copy)) {
142  ldns_rr_free(rr_copy);
143  ods_fatal_exit("[%s] fatal unable to -RR: ldns_rr_list_push_rr() failed",
144  ixfr_str);
145  }
146  if (ldns_rr_get_type(rr_copy) == LDNS_RR_TYPE_SOA) {
147  ixfr->part[0]->soamin = rr_copy;
148  }
149 }
150 
151 
156 static int
157 part_rr_list_print_nonsoa(FILE* fd, ldns_rr_list* list)
158 {
159  size_t i = 0;
160  int error = 0;
161  if (!list || !fd) {
162  return 1;
163  }
164  for (i = 0; i < ldns_rr_list_rr_count(list); i++) {
165  if (ldns_rr_get_type(ldns_rr_list_rr(list, i)) != LDNS_RR_TYPE_SOA) {
166  if (util_rr_print(fd, ldns_rr_list_rr(list, i)) != ODS_STATUS_OK) {
167  error = 1;
168  }
169  }
170  }
171  return error;
172 }
173 
174 
179 static int
180 part_print(FILE* fd, ixfr_type* ixfr, size_t i)
181 {
182  part_type* part = NULL;
183  int error = 0;
184 
185  ods_log_assert(ixfr);
186  ods_log_assert(fd);
187 
188  part = ixfr->part[i];
189  if (!part || !part->soamin || !part->soaplus) {
190  return 0; /* due to code buggyness this is not considered an
191  error condition*/
192  }
193  ods_log_assert(part->min);
194  ods_log_assert(part->plus);
195  ods_log_assert(part->soamin);
196  ods_log_assert(part->soaplus);
197 
198  if (util_rr_print(fd, part->soamin) != ODS_STATUS_OK) {
199  return 1;
200  } else if (part_rr_list_print_nonsoa(fd, part->min)) {
201  return 1;
202  } else if (util_rr_print(fd, part->soaplus) != ODS_STATUS_OK) {
203  return 1;
204  } else if (part_rr_list_print_nonsoa(fd, part->plus)) {
205  return 1;
206  }
207  return 0;
208 }
209 
210 
215 int
217 {
218  int i = 0, error = 0;
219 
220  ods_log_assert(fd);
221  ods_log_assert(ixfr);
222 
223  ods_log_debug("[%s] print ixfr", ixfr_str);
224  for (i = IXFR_MAX_PARTS - 1; i >= 0; i--) {
225  ods_log_deeebug("[%s] print ixfr part #%d", ixfr_str, i);
226  if (part_print(fd, ixfr, i)) {
227  return 1;
228  }
229  }
230  return 0;
231 }
232 
233 
238 void
239 ixfr_purge(ixfr_type* ixfr, char const *zonename)
240 {
241  int i = 0;
242 
243  ods_log_assert(ixfr);
244  ods_log_assert(zonename);
245 
246  if (ixfr->part[0] &&
247  (!ixfr->part[0]->soamin || !ixfr->part[0]->soaplus))
248  {
249  /* Somehow the signer does a double purge without having used
250  * this part. There is no need to create a new one. In fact,
251  * we should not. It would cause an assertion later on when
252  * printing to file */
253  return;
254  }
255 
256  ods_log_debug("[%s] purge ixfr for zone %s", ixfr_str, zonename);
257  for (i = IXFR_MAX_PARTS - 1; i >= 0; i--) {
258  if (i == (IXFR_MAX_PARTS - 1)) {
259  part_free(ixfr->part[i]);
260  ixfr->part[i] = NULL;
261  } else {
262  ixfr->part[i+1] = ixfr->part[i];
263  ixfr->part[i] = NULL;
264  }
265  }
266  ixfr->part[0] = part_create();
267  if (!ixfr->part[0]) {
268  ods_fatal_exit("[%s] fatal unable to purge ixfr for zone %s: "
269  "part_create() failed", ixfr_str, zonename);
270  }
271 }
272 
273 
278 void
280 {
281  int i = 0;
282  if (!ixfr) {
283  return;
284  }
285  for (i = IXFR_MAX_PARTS - 1; i >= 0; i--) {
286  part_free(ixfr->part[i]);
287  }
288  pthread_mutex_destroy(&ixfr->ixfr_lock);
289  free(ixfr);
290 }
query_state ixfr(query_type *q, engine_type *engine)
Definition: axfr.c:389
void ixfr_purge(ixfr_type *ixfr, char const *zonename)
Definition: ixfr.c:239
int ixfr_print(FILE *fd, ixfr_type *ixfr)
Definition: ixfr.c:216
ixfr_type * ixfr_create()
Definition: ixfr.c:91
void ixfr_del_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:132
void ixfr_cleanup(ixfr_type *ixfr)
Definition: ixfr.c:279
void ixfr_add_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:107
#define IXFR_MAX_PARTS
Definition: ixfr.h:44
pthread_mutex_t ixfr_lock
Definition: ixfr.h:64
ldns_rr_list * plus
Definition: ixfr.h:55
ldns_rr * soamin
Definition: ixfr.h:52
ldns_rr_list * min
Definition: ixfr.h:53
ldns_rr * soaplus
Definition: ixfr.h:54