OpenDNSSEC-signer  2.0.2
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_cleanup(part_type* part)
78 {
79  if (!part) {
80  return;
81  }
82  ldns_rr_list_deep_free(part->min);
83  ldns_rr_list_free(part->plus);
84  free(part);
85 }
86 
87 
92 ixfr_type*
94 {
95  size_t i = 0;
96  ixfr_type* xfr = NULL;
97 
98  ods_log_assert(zone);
99  ods_log_assert(zone->name);
100 
101  CHECKALLOC(xfr = (ixfr_type*) malloc(sizeof(ixfr_type)));
102  if (!xfr) {
103  ods_log_error("[%s] unable to create ixfr for zone %s: "
104  "allocator_alloc() failed", ixfr_str, zone->name);
105  return NULL;
106  }
107  for (i=0; i < IXFR_MAX_PARTS; i++) {
108  xfr->part[i] = NULL;
109  }
110  xfr->zone = zone;
111  lock_basic_init(&xfr->ixfr_lock);
112  return xfr;
113 }
114 
115 
120 void
121 ixfr_add_rr(ixfr_type* ixfr, ldns_rr* rr)
122 {
123  zone_type* zone = NULL;
124  if (!ixfr || !rr) {
125  return;
126  }
127  zone = (zone_type*) ixfr->zone;
128  ods_log_assert(zone);
129  ods_log_assert(zone->db);
130  if (!zone->db->is_initialized) {
131  /* no ixfr yet */
132  return;
133  }
134  ods_log_assert(ixfr->part[0]);
135  ods_log_assert(ixfr->part[0]->plus);
136  if (!ldns_rr_list_push_rr(ixfr->part[0]->plus, rr)) {
137  ods_fatal_exit("[%s] fatal unable to +RR: ldns_rr_list_push_rr() failed",
138  ixfr_str);
139  }
140  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
141  ixfr->part[0]->soaplus = rr;
142  }
143 }
144 
145 
150 void
151 ixfr_del_rr(ixfr_type* ixfr, ldns_rr* rr)
152 {
153  zone_type* zone = NULL;
154  if (!ixfr || !rr) {
155  return;
156  }
157  zone = (zone_type*) ixfr->zone;
158  ods_log_assert(zone);
159  ods_log_assert(zone->db);
160  if (!zone->db->is_initialized) {
161  /* no ixfr yet */
162  return;
163  }
164  ods_log_assert(ixfr->part[0]);
165  ods_log_assert(ixfr->part[0]->min);
166  if (!ldns_rr_list_push_rr(ixfr->part[0]->min, rr)) {
167  ods_fatal_exit("[%s] fatal unable to -RR: ldns_rr_list_push_rr() failed",
168  ixfr_str);
169  }
170  if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) {
171  ixfr->part[0]->soamin = rr;
172  }
173 }
174 
175 
180 static int
181 part_rr_list_print_nonsoa(FILE* fd, ldns_rr_list* list)
182 {
183  size_t i = 0;
184  int error = 0;
185  if (!list || !fd) {
186  return 1;
187  }
188  for (i = 0; i < ldns_rr_list_rr_count(list); i++) {
189  if (ldns_rr_get_type(ldns_rr_list_rr(list, i)) != LDNS_RR_TYPE_SOA) {
190  if (util_rr_print(fd, ldns_rr_list_rr(list, i)) != ODS_STATUS_OK) {
191  error = 1;
192  }
193  }
194  }
195  return error;
196 }
197 
198 
203 static void
204 part_print(FILE* fd, ixfr_type* ixfr, size_t i)
205 {
206  zone_type* zone = NULL;
207  part_type* part = NULL;
208  int error = 0;
209  if (!ixfr || !fd) {
210  return;
211  }
212  zone = (zone_type*) ixfr->zone;
213  part = ixfr->part[i];
214  if (!part || !part->soamin || !part->soaplus) {
215  return;
216  }
217  ods_log_assert(part->min);
218  ods_log_assert(part->plus);
219  ods_log_assert(part->soamin);
220  ods_log_assert(part->soaplus);
221  if (util_rr_print(fd, part->soamin) != ODS_STATUS_OK) {
222  zone->adoutbound->error = 1;
223  }
224  error = part_rr_list_print_nonsoa(fd, part->min);
225  if (error) {
226  zone->adoutbound->error = 1;
227  }
228  if (util_rr_print(fd, part->soaplus) != ODS_STATUS_OK) {
229  zone->adoutbound->error = 1;
230  }
231  error = part_rr_list_print_nonsoa(fd, part->plus);
232  if (error) {
233  zone->adoutbound->error = 1;
234  }
235 }
236 
237 
242 void
243 ixfr_print(FILE* fd, ixfr_type* ixfr)
244 {
245  int i = 0;
246  if (!ixfr || !fd) {
247  return;
248  }
249  ods_log_debug("[%s] print ixfr", ixfr_str);
250  for (i = IXFR_MAX_PARTS - 1; i >= 0; i--) {
251  ods_log_deeebug("[%s] print ixfr part #%d", ixfr_str, i);
252  part_print(fd, ixfr, i);
253  }
254 }
255 
256 
261 void
263 {
264  int i = 0;
265  zone_type* zone = NULL;
266  if (!ixfr) {
267  return;
268  }
269 
270  if (ixfr->part[0] &&
271  (!ixfr->part[0]->soamin || !ixfr->part[0]->soaplus))
272  {
273  /* Somehow the signer does a double purge without having used
274  * this part. There is no need to create a new one. In fact,
275  * we should not. It would cause an assertion later on when
276  * printing to file */
277  return;
278  }
279 
280  zone = (zone_type*) ixfr->zone;
281  ods_log_assert(zone);
282  ods_log_debug("[%s] purge ixfr for zone %s", ixfr_str, zone->name);
283  for (i = IXFR_MAX_PARTS - 1; i >= 0; i--) {
284  if (i == (IXFR_MAX_PARTS - 1)) {
285  part_cleanup(ixfr->part[i]);
286  ixfr->part[i] = NULL;
287  } else {
288  ixfr->part[i+1] = ixfr->part[i];
289  ixfr->part[i] = NULL;
290  }
291  }
292  ixfr->part[0] = part_create();
293  if (!ixfr->part[0]) {
294  ods_fatal_exit("[%s] fatal unable to purge ixfr for zone %s: "
295  "part_create() failed", ixfr_str, zone->name);
296  }
297 }
298 
299 
304 void
306 {
307  int i = 0;
308  if (!ixfr) {
309  return;
310  }
311  for (i = IXFR_MAX_PARTS - 1; i >= 0; i--) {
312  part_cleanup(ixfr->part[i]);
313  }
314  lock_basic_destroy(&ixfr->ixfr_lock);
315  free(ixfr);
316 }
void ixfr_cleanup(ixfr_type *ixfr)
Definition: ixfr.c:305
void ixfr_print(FILE *fd, ixfr_type *ixfr)
Definition: ixfr.c:243
ixfr_type * ixfr_create(zone_type *zone)
Definition: ixfr.c:93
void ixfr_add_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:121
void ixfr_del_rr(ixfr_type *ixfr, ldns_rr *rr)
Definition: ixfr.c:151
unsigned error
Definition: adapter.h:63
part_type * part[IXFR_MAX_PARTS]
Definition: ixfr.h:63
ldns_rr_list * plus
Definition: ixfr.h:54
#define IXFR_MAX_PARTS
Definition: ixfr.h:44
adapter_type * adoutbound
Definition: zone.h:73
ldns_rr * soamin
Definition: ixfr.h:51
zone_type * zone
Definition: ixfr.h:62
namedb_type * db
Definition: zone.h:77
ldns_rr * soaplus
Definition: ixfr.h:53
unsigned is_initialized
Definition: namedb.h:57
query_state ixfr(query_type *q, engine_type *engine)
Definition: axfr.c:389
lock_basic_type ixfr_lock
Definition: ixfr.h:64
const char * name
Definition: zone.h:67
void ixfr_purge(ixfr_type *ixfr)
Definition: ixfr.c:262
ldns_rr_list * min
Definition: ixfr.h:52