line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/* |
2
|
|
|
|
|
|
|
* special zone file structures and functions for better dnssec handling |
3
|
|
|
|
|
|
|
*/ |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
#include |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
#include |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
ldns_dnssec_rrs * |
10
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_new(void) |
11
|
|
|
|
|
|
|
{ |
12
|
|
|
|
|
|
|
ldns_dnssec_rrs *new_rrs; |
13
|
0
|
|
|
|
|
|
new_rrs = LDNS_MALLOC(ldns_dnssec_rrs); |
14
|
0
|
0
|
|
|
|
|
if(!new_rrs) return NULL; |
15
|
0
|
|
|
|
|
|
new_rrs->rr = NULL; |
16
|
0
|
|
|
|
|
|
new_rrs->next = NULL; |
17
|
0
|
|
|
|
|
|
return new_rrs; |
18
|
|
|
|
|
|
|
} |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
INLINE void |
21
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_free_internal(ldns_dnssec_rrs *rrs, int deep) |
22
|
|
|
|
|
|
|
{ |
23
|
|
|
|
|
|
|
ldns_dnssec_rrs *next; |
24
|
0
|
0
|
|
|
|
|
while (rrs) { |
25
|
0
|
|
|
|
|
|
next = rrs->next; |
26
|
0
|
0
|
|
|
|
|
if (deep) { |
27
|
0
|
|
|
|
|
|
ldns_rr_free(rrs->rr); |
28
|
|
|
|
|
|
|
} |
29
|
0
|
|
|
|
|
|
LDNS_FREE(rrs); |
30
|
0
|
|
|
|
|
|
rrs = next; |
31
|
|
|
|
|
|
|
} |
32
|
0
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
void |
35
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_free(ldns_dnssec_rrs *rrs) |
36
|
|
|
|
|
|
|
{ |
37
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_free_internal(rrs, 0); |
38
|
0
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
void |
41
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_deep_free(ldns_dnssec_rrs *rrs) |
42
|
|
|
|
|
|
|
{ |
43
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_free_internal(rrs, 1); |
44
|
0
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
ldns_status |
47
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_add_rr(ldns_dnssec_rrs *rrs, ldns_rr *rr) |
48
|
|
|
|
|
|
|
{ |
49
|
|
|
|
|
|
|
int cmp; |
50
|
|
|
|
|
|
|
ldns_dnssec_rrs *new_rrs; |
51
|
0
|
0
|
|
|
|
|
if (!rrs || !rr) { |
|
|
0
|
|
|
|
|
|
52
|
0
|
|
|
|
|
|
return LDNS_STATUS_ERR; |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
/* this could be done more efficiently; name and type should already |
56
|
|
|
|
|
|
|
be equal */ |
57
|
0
|
|
|
|
|
|
cmp = ldns_rr_compare(rrs->rr, rr); |
58
|
0
|
0
|
|
|
|
|
if (cmp < 0) { |
59
|
0
|
0
|
|
|
|
|
if (rrs->next) { |
60
|
0
|
|
|
|
|
|
return ldns_dnssec_rrs_add_rr(rrs->next, rr); |
61
|
|
|
|
|
|
|
} else { |
62
|
0
|
|
|
|
|
|
new_rrs = ldns_dnssec_rrs_new(); |
63
|
0
|
|
|
|
|
|
new_rrs->rr = rr; |
64
|
0
|
|
|
|
|
|
rrs->next = new_rrs; |
65
|
|
|
|
|
|
|
} |
66
|
0
|
0
|
|
|
|
|
} else if (cmp > 0) { |
67
|
|
|
|
|
|
|
/* put the current old rr in the new next, put the new |
68
|
|
|
|
|
|
|
rr in the current container */ |
69
|
0
|
|
|
|
|
|
new_rrs = ldns_dnssec_rrs_new(); |
70
|
0
|
|
|
|
|
|
new_rrs->rr = rrs->rr; |
71
|
0
|
|
|
|
|
|
new_rrs->next = rrs->next; |
72
|
0
|
|
|
|
|
|
rrs->rr = rr; |
73
|
0
|
|
|
|
|
|
rrs->next = new_rrs; |
74
|
|
|
|
|
|
|
} |
75
|
|
|
|
|
|
|
/* Silently ignore equal rr's */ |
76
|
0
|
|
|
|
|
|
return LDNS_STATUS_OK; |
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
void |
80
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_print_fmt(FILE *out, const ldns_output_format *fmt, |
81
|
|
|
|
|
|
|
ldns_dnssec_rrs *rrs) |
82
|
|
|
|
|
|
|
{ |
83
|
0
|
0
|
|
|
|
|
if (!rrs) { |
84
|
0
|
0
|
|
|
|
|
if ((fmt->flags & LDNS_COMMENT_LAYOUT)) |
85
|
0
|
|
|
|
|
|
fprintf(out, "; "); |
86
|
|
|
|
|
|
|
} else { |
87
|
0
|
0
|
|
|
|
|
if (rrs->rr) { |
88
|
0
|
|
|
|
|
|
ldns_rr_print_fmt(out, fmt, rrs->rr); |
89
|
|
|
|
|
|
|
} |
90
|
0
|
0
|
|
|
|
|
if (rrs->next) { |
91
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_print_fmt(out, fmt, rrs->next); |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
} |
94
|
0
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
void |
97
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_print(FILE *out, ldns_dnssec_rrs *rrs) |
98
|
|
|
|
|
|
|
{ |
99
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_print_fmt(out, ldns_output_format_default, rrs); |
100
|
0
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
ldns_dnssec_rrsets * |
104
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_new(void) |
105
|
|
|
|
|
|
|
{ |
106
|
|
|
|
|
|
|
ldns_dnssec_rrsets *new_rrsets; |
107
|
0
|
|
|
|
|
|
new_rrsets = LDNS_MALLOC(ldns_dnssec_rrsets); |
108
|
0
|
0
|
|
|
|
|
if(!new_rrsets) return NULL; |
109
|
0
|
|
|
|
|
|
new_rrsets->rrs = NULL; |
110
|
0
|
|
|
|
|
|
new_rrsets->type = 0; |
111
|
0
|
|
|
|
|
|
new_rrsets->signatures = NULL; |
112
|
0
|
|
|
|
|
|
new_rrsets->next = NULL; |
113
|
0
|
|
|
|
|
|
return new_rrsets; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
INLINE void |
117
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_free_internal(ldns_dnssec_rrsets *rrsets, int deep) |
118
|
|
|
|
|
|
|
{ |
119
|
0
|
0
|
|
|
|
|
if (rrsets) { |
120
|
0
|
0
|
|
|
|
|
if (rrsets->rrs) { |
121
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_free_internal(rrsets->rrs, deep); |
122
|
|
|
|
|
|
|
} |
123
|
0
|
0
|
|
|
|
|
if (rrsets->next) { |
124
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_free_internal(rrsets->next, deep); |
125
|
|
|
|
|
|
|
} |
126
|
0
|
0
|
|
|
|
|
if (rrsets->signatures) { |
127
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_free_internal(rrsets->signatures, deep); |
128
|
|
|
|
|
|
|
} |
129
|
0
|
|
|
|
|
|
LDNS_FREE(rrsets); |
130
|
|
|
|
|
|
|
} |
131
|
0
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
void |
134
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_free(ldns_dnssec_rrsets *rrsets) |
135
|
|
|
|
|
|
|
{ |
136
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_free_internal(rrsets, 0); |
137
|
0
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
void |
140
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_deep_free(ldns_dnssec_rrsets *rrsets) |
141
|
|
|
|
|
|
|
{ |
142
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_free_internal(rrsets, 1); |
143
|
0
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
ldns_rr_type |
146
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_type(ldns_dnssec_rrsets *rrsets) |
147
|
|
|
|
|
|
|
{ |
148
|
0
|
0
|
|
|
|
|
if (rrsets) { |
149
|
0
|
|
|
|
|
|
return rrsets->type; |
150
|
|
|
|
|
|
|
} else { |
151
|
0
|
|
|
|
|
|
return 0; |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
} |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
ldns_status |
156
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_set_type(ldns_dnssec_rrsets *rrsets, |
157
|
|
|
|
|
|
|
ldns_rr_type type) |
158
|
|
|
|
|
|
|
{ |
159
|
0
|
0
|
|
|
|
|
if (rrsets) { |
160
|
0
|
|
|
|
|
|
rrsets->type = type; |
161
|
0
|
|
|
|
|
|
return LDNS_STATUS_OK; |
162
|
|
|
|
|
|
|
} |
163
|
0
|
|
|
|
|
|
return LDNS_STATUS_ERR; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
static ldns_dnssec_rrsets * |
167
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_new_frm_rr(ldns_rr *rr) |
168
|
|
|
|
|
|
|
{ |
169
|
|
|
|
|
|
|
ldns_dnssec_rrsets *new_rrsets; |
170
|
|
|
|
|
|
|
ldns_rr_type rr_type; |
171
|
|
|
|
|
|
|
bool rrsig; |
172
|
|
|
|
|
|
|
|
173
|
0
|
|
|
|
|
|
new_rrsets = ldns_dnssec_rrsets_new(); |
174
|
0
|
|
|
|
|
|
rr_type = ldns_rr_get_type(rr); |
175
|
0
|
0
|
|
|
|
|
if (rr_type == LDNS_RR_TYPE_RRSIG) { |
176
|
0
|
|
|
|
|
|
rrsig = true; |
177
|
0
|
|
|
|
|
|
rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); |
178
|
|
|
|
|
|
|
} else { |
179
|
0
|
|
|
|
|
|
rrsig = false; |
180
|
|
|
|
|
|
|
} |
181
|
0
|
0
|
|
|
|
|
if (!rrsig) { |
182
|
0
|
|
|
|
|
|
new_rrsets->rrs = ldns_dnssec_rrs_new(); |
183
|
0
|
|
|
|
|
|
new_rrsets->rrs->rr = rr; |
184
|
|
|
|
|
|
|
} else { |
185
|
0
|
|
|
|
|
|
new_rrsets->signatures = ldns_dnssec_rrs_new(); |
186
|
0
|
|
|
|
|
|
new_rrsets->signatures->rr = rr; |
187
|
|
|
|
|
|
|
} |
188
|
0
|
|
|
|
|
|
new_rrsets->type = rr_type; |
189
|
0
|
|
|
|
|
|
return new_rrsets; |
190
|
|
|
|
|
|
|
} |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
ldns_status |
193
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_add_rr(ldns_dnssec_rrsets *rrsets, ldns_rr *rr) |
194
|
|
|
|
|
|
|
{ |
195
|
|
|
|
|
|
|
ldns_dnssec_rrsets *new_rrsets; |
196
|
|
|
|
|
|
|
ldns_rr_type rr_type; |
197
|
0
|
|
|
|
|
|
bool rrsig = false; |
198
|
0
|
|
|
|
|
|
ldns_status result = LDNS_STATUS_OK; |
199
|
|
|
|
|
|
|
|
200
|
0
|
0
|
|
|
|
|
if (!rrsets || !rr) { |
|
|
0
|
|
|
|
|
|
201
|
0
|
|
|
|
|
|
return LDNS_STATUS_ERR; |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
0
|
|
|
|
|
|
rr_type = ldns_rr_get_type(rr); |
205
|
|
|
|
|
|
|
|
206
|
0
|
0
|
|
|
|
|
if (rr_type == LDNS_RR_TYPE_RRSIG) { |
207
|
0
|
|
|
|
|
|
rrsig = true; |
208
|
0
|
|
|
|
|
|
rr_type = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); |
209
|
|
|
|
|
|
|
} |
210
|
|
|
|
|
|
|
|
211
|
0
|
0
|
|
|
|
|
if (!rrsets->rrs && rrsets->type == 0 && !rrsets->signatures) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
212
|
0
|
0
|
|
|
|
|
if (!rrsig) { |
213
|
0
|
|
|
|
|
|
rrsets->rrs = ldns_dnssec_rrs_new(); |
214
|
0
|
|
|
|
|
|
rrsets->rrs->rr = rr; |
215
|
0
|
|
|
|
|
|
rrsets->type = rr_type; |
216
|
|
|
|
|
|
|
} else { |
217
|
0
|
|
|
|
|
|
rrsets->signatures = ldns_dnssec_rrs_new(); |
218
|
0
|
|
|
|
|
|
rrsets->signatures->rr = rr; |
219
|
0
|
|
|
|
|
|
rrsets->type = rr_type; |
220
|
|
|
|
|
|
|
} |
221
|
0
|
|
|
|
|
|
return LDNS_STATUS_OK; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
0
|
0
|
|
|
|
|
if (rr_type > ldns_dnssec_rrsets_type(rrsets)) { |
225
|
0
|
0
|
|
|
|
|
if (rrsets->next) { |
226
|
0
|
|
|
|
|
|
result = ldns_dnssec_rrsets_add_rr(rrsets->next, rr); |
227
|
|
|
|
|
|
|
} else { |
228
|
0
|
|
|
|
|
|
new_rrsets = ldns_dnssec_rrsets_new_frm_rr(rr); |
229
|
0
|
|
|
|
|
|
rrsets->next = new_rrsets; |
230
|
|
|
|
|
|
|
} |
231
|
0
|
0
|
|
|
|
|
} else if (rr_type < ldns_dnssec_rrsets_type(rrsets)) { |
232
|
|
|
|
|
|
|
/* move the current one into the new next, |
233
|
|
|
|
|
|
|
replace field of current with data from new rr */ |
234
|
0
|
|
|
|
|
|
new_rrsets = ldns_dnssec_rrsets_new(); |
235
|
0
|
|
|
|
|
|
new_rrsets->rrs = rrsets->rrs; |
236
|
0
|
|
|
|
|
|
new_rrsets->type = rrsets->type; |
237
|
0
|
|
|
|
|
|
new_rrsets->signatures = rrsets->signatures; |
238
|
0
|
|
|
|
|
|
new_rrsets->next = rrsets->next; |
239
|
0
|
0
|
|
|
|
|
if (!rrsig) { |
240
|
0
|
|
|
|
|
|
rrsets->rrs = ldns_dnssec_rrs_new(); |
241
|
0
|
|
|
|
|
|
rrsets->rrs->rr = rr; |
242
|
0
|
|
|
|
|
|
rrsets->signatures = NULL; |
243
|
|
|
|
|
|
|
} else { |
244
|
0
|
|
|
|
|
|
rrsets->rrs = NULL; |
245
|
0
|
|
|
|
|
|
rrsets->signatures = ldns_dnssec_rrs_new(); |
246
|
0
|
|
|
|
|
|
rrsets->signatures->rr = rr; |
247
|
|
|
|
|
|
|
} |
248
|
0
|
|
|
|
|
|
rrsets->type = rr_type; |
249
|
0
|
|
|
|
|
|
rrsets->next = new_rrsets; |
250
|
|
|
|
|
|
|
} else { |
251
|
|
|
|
|
|
|
/* equal, add to current rrsets */ |
252
|
0
|
0
|
|
|
|
|
if (rrsig) { |
253
|
0
|
0
|
|
|
|
|
if (rrsets->signatures) { |
254
|
0
|
|
|
|
|
|
result = ldns_dnssec_rrs_add_rr(rrsets->signatures, rr); |
255
|
|
|
|
|
|
|
} else { |
256
|
0
|
|
|
|
|
|
rrsets->signatures = ldns_dnssec_rrs_new(); |
257
|
0
|
|
|
|
|
|
rrsets->signatures->rr = rr; |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
} else { |
260
|
0
|
0
|
|
|
|
|
if (rrsets->rrs) { |
261
|
0
|
|
|
|
|
|
result = ldns_dnssec_rrs_add_rr(rrsets->rrs, rr); |
262
|
|
|
|
|
|
|
} else { |
263
|
0
|
|
|
|
|
|
rrsets->rrs = ldns_dnssec_rrs_new(); |
264
|
0
|
|
|
|
|
|
rrsets->rrs->rr = rr; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
} |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
0
|
|
|
|
|
|
return result; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
static void |
273
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_print_soa_fmt(FILE *out, const ldns_output_format *fmt, |
274
|
|
|
|
|
|
|
ldns_dnssec_rrsets *rrsets, |
275
|
|
|
|
|
|
|
bool follow, |
276
|
|
|
|
|
|
|
bool show_soa) |
277
|
|
|
|
|
|
|
{ |
278
|
0
|
0
|
|
|
|
|
if (!rrsets) { |
279
|
0
|
0
|
|
|
|
|
if ((fmt->flags & LDNS_COMMENT_LAYOUT)) |
280
|
0
|
|
|
|
|
|
fprintf(out, "; \n"); |
281
|
|
|
|
|
|
|
} else { |
282
|
0
|
0
|
|
|
|
|
if (rrsets->rrs && |
|
|
0
|
|
|
|
|
|
283
|
0
|
0
|
|
|
|
|
(show_soa || |
284
|
0
|
|
|
|
|
|
ldns_rr_get_type(rrsets->rrs->rr) != LDNS_RR_TYPE_SOA |
285
|
|
|
|
|
|
|
) |
286
|
|
|
|
|
|
|
) { |
287
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_print_fmt(out, fmt, rrsets->rrs); |
288
|
0
|
0
|
|
|
|
|
if (rrsets->signatures) { |
289
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_print_fmt(out, fmt, |
290
|
|
|
|
|
|
|
rrsets->signatures); |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
} |
293
|
0
|
0
|
|
|
|
|
if (follow && rrsets->next) { |
|
|
0
|
|
|
|
|
|
294
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_print_soa_fmt(out, fmt, |
295
|
|
|
|
|
|
|
rrsets->next, follow, show_soa); |
296
|
|
|
|
|
|
|
} |
297
|
|
|
|
|
|
|
} |
298
|
0
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
void |
302
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_print_fmt(FILE *out, const ldns_output_format *fmt, |
303
|
|
|
|
|
|
|
ldns_dnssec_rrsets *rrsets, |
304
|
|
|
|
|
|
|
bool follow) |
305
|
|
|
|
|
|
|
{ |
306
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_print_soa_fmt(out, fmt, rrsets, follow, true); |
307
|
0
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
void |
310
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_print(FILE *out, ldns_dnssec_rrsets *rrsets, bool follow) |
311
|
|
|
|
|
|
|
{ |
312
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_print_fmt(out, ldns_output_format_default, |
313
|
|
|
|
|
|
|
rrsets, follow); |
314
|
0
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
|
316
|
|
|
|
|
|
|
ldns_dnssec_name * |
317
|
0
|
|
|
|
|
|
ldns_dnssec_name_new(void) |
318
|
|
|
|
|
|
|
{ |
319
|
|
|
|
|
|
|
ldns_dnssec_name *new_name; |
320
|
|
|
|
|
|
|
|
321
|
0
|
|
|
|
|
|
new_name = LDNS_CALLOC(ldns_dnssec_name, 1); |
322
|
0
|
0
|
|
|
|
|
if (!new_name) { |
323
|
0
|
|
|
|
|
|
return NULL; |
324
|
|
|
|
|
|
|
} |
325
|
|
|
|
|
|
|
/* |
326
|
|
|
|
|
|
|
* not needed anymore because CALLOC initalizes everything to zero. |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
new_name->name = NULL; |
329
|
|
|
|
|
|
|
new_name->rrsets = NULL; |
330
|
|
|
|
|
|
|
new_name->name_alloced = false; |
331
|
|
|
|
|
|
|
new_name->nsec = NULL; |
332
|
|
|
|
|
|
|
new_name->nsec_signatures = NULL; |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
new_name->is_glue = false; |
335
|
|
|
|
|
|
|
new_name->hashed_name = NULL; |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
*/ |
338
|
0
|
|
|
|
|
|
return new_name; |
339
|
|
|
|
|
|
|
} |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
ldns_dnssec_name * |
342
|
0
|
|
|
|
|
|
ldns_dnssec_name_new_frm_rr(ldns_rr *rr) |
343
|
|
|
|
|
|
|
{ |
344
|
0
|
|
|
|
|
|
ldns_dnssec_name *new_name = ldns_dnssec_name_new(); |
345
|
|
|
|
|
|
|
|
346
|
0
|
|
|
|
|
|
new_name->name = ldns_rr_owner(rr); |
347
|
0
|
0
|
|
|
|
|
if(ldns_dnssec_name_add_rr(new_name, rr) != LDNS_STATUS_OK) { |
348
|
0
|
|
|
|
|
|
ldns_dnssec_name_free(new_name); |
349
|
0
|
|
|
|
|
|
return NULL; |
350
|
|
|
|
|
|
|
} |
351
|
|
|
|
|
|
|
|
352
|
0
|
|
|
|
|
|
return new_name; |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
INLINE void |
356
|
0
|
|
|
|
|
|
ldns_dnssec_name_free_internal(ldns_dnssec_name *name, |
357
|
|
|
|
|
|
|
int deep) |
358
|
|
|
|
|
|
|
{ |
359
|
0
|
0
|
|
|
|
|
if (name) { |
360
|
0
|
0
|
|
|
|
|
if (name->name_alloced) { |
361
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(name->name); |
362
|
|
|
|
|
|
|
} |
363
|
0
|
0
|
|
|
|
|
if (name->rrsets) { |
364
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_free_internal(name->rrsets, deep); |
365
|
|
|
|
|
|
|
} |
366
|
0
|
0
|
|
|
|
|
if (name->nsec && deep) { |
|
|
0
|
|
|
|
|
|
367
|
0
|
|
|
|
|
|
ldns_rr_free(name->nsec); |
368
|
|
|
|
|
|
|
} |
369
|
0
|
0
|
|
|
|
|
if (name->nsec_signatures) { |
370
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep); |
371
|
|
|
|
|
|
|
} |
372
|
0
|
0
|
|
|
|
|
if (name->hashed_name) { |
373
|
0
|
0
|
|
|
|
|
if (deep) { |
374
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(name->hashed_name); |
375
|
|
|
|
|
|
|
} |
376
|
|
|
|
|
|
|
} |
377
|
0
|
|
|
|
|
|
LDNS_FREE(name); |
378
|
|
|
|
|
|
|
} |
379
|
0
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
void |
382
|
0
|
|
|
|
|
|
ldns_dnssec_name_free(ldns_dnssec_name *name) |
383
|
|
|
|
|
|
|
{ |
384
|
0
|
|
|
|
|
|
ldns_dnssec_name_free_internal(name, 0); |
385
|
0
|
|
|
|
|
|
} |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
void |
388
|
0
|
|
|
|
|
|
ldns_dnssec_name_deep_free(ldns_dnssec_name *name) |
389
|
|
|
|
|
|
|
{ |
390
|
0
|
|
|
|
|
|
ldns_dnssec_name_free_internal(name, 1); |
391
|
0
|
|
|
|
|
|
} |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
ldns_rdf * |
394
|
0
|
|
|
|
|
|
ldns_dnssec_name_name(ldns_dnssec_name *name) |
395
|
|
|
|
|
|
|
{ |
396
|
0
|
0
|
|
|
|
|
if (name) { |
397
|
0
|
|
|
|
|
|
return name->name; |
398
|
|
|
|
|
|
|
} |
399
|
0
|
|
|
|
|
|
return NULL; |
400
|
|
|
|
|
|
|
} |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
bool |
403
|
0
|
|
|
|
|
|
ldns_dnssec_name_is_glue(ldns_dnssec_name *name) |
404
|
|
|
|
|
|
|
{ |
405
|
0
|
0
|
|
|
|
|
if (name) { |
406
|
0
|
|
|
|
|
|
return name->is_glue; |
407
|
|
|
|
|
|
|
} |
408
|
0
|
|
|
|
|
|
return false; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
void |
412
|
0
|
|
|
|
|
|
ldns_dnssec_name_set_name(ldns_dnssec_name *rrset, |
413
|
|
|
|
|
|
|
ldns_rdf *dname) |
414
|
|
|
|
|
|
|
{ |
415
|
0
|
0
|
|
|
|
|
if (rrset && dname) { |
|
|
0
|
|
|
|
|
|
416
|
0
|
|
|
|
|
|
rrset->name = dname; |
417
|
|
|
|
|
|
|
} |
418
|
0
|
|
|
|
|
|
} |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
void |
422
|
0
|
|
|
|
|
|
ldns_dnssec_name_set_nsec(ldns_dnssec_name *rrset, ldns_rr *nsec) |
423
|
|
|
|
|
|
|
{ |
424
|
0
|
0
|
|
|
|
|
if (rrset && nsec) { |
|
|
0
|
|
|
|
|
|
425
|
0
|
|
|
|
|
|
rrset->nsec = nsec; |
426
|
|
|
|
|
|
|
} |
427
|
0
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
int |
430
|
0
|
|
|
|
|
|
ldns_dnssec_name_cmp(const void *a, const void *b) |
431
|
|
|
|
|
|
|
{ |
432
|
0
|
|
|
|
|
|
ldns_dnssec_name *na = (ldns_dnssec_name *) a; |
433
|
0
|
|
|
|
|
|
ldns_dnssec_name *nb = (ldns_dnssec_name *) b; |
434
|
|
|
|
|
|
|
|
435
|
0
|
0
|
|
|
|
|
if (na && nb) { |
|
|
0
|
|
|
|
|
|
436
|
0
|
|
|
|
|
|
return ldns_dname_compare(ldns_dnssec_name_name(na), |
437
|
0
|
|
|
|
|
|
ldns_dnssec_name_name(nb)); |
438
|
0
|
0
|
|
|
|
|
} else if (na) { |
439
|
0
|
|
|
|
|
|
return 1; |
440
|
0
|
0
|
|
|
|
|
} else if (nb) { |
441
|
0
|
|
|
|
|
|
return -1; |
442
|
|
|
|
|
|
|
} else { |
443
|
0
|
|
|
|
|
|
return 0; |
444
|
|
|
|
|
|
|
} |
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
ldns_status |
448
|
0
|
|
|
|
|
|
ldns_dnssec_name_add_rr(ldns_dnssec_name *name, |
449
|
|
|
|
|
|
|
ldns_rr *rr) |
450
|
|
|
|
|
|
|
{ |
451
|
0
|
|
|
|
|
|
ldns_status result = LDNS_STATUS_OK; |
452
|
|
|
|
|
|
|
ldns_rr_type rr_type; |
453
|
0
|
|
|
|
|
|
ldns_rr_type typecovered = 0; |
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
/* special handling for NSEC3 and NSECX covering RRSIGS */ |
456
|
|
|
|
|
|
|
|
457
|
0
|
0
|
|
|
|
|
if (!name || !rr) { |
|
|
0
|
|
|
|
|
|
458
|
0
|
|
|
|
|
|
return LDNS_STATUS_ERR; |
459
|
|
|
|
|
|
|
} |
460
|
|
|
|
|
|
|
|
461
|
0
|
|
|
|
|
|
rr_type = ldns_rr_get_type(rr); |
462
|
|
|
|
|
|
|
|
463
|
0
|
0
|
|
|
|
|
if (rr_type == LDNS_RR_TYPE_RRSIG) { |
464
|
0
|
|
|
|
|
|
typecovered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); |
465
|
|
|
|
|
|
|
} |
466
|
|
|
|
|
|
|
|
467
|
0
|
0
|
|
|
|
|
if (rr_type == LDNS_RR_TYPE_NSEC || |
|
|
0
|
|
|
|
|
|
468
|
|
|
|
|
|
|
rr_type == LDNS_RR_TYPE_NSEC3) { |
469
|
|
|
|
|
|
|
/* XX check if is already set (and error?) */ |
470
|
0
|
|
|
|
|
|
name->nsec = rr; |
471
|
0
|
0
|
|
|
|
|
} else if (typecovered == LDNS_RR_TYPE_NSEC || |
|
|
0
|
|
|
|
|
|
472
|
|
|
|
|
|
|
typecovered == LDNS_RR_TYPE_NSEC3) { |
473
|
0
|
0
|
|
|
|
|
if (name->nsec_signatures) { |
474
|
0
|
|
|
|
|
|
result = ldns_dnssec_rrs_add_rr(name->nsec_signatures, rr); |
475
|
|
|
|
|
|
|
} else { |
476
|
0
|
|
|
|
|
|
name->nsec_signatures = ldns_dnssec_rrs_new(); |
477
|
0
|
|
|
|
|
|
name->nsec_signatures->rr = rr; |
478
|
|
|
|
|
|
|
} |
479
|
|
|
|
|
|
|
} else { |
480
|
|
|
|
|
|
|
/* it's a 'normal' RR, add it to the right rrset */ |
481
|
0
|
0
|
|
|
|
|
if (name->rrsets) { |
482
|
0
|
|
|
|
|
|
result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); |
483
|
|
|
|
|
|
|
} else { |
484
|
0
|
|
|
|
|
|
name->rrsets = ldns_dnssec_rrsets_new(); |
485
|
0
|
|
|
|
|
|
result = ldns_dnssec_rrsets_add_rr(name->rrsets, rr); |
486
|
|
|
|
|
|
|
} |
487
|
|
|
|
|
|
|
} |
488
|
0
|
|
|
|
|
|
return result; |
489
|
|
|
|
|
|
|
} |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
ldns_dnssec_rrsets * |
492
|
0
|
|
|
|
|
|
ldns_dnssec_name_find_rrset(ldns_dnssec_name *name, |
493
|
|
|
|
|
|
|
ldns_rr_type type) { |
494
|
|
|
|
|
|
|
ldns_dnssec_rrsets *result; |
495
|
|
|
|
|
|
|
|
496
|
0
|
|
|
|
|
|
result = name->rrsets; |
497
|
0
|
0
|
|
|
|
|
while (result) { |
498
|
0
|
0
|
|
|
|
|
if (result->type == type) { |
499
|
0
|
|
|
|
|
|
return result; |
500
|
|
|
|
|
|
|
} else { |
501
|
0
|
|
|
|
|
|
result = result->next; |
502
|
|
|
|
|
|
|
} |
503
|
|
|
|
|
|
|
} |
504
|
0
|
|
|
|
|
|
return NULL; |
505
|
|
|
|
|
|
|
} |
506
|
|
|
|
|
|
|
|
507
|
|
|
|
|
|
|
ldns_dnssec_rrsets * |
508
|
0
|
|
|
|
|
|
ldns_dnssec_zone_find_rrset(ldns_dnssec_zone *zone, |
509
|
|
|
|
|
|
|
ldns_rdf *dname, |
510
|
|
|
|
|
|
|
ldns_rr_type type) |
511
|
|
|
|
|
|
|
{ |
512
|
|
|
|
|
|
|
ldns_rbnode_t *node; |
513
|
|
|
|
|
|
|
|
514
|
0
|
0
|
|
|
|
|
if (!zone || !dname || !zone->names) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
515
|
0
|
|
|
|
|
|
return NULL; |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
0
|
|
|
|
|
|
node = ldns_rbtree_search(zone->names, dname); |
519
|
0
|
0
|
|
|
|
|
if (node) { |
520
|
0
|
|
|
|
|
|
return ldns_dnssec_name_find_rrset((ldns_dnssec_name *)node->data, |
521
|
|
|
|
|
|
|
type); |
522
|
|
|
|
|
|
|
} else { |
523
|
0
|
|
|
|
|
|
return NULL; |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
} |
526
|
|
|
|
|
|
|
|
527
|
|
|
|
|
|
|
static void |
528
|
0
|
|
|
|
|
|
ldns_dnssec_name_print_soa_fmt(FILE *out, const ldns_output_format *fmt, |
529
|
|
|
|
|
|
|
ldns_dnssec_name *name, |
530
|
|
|
|
|
|
|
bool show_soa) |
531
|
|
|
|
|
|
|
{ |
532
|
0
|
0
|
|
|
|
|
if (name) { |
533
|
0
|
0
|
|
|
|
|
if(name->rrsets) { |
534
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_print_soa_fmt(out, fmt, |
535
|
|
|
|
|
|
|
name->rrsets, true, show_soa); |
536
|
0
|
0
|
|
|
|
|
} else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { |
537
|
0
|
|
|
|
|
|
fprintf(out, ";; Empty nonterminal: "); |
538
|
0
|
|
|
|
|
|
ldns_rdf_print(out, name->name); |
539
|
0
|
|
|
|
|
|
fprintf(out, "\n"); |
540
|
|
|
|
|
|
|
} |
541
|
0
|
0
|
|
|
|
|
if(name->nsec) { |
542
|
0
|
|
|
|
|
|
ldns_rr_print_fmt(out, fmt, name->nsec); |
543
|
|
|
|
|
|
|
} |
544
|
0
|
0
|
|
|
|
|
if (name->nsec_signatures) { |
545
|
0
|
|
|
|
|
|
ldns_dnssec_rrs_print_fmt(out, fmt, |
546
|
|
|
|
|
|
|
name->nsec_signatures); |
547
|
|
|
|
|
|
|
} |
548
|
0
|
0
|
|
|
|
|
} else if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { |
549
|
0
|
|
|
|
|
|
fprintf(out, "; \n"); |
550
|
|
|
|
|
|
|
} |
551
|
0
|
|
|
|
|
|
} |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
void |
555
|
0
|
|
|
|
|
|
ldns_dnssec_name_print_fmt(FILE *out, const ldns_output_format *fmt, |
556
|
|
|
|
|
|
|
ldns_dnssec_name *name) |
557
|
|
|
|
|
|
|
{ |
558
|
0
|
|
|
|
|
|
ldns_dnssec_name_print_soa_fmt(out, fmt, name, true); |
559
|
0
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
void |
562
|
0
|
|
|
|
|
|
ldns_dnssec_name_print(FILE *out, ldns_dnssec_name *name) |
563
|
|
|
|
|
|
|
{ |
564
|
0
|
|
|
|
|
|
ldns_dnssec_name_print_fmt(out, ldns_output_format_default, name); |
565
|
0
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
ldns_dnssec_zone * |
569
|
0
|
|
|
|
|
|
ldns_dnssec_zone_new(void) |
570
|
|
|
|
|
|
|
{ |
571
|
0
|
|
|
|
|
|
ldns_dnssec_zone *zone = LDNS_MALLOC(ldns_dnssec_zone); |
572
|
0
|
0
|
|
|
|
|
if(!zone) return NULL; |
573
|
0
|
|
|
|
|
|
zone->soa = NULL; |
574
|
0
|
|
|
|
|
|
zone->names = NULL; |
575
|
0
|
|
|
|
|
|
zone->hashed_names = NULL; |
576
|
0
|
|
|
|
|
|
zone->_nsec3params = NULL; |
577
|
|
|
|
|
|
|
|
578
|
0
|
|
|
|
|
|
return zone; |
579
|
|
|
|
|
|
|
} |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
static bool |
582
|
0
|
|
|
|
|
|
rr_is_rrsig_covering(ldns_rr* rr, ldns_rr_type t) |
583
|
|
|
|
|
|
|
{ |
584
|
0
|
|
|
|
|
|
return ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG |
585
|
0
|
0
|
|
|
|
|
&& ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)) == t; |
|
|
0
|
|
|
|
|
|
586
|
|
|
|
|
|
|
} |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
/* When the zone is first read into an list and then inserted into an |
589
|
|
|
|
|
|
|
* ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next) |
590
|
|
|
|
|
|
|
* to each other. Because ldns-verify-zone (the only program that uses this |
591
|
|
|
|
|
|
|
* function) uses the rbtree mostly for sequentual walking, this results |
592
|
|
|
|
|
|
|
* in a speed increase (of 15% on linux) because we have less CPU-cache misses. |
593
|
|
|
|
|
|
|
*/ |
594
|
|
|
|
|
|
|
#define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */ |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
static ldns_status |
597
|
|
|
|
|
|
|
ldns_dnssec_zone_add_empty_nonterminals_nsec3( |
598
|
|
|
|
|
|
|
ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s); |
599
|
|
|
|
|
|
|
|
600
|
|
|
|
|
|
|
static void |
601
|
0
|
|
|
|
|
|
ldns_todo_nsec3_ents_node_free(ldns_rbnode_t *node, void *arg) { |
602
|
|
|
|
|
|
|
(void) arg; |
603
|
0
|
|
|
|
|
|
ldns_rdf_deep_free((ldns_rdf *)node->key); |
604
|
0
|
|
|
|
|
|
LDNS_FREE(node); |
605
|
0
|
|
|
|
|
|
} |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
ldns_status |
608
|
0
|
|
|
|
|
|
ldns_dnssec_zone_new_frm_fp_l(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, |
609
|
|
|
|
|
|
|
uint32_t ttl, ldns_rr_class ATTR_UNUSED(c), int* line_nr) |
610
|
|
|
|
|
|
|
{ |
611
|
|
|
|
|
|
|
ldns_rr* cur_rr; |
612
|
|
|
|
|
|
|
size_t i; |
613
|
|
|
|
|
|
|
|
614
|
0
|
|
|
|
|
|
ldns_rdf *my_origin = NULL; |
615
|
0
|
|
|
|
|
|
ldns_rdf *my_prev = NULL; |
616
|
|
|
|
|
|
|
|
617
|
0
|
|
|
|
|
|
ldns_dnssec_zone *newzone = ldns_dnssec_zone_new(); |
618
|
|
|
|
|
|
|
/* NSEC3s may occur before the names they refer to. We must remember |
619
|
|
|
|
|
|
|
them and add them to the name later on, after the name is read. |
620
|
|
|
|
|
|
|
We track not yet matching NSEC3s*n the todo_nsec3s list */ |
621
|
0
|
|
|
|
|
|
ldns_rr_list* todo_nsec3s = ldns_rr_list_new(); |
622
|
|
|
|
|
|
|
/* when reading NSEC3s, there is a chance that we encounter nsecs |
623
|
|
|
|
|
|
|
for empty nonterminals, whose nonterminals we cannot derive yet |
624
|
|
|
|
|
|
|
because the needed information is to be read later. |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
nsec3_ents (where ent is e.n.t.; i.e. empty non terminal) will |
627
|
|
|
|
|
|
|
hold the NSEC3s that still didn't have a matching name in the |
628
|
|
|
|
|
|
|
zone tree, even after all names were read. They can only match |
629
|
|
|
|
|
|
|
after the zone is equiped with all the empty non terminals. */ |
630
|
|
|
|
|
|
|
ldns_rbtree_t todo_nsec3_ents; |
631
|
|
|
|
|
|
|
ldns_rbnode_t *new_node; |
632
|
0
|
|
|
|
|
|
ldns_rr_list* todo_nsec3_rrsigs = ldns_rr_list_new(); |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
ldns_status status; |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP |
637
|
0
|
|
|
|
|
|
ldns_zone* zone = NULL; |
638
|
|
|
|
|
|
|
#else |
639
|
|
|
|
|
|
|
uint32_t my_ttl = ttl; |
640
|
|
|
|
|
|
|
#endif |
641
|
|
|
|
|
|
|
|
642
|
0
|
|
|
|
|
|
ldns_rbtree_init(&todo_nsec3_ents, ldns_dname_compare_v); |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP |
645
|
0
|
|
|
|
|
|
status = ldns_zone_new_frm_fp_l(&zone, fp, origin,ttl, c, line_nr); |
646
|
0
|
0
|
|
|
|
|
if (status != LDNS_STATUS_OK) |
647
|
0
|
|
|
|
|
|
goto error; |
648
|
|
|
|
|
|
|
#endif |
649
|
0
|
0
|
|
|
|
|
if (!newzone || !todo_nsec3s || !todo_nsec3_rrsigs ) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
650
|
0
|
|
|
|
|
|
status = LDNS_STATUS_MEM_ERR; |
651
|
0
|
|
|
|
|
|
goto error; |
652
|
|
|
|
|
|
|
} |
653
|
0
|
0
|
|
|
|
|
if (origin) { |
654
|
0
|
0
|
|
|
|
|
if (!(my_origin = ldns_rdf_clone(origin))) { |
655
|
0
|
|
|
|
|
|
status = LDNS_STATUS_MEM_ERR; |
656
|
0
|
|
|
|
|
|
goto error; |
657
|
|
|
|
|
|
|
} |
658
|
0
|
0
|
|
|
|
|
if (!(my_prev = ldns_rdf_clone(origin))) { |
659
|
0
|
|
|
|
|
|
status = LDNS_STATUS_MEM_ERR; |
660
|
0
|
|
|
|
|
|
goto error; |
661
|
|
|
|
|
|
|
} |
662
|
|
|
|
|
|
|
} |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP |
665
|
0
|
0
|
|
|
|
|
if (ldns_zone_soa(zone)) { |
666
|
0
|
|
|
|
|
|
status = ldns_dnssec_zone_add_rr(newzone, ldns_zone_soa(zone)); |
667
|
0
|
0
|
|
|
|
|
if (status != LDNS_STATUS_OK) |
668
|
0
|
|
|
|
|
|
goto error; |
669
|
|
|
|
|
|
|
} |
670
|
0
|
0
|
|
|
|
|
for (i = 0; i < ldns_rr_list_rr_count(ldns_zone_rrs(zone)); i++) { |
671
|
0
|
|
|
|
|
|
cur_rr = ldns_rr_list_rr(ldns_zone_rrs(zone), i); |
672
|
0
|
|
|
|
|
|
status = LDNS_STATUS_OK; |
673
|
|
|
|
|
|
|
#else |
674
|
|
|
|
|
|
|
while (!feof(fp)) { |
675
|
|
|
|
|
|
|
status = ldns_rr_new_frm_fp_l(&cur_rr, fp, &my_ttl, &my_origin, |
676
|
|
|
|
|
|
|
&my_prev, line_nr); |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
#endif |
679
|
0
|
|
|
|
|
|
switch (status) { |
680
|
|
|
|
|
|
|
case LDNS_STATUS_OK: |
681
|
|
|
|
|
|
|
|
682
|
0
|
|
|
|
|
|
status = ldns_dnssec_zone_add_rr(newzone, cur_rr); |
683
|
0
|
0
|
|
|
|
|
if (status == |
684
|
|
|
|
|
|
|
LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) { |
685
|
|
|
|
|
|
|
|
686
|
0
|
0
|
|
|
|
|
if (rr_is_rrsig_covering(cur_rr, |
687
|
|
|
|
|
|
|
LDNS_RR_TYPE_NSEC3)){ |
688
|
0
|
|
|
|
|
|
ldns_rr_list_push_rr(todo_nsec3_rrsigs, |
689
|
|
|
|
|
|
|
cur_rr); |
690
|
|
|
|
|
|
|
} else { |
691
|
0
|
|
|
|
|
|
ldns_rr_list_push_rr(todo_nsec3s, |
692
|
|
|
|
|
|
|
cur_rr); |
693
|
|
|
|
|
|
|
} |
694
|
0
|
|
|
|
|
|
status = LDNS_STATUS_OK; |
695
|
|
|
|
|
|
|
|
696
|
0
|
0
|
|
|
|
|
} else if (status != LDNS_STATUS_OK) |
697
|
0
|
|
|
|
|
|
goto error; |
698
|
|
|
|
|
|
|
|
699
|
0
|
|
|
|
|
|
break; |
700
|
|
|
|
|
|
|
|
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
case LDNS_STATUS_SYNTAX_EMPTY: /* empty line was seen */ |
703
|
|
|
|
|
|
|
case LDNS_STATUS_SYNTAX_TTL: /* the ttl was set*/ |
704
|
|
|
|
|
|
|
case LDNS_STATUS_SYNTAX_ORIGIN: /* the origin was set*/ |
705
|
0
|
|
|
|
|
|
status = LDNS_STATUS_OK; |
706
|
0
|
|
|
|
|
|
break; |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
case LDNS_STATUS_SYNTAX_INCLUDE:/* $include not implemented */ |
709
|
0
|
|
|
|
|
|
status = LDNS_STATUS_SYNTAX_INCLUDE_ERR_NOTIMPL; |
710
|
0
|
|
|
|
|
|
break; |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
default: |
713
|
0
|
|
|
|
|
|
goto error; |
714
|
|
|
|
|
|
|
} |
715
|
|
|
|
|
|
|
} |
716
|
|
|
|
|
|
|
|
717
|
0
|
|
|
|
|
|
for (i = 0; status == LDNS_STATUS_OK && |
718
|
0
|
|
|
|
|
|
i < ldns_rr_list_rr_count(todo_nsec3s); i++) { |
719
|
0
|
|
|
|
|
|
cur_rr = ldns_rr_list_rr(todo_nsec3s, i); |
720
|
0
|
|
|
|
|
|
status = ldns_dnssec_zone_add_rr(newzone, cur_rr); |
721
|
0
|
0
|
|
|
|
|
if (status == LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND) { |
722
|
0
|
0
|
|
|
|
|
if (!(new_node = LDNS_MALLOC(ldns_rbnode_t))) { |
723
|
0
|
|
|
|
|
|
status = LDNS_STATUS_MEM_ERR; |
724
|
0
|
|
|
|
|
|
break; |
725
|
|
|
|
|
|
|
} |
726
|
0
|
|
|
|
|
|
new_node->key = ldns_dname_label(ldns_rr_owner(cur_rr), 0); |
727
|
0
|
|
|
|
|
|
new_node->data = cur_rr; |
728
|
0
|
0
|
|
|
|
|
if (!ldns_rbtree_insert(&todo_nsec3_ents, new_node)) { |
729
|
0
|
|
|
|
|
|
LDNS_FREE(new_node); |
730
|
0
|
|
|
|
|
|
status = LDNS_STATUS_MEM_ERR; |
731
|
0
|
|
|
|
|
|
break; |
732
|
|
|
|
|
|
|
} |
733
|
0
|
|
|
|
|
|
status = LDNS_STATUS_OK; |
734
|
|
|
|
|
|
|
} |
735
|
|
|
|
|
|
|
} |
736
|
0
|
0
|
|
|
|
|
if (todo_nsec3_ents.count > 0) |
737
|
0
|
|
|
|
|
|
(void) ldns_dnssec_zone_add_empty_nonterminals_nsec3( |
738
|
|
|
|
|
|
|
newzone, &todo_nsec3_ents); |
739
|
0
|
|
|
|
|
|
for (i = 0; status == LDNS_STATUS_OK && |
740
|
0
|
|
|
|
|
|
i < ldns_rr_list_rr_count(todo_nsec3_rrsigs); i++) { |
741
|
0
|
|
|
|
|
|
cur_rr = ldns_rr_list_rr(todo_nsec3_rrsigs, i); |
742
|
0
|
|
|
|
|
|
status = ldns_dnssec_zone_add_rr(newzone, cur_rr); |
743
|
|
|
|
|
|
|
} |
744
|
0
|
0
|
|
|
|
|
if (z) { |
745
|
0
|
|
|
|
|
|
*z = newzone; |
746
|
0
|
|
|
|
|
|
newzone = NULL; |
747
|
|
|
|
|
|
|
} else { |
748
|
0
|
|
|
|
|
|
ldns_dnssec_zone_free(newzone); |
749
|
|
|
|
|
|
|
} |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
error: |
752
|
|
|
|
|
|
|
#ifdef FASTER_DNSSEC_ZONE_NEW_FRM_FP |
753
|
0
|
0
|
|
|
|
|
if (zone) { |
754
|
0
|
|
|
|
|
|
ldns_zone_free(zone); |
755
|
|
|
|
|
|
|
} |
756
|
|
|
|
|
|
|
#endif |
757
|
0
|
|
|
|
|
|
ldns_rr_list_free(todo_nsec3_rrsigs); |
758
|
0
|
|
|
|
|
|
ldns_traverse_postorder(&todo_nsec3_ents, |
759
|
|
|
|
|
|
|
ldns_todo_nsec3_ents_node_free, NULL); |
760
|
0
|
|
|
|
|
|
ldns_rr_list_free(todo_nsec3s); |
761
|
|
|
|
|
|
|
|
762
|
0
|
0
|
|
|
|
|
if (my_origin) { |
763
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(my_origin); |
764
|
|
|
|
|
|
|
} |
765
|
0
|
0
|
|
|
|
|
if (my_prev) { |
766
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(my_prev); |
767
|
|
|
|
|
|
|
} |
768
|
0
|
0
|
|
|
|
|
if (newzone) { |
769
|
0
|
|
|
|
|
|
ldns_dnssec_zone_free(newzone); |
770
|
|
|
|
|
|
|
} |
771
|
0
|
|
|
|
|
|
return status; |
772
|
|
|
|
|
|
|
} |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
ldns_status |
775
|
0
|
|
|
|
|
|
ldns_dnssec_zone_new_frm_fp(ldns_dnssec_zone** z, FILE* fp, ldns_rdf* origin, |
776
|
|
|
|
|
|
|
uint32_t ttl, ldns_rr_class ATTR_UNUSED(c)) |
777
|
|
|
|
|
|
|
{ |
778
|
0
|
|
|
|
|
|
return ldns_dnssec_zone_new_frm_fp_l(z, fp, origin, ttl, c, NULL); |
779
|
|
|
|
|
|
|
} |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
static void |
782
|
0
|
|
|
|
|
|
ldns_dnssec_name_node_free(ldns_rbnode_t *node, void *arg) { |
783
|
|
|
|
|
|
|
(void) arg; |
784
|
0
|
|
|
|
|
|
ldns_dnssec_name_free((ldns_dnssec_name *)node->data); |
785
|
0
|
|
|
|
|
|
LDNS_FREE(node); |
786
|
0
|
|
|
|
|
|
} |
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
static void |
789
|
0
|
|
|
|
|
|
ldns_dnssec_name_node_deep_free(ldns_rbnode_t *node, void *arg) { |
790
|
|
|
|
|
|
|
(void) arg; |
791
|
0
|
|
|
|
|
|
ldns_dnssec_name_deep_free((ldns_dnssec_name *)node->data); |
792
|
0
|
|
|
|
|
|
LDNS_FREE(node); |
793
|
0
|
|
|
|
|
|
} |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
void |
796
|
0
|
|
|
|
|
|
ldns_dnssec_zone_free(ldns_dnssec_zone *zone) |
797
|
|
|
|
|
|
|
{ |
798
|
0
|
0
|
|
|
|
|
if (zone) { |
799
|
0
|
0
|
|
|
|
|
if (zone->names) { |
800
|
|
|
|
|
|
|
/* destroy all name structures within the tree */ |
801
|
0
|
|
|
|
|
|
ldns_traverse_postorder(zone->names, |
802
|
|
|
|
|
|
|
ldns_dnssec_name_node_free, |
803
|
|
|
|
|
|
|
NULL); |
804
|
0
|
|
|
|
|
|
LDNS_FREE(zone->names); |
805
|
|
|
|
|
|
|
} |
806
|
0
|
|
|
|
|
|
LDNS_FREE(zone); |
807
|
|
|
|
|
|
|
} |
808
|
0
|
|
|
|
|
|
} |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
void |
811
|
0
|
|
|
|
|
|
ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone) |
812
|
|
|
|
|
|
|
{ |
813
|
0
|
0
|
|
|
|
|
if (zone) { |
814
|
0
|
0
|
|
|
|
|
if (zone->names) { |
815
|
|
|
|
|
|
|
/* destroy all name structures within the tree */ |
816
|
0
|
|
|
|
|
|
ldns_traverse_postorder(zone->names, |
817
|
|
|
|
|
|
|
ldns_dnssec_name_node_deep_free, |
818
|
|
|
|
|
|
|
NULL); |
819
|
0
|
|
|
|
|
|
LDNS_FREE(zone->names); |
820
|
|
|
|
|
|
|
} |
821
|
0
|
|
|
|
|
|
LDNS_FREE(zone); |
822
|
|
|
|
|
|
|
} |
823
|
0
|
|
|
|
|
|
} |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
/* use for dname comparison in tree */ |
826
|
|
|
|
|
|
|
int |
827
|
0
|
|
|
|
|
|
ldns_dname_compare_v(const void *a, const void *b) { |
828
|
0
|
|
|
|
|
|
return ldns_dname_compare((ldns_rdf *)a, (ldns_rdf *)b); |
829
|
|
|
|
|
|
|
} |
830
|
|
|
|
|
|
|
|
831
|
|
|
|
|
|
|
static void |
832
|
|
|
|
|
|
|
ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone, |
833
|
|
|
|
|
|
|
ldns_dnssec_name* name, ldns_rr* nsec3rr); |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
static void |
836
|
0
|
|
|
|
|
|
ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) { |
837
|
|
|
|
|
|
|
(void) arg; |
838
|
0
|
|
|
|
|
|
LDNS_FREE(node); |
839
|
0
|
|
|
|
|
|
} |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
static void |
842
|
0
|
|
|
|
|
|
ldns_dnssec_zone_hashed_names_from_nsec3( |
843
|
|
|
|
|
|
|
ldns_dnssec_zone* zone, ldns_rr* nsec3rr) |
844
|
|
|
|
|
|
|
{ |
845
|
|
|
|
|
|
|
ldns_rbnode_t* current_node; |
846
|
|
|
|
|
|
|
ldns_dnssec_name* current_name; |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
assert(zone != NULL); |
849
|
|
|
|
|
|
|
assert(nsec3rr != NULL); |
850
|
|
|
|
|
|
|
|
851
|
0
|
0
|
|
|
|
|
if (zone->hashed_names) { |
852
|
0
|
|
|
|
|
|
ldns_traverse_postorder(zone->hashed_names, |
853
|
|
|
|
|
|
|
ldns_hashed_names_node_free, NULL); |
854
|
0
|
|
|
|
|
|
LDNS_FREE(zone->hashed_names); |
855
|
|
|
|
|
|
|
} |
856
|
0
|
|
|
|
|
|
zone->_nsec3params = nsec3rr; |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
/* So this is a NSEC3 zone. |
859
|
|
|
|
|
|
|
* Calculate hashes for all names already in the zone |
860
|
|
|
|
|
|
|
*/ |
861
|
0
|
|
|
|
|
|
zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v); |
862
|
0
|
0
|
|
|
|
|
if (zone->hashed_names == NULL) { |
863
|
0
|
|
|
|
|
|
return; |
864
|
|
|
|
|
|
|
} |
865
|
0
|
0
|
|
|
|
|
for ( current_node = ldns_rbtree_first(zone->names) |
866
|
|
|
|
|
|
|
; current_node != LDNS_RBTREE_NULL |
867
|
0
|
|
|
|
|
|
; current_node = ldns_rbtree_next(current_node) |
868
|
|
|
|
|
|
|
) { |
869
|
0
|
|
|
|
|
|
current_name = (ldns_dnssec_name *) current_node->data; |
870
|
0
|
|
|
|
|
|
ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr); |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
} |
873
|
|
|
|
|
|
|
} |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
static void |
876
|
0
|
|
|
|
|
|
ldns_dnssec_name_make_hashed_name(ldns_dnssec_zone *zone, |
877
|
|
|
|
|
|
|
ldns_dnssec_name* name, ldns_rr* nsec3rr) |
878
|
|
|
|
|
|
|
{ |
879
|
|
|
|
|
|
|
ldns_rbnode_t* new_node; |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
assert(name != NULL); |
882
|
0
|
0
|
|
|
|
|
if (! zone->_nsec3params) { |
883
|
0
|
0
|
|
|
|
|
if (! nsec3rr) { |
884
|
0
|
|
|
|
|
|
return; |
885
|
|
|
|
|
|
|
} |
886
|
0
|
|
|
|
|
|
ldns_dnssec_zone_hashed_names_from_nsec3(zone, nsec3rr); |
887
|
|
|
|
|
|
|
|
888
|
0
|
0
|
|
|
|
|
} else if (! nsec3rr) { |
889
|
0
|
|
|
|
|
|
nsec3rr = zone->_nsec3params; |
890
|
|
|
|
|
|
|
} |
891
|
0
|
|
|
|
|
|
name->hashed_name = ldns_nsec3_hash_name_frm_nsec3(nsec3rr, name->name); |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
/* Also store in zone->hashed_names */ |
894
|
0
|
0
|
|
|
|
|
if ((new_node = LDNS_MALLOC(ldns_rbnode_t))) { |
895
|
|
|
|
|
|
|
|
896
|
0
|
|
|
|
|
|
new_node->key = name->hashed_name; |
897
|
0
|
|
|
|
|
|
new_node->data = name; |
898
|
|
|
|
|
|
|
|
899
|
0
|
0
|
|
|
|
|
if (ldns_rbtree_insert(zone->hashed_names, new_node) == NULL) { |
900
|
|
|
|
|
|
|
|
901
|
0
|
|
|
|
|
|
LDNS_FREE(new_node); |
902
|
|
|
|
|
|
|
} |
903
|
|
|
|
|
|
|
} |
904
|
|
|
|
|
|
|
} |
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
static ldns_rbnode_t * |
908
|
0
|
|
|
|
|
|
ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) { |
909
|
|
|
|
|
|
|
ldns_rdf *hashed_name; |
910
|
|
|
|
|
|
|
|
911
|
0
|
|
|
|
|
|
hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0); |
912
|
0
|
0
|
|
|
|
|
if (hashed_name == NULL) { |
913
|
0
|
|
|
|
|
|
return NULL; |
914
|
|
|
|
|
|
|
} |
915
|
0
|
0
|
|
|
|
|
if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){ |
|
|
0
|
|
|
|
|
|
916
|
|
|
|
|
|
|
|
917
|
0
|
|
|
|
|
|
ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr); |
918
|
|
|
|
|
|
|
} |
919
|
0
|
0
|
|
|
|
|
if (zone->hashed_names == NULL) { |
920
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(hashed_name); |
921
|
0
|
|
|
|
|
|
return NULL; |
922
|
|
|
|
|
|
|
} |
923
|
0
|
|
|
|
|
|
return ldns_rbtree_search(zone->hashed_names, hashed_name); |
924
|
|
|
|
|
|
|
} |
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
ldns_status |
927
|
0
|
|
|
|
|
|
ldns_dnssec_zone_add_rr(ldns_dnssec_zone *zone, ldns_rr *rr) |
928
|
|
|
|
|
|
|
{ |
929
|
0
|
|
|
|
|
|
ldns_status result = LDNS_STATUS_OK; |
930
|
|
|
|
|
|
|
ldns_dnssec_name *cur_name; |
931
|
|
|
|
|
|
|
ldns_rbnode_t *cur_node; |
932
|
0
|
|
|
|
|
|
ldns_rr_type type_covered = 0; |
933
|
|
|
|
|
|
|
|
934
|
0
|
0
|
|
|
|
|
if (!zone || !rr) { |
|
|
0
|
|
|
|
|
|
935
|
0
|
|
|
|
|
|
return LDNS_STATUS_ERR; |
936
|
|
|
|
|
|
|
} |
937
|
|
|
|
|
|
|
|
938
|
0
|
0
|
|
|
|
|
if (!zone->names) { |
939
|
0
|
|
|
|
|
|
zone->names = ldns_rbtree_create(ldns_dname_compare_v); |
940
|
0
|
0
|
|
|
|
|
if(!zone->names) return LDNS_STATUS_MEM_ERR; |
941
|
|
|
|
|
|
|
} |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
/* we need the original of the hashed name if this is |
944
|
|
|
|
|
|
|
an NSEC3, or an RRSIG that covers an NSEC3 */ |
945
|
0
|
0
|
|
|
|
|
if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) { |
946
|
0
|
|
|
|
|
|
type_covered = ldns_rdf2rr_type(ldns_rr_rrsig_typecovered(rr)); |
947
|
|
|
|
|
|
|
} |
948
|
0
|
0
|
|
|
|
|
if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 || |
|
|
0
|
|
|
|
|
|
949
|
|
|
|
|
|
|
type_covered == LDNS_RR_TYPE_NSEC3) { |
950
|
0
|
|
|
|
|
|
cur_node = ldns_dnssec_zone_find_nsec3_original(zone, rr); |
951
|
0
|
0
|
|
|
|
|
if (!cur_node) { |
952
|
0
|
|
|
|
|
|
return LDNS_STATUS_DNSSEC_NSEC3_ORIGINAL_NOT_FOUND; |
953
|
|
|
|
|
|
|
} |
954
|
|
|
|
|
|
|
} else { |
955
|
0
|
|
|
|
|
|
cur_node = ldns_rbtree_search(zone->names, ldns_rr_owner(rr)); |
956
|
|
|
|
|
|
|
} |
957
|
0
|
0
|
|
|
|
|
if (!cur_node) { |
958
|
|
|
|
|
|
|
/* add */ |
959
|
0
|
|
|
|
|
|
cur_name = ldns_dnssec_name_new_frm_rr(rr); |
960
|
0
|
0
|
|
|
|
|
if(!cur_name) return LDNS_STATUS_MEM_ERR; |
961
|
0
|
|
|
|
|
|
cur_node = LDNS_MALLOC(ldns_rbnode_t); |
962
|
0
|
0
|
|
|
|
|
if(!cur_node) { |
963
|
0
|
|
|
|
|
|
ldns_dnssec_name_free(cur_name); |
964
|
0
|
|
|
|
|
|
return LDNS_STATUS_MEM_ERR; |
965
|
|
|
|
|
|
|
} |
966
|
0
|
|
|
|
|
|
cur_node->key = ldns_rr_owner(rr); |
967
|
0
|
|
|
|
|
|
cur_node->data = cur_name; |
968
|
0
|
|
|
|
|
|
(void)ldns_rbtree_insert(zone->names, cur_node); |
969
|
0
|
|
|
|
|
|
ldns_dnssec_name_make_hashed_name(zone, cur_name, NULL); |
970
|
|
|
|
|
|
|
} else { |
971
|
0
|
|
|
|
|
|
cur_name = (ldns_dnssec_name *) cur_node->data; |
972
|
0
|
|
|
|
|
|
result = ldns_dnssec_name_add_rr(cur_name, rr); |
973
|
|
|
|
|
|
|
} |
974
|
0
|
0
|
|
|
|
|
if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_SOA) { |
975
|
0
|
|
|
|
|
|
zone->soa = cur_name; |
976
|
|
|
|
|
|
|
} |
977
|
0
|
|
|
|
|
|
return result; |
978
|
|
|
|
|
|
|
} |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
void |
981
|
0
|
|
|
|
|
|
ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt, |
982
|
|
|
|
|
|
|
ldns_rbtree_t *tree, |
983
|
|
|
|
|
|
|
bool print_soa) |
984
|
|
|
|
|
|
|
{ |
985
|
|
|
|
|
|
|
ldns_rbnode_t *node; |
986
|
|
|
|
|
|
|
ldns_dnssec_name *name; |
987
|
|
|
|
|
|
|
|
988
|
0
|
|
|
|
|
|
node = ldns_rbtree_first(tree); |
989
|
0
|
0
|
|
|
|
|
while (node != LDNS_RBTREE_NULL) { |
990
|
0
|
|
|
|
|
|
name = (ldns_dnssec_name *) node->data; |
991
|
0
|
|
|
|
|
|
ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa); |
992
|
0
|
0
|
|
|
|
|
if ((fmt->flags & LDNS_COMMENT_LAYOUT)) |
993
|
0
|
|
|
|
|
|
fprintf(out, ";\n"); |
994
|
0
|
|
|
|
|
|
node = ldns_rbtree_next(node); |
995
|
|
|
|
|
|
|
} |
996
|
0
|
|
|
|
|
|
} |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
void |
999
|
0
|
|
|
|
|
|
ldns_dnssec_zone_names_print(FILE *out, ldns_rbtree_t *tree, bool print_soa) |
1000
|
|
|
|
|
|
|
{ |
1001
|
0
|
|
|
|
|
|
ldns_dnssec_zone_names_print_fmt(out, ldns_output_format_default, |
1002
|
|
|
|
|
|
|
tree, print_soa); |
1003
|
0
|
|
|
|
|
|
} |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
void |
1006
|
0
|
|
|
|
|
|
ldns_dnssec_zone_print_fmt(FILE *out, const ldns_output_format *fmt, |
1007
|
|
|
|
|
|
|
ldns_dnssec_zone *zone) |
1008
|
|
|
|
|
|
|
{ |
1009
|
0
|
0
|
|
|
|
|
if (zone) { |
1010
|
0
|
0
|
|
|
|
|
if (zone->soa) { |
1011
|
0
|
0
|
|
|
|
|
if ((fmt->flags & LDNS_COMMENT_LAYOUT)) { |
1012
|
0
|
|
|
|
|
|
fprintf(out, ";; Zone: "); |
1013
|
0
|
|
|
|
|
|
ldns_rdf_print(out, ldns_dnssec_name_name( |
1014
|
|
|
|
|
|
|
zone->soa)); |
1015
|
0
|
|
|
|
|
|
fprintf(out, "\n;\n"); |
1016
|
|
|
|
|
|
|
} |
1017
|
0
|
|
|
|
|
|
ldns_dnssec_rrsets_print_fmt(out, fmt, |
1018
|
|
|
|
|
|
|
ldns_dnssec_name_find_rrset( |
1019
|
|
|
|
|
|
|
zone->soa, |
1020
|
|
|
|
|
|
|
LDNS_RR_TYPE_SOA), |
1021
|
|
|
|
|
|
|
false); |
1022
|
0
|
0
|
|
|
|
|
if ((fmt->flags & LDNS_COMMENT_LAYOUT)) |
1023
|
0
|
|
|
|
|
|
fprintf(out, ";\n"); |
1024
|
|
|
|
|
|
|
} |
1025
|
|
|
|
|
|
|
|
1026
|
0
|
0
|
|
|
|
|
if (zone->names) { |
1027
|
0
|
|
|
|
|
|
ldns_dnssec_zone_names_print_fmt(out, fmt, |
1028
|
|
|
|
|
|
|
zone->names, false); |
1029
|
|
|
|
|
|
|
} |
1030
|
|
|
|
|
|
|
} |
1031
|
0
|
|
|
|
|
|
} |
1032
|
|
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
void |
1034
|
0
|
|
|
|
|
|
ldns_dnssec_zone_print(FILE *out, ldns_dnssec_zone *zone) |
1035
|
|
|
|
|
|
|
{ |
1036
|
0
|
|
|
|
|
|
ldns_dnssec_zone_print_fmt(out, ldns_output_format_default, zone); |
1037
|
0
|
|
|
|
|
|
} |
1038
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
static ldns_status |
1040
|
0
|
|
|
|
|
|
ldns_dnssec_zone_add_empty_nonterminals_nsec3( |
1041
|
|
|
|
|
|
|
ldns_dnssec_zone *zone, ldns_rbtree_t *nsec3s) |
1042
|
|
|
|
|
|
|
{ |
1043
|
|
|
|
|
|
|
ldns_dnssec_name *new_name; |
1044
|
|
|
|
|
|
|
ldns_rdf *cur_name; |
1045
|
|
|
|
|
|
|
ldns_rdf *next_name; |
1046
|
|
|
|
|
|
|
ldns_rbnode_t *cur_node, *next_node, *new_node; |
1047
|
|
|
|
|
|
|
|
1048
|
|
|
|
|
|
|
/* for the detection */ |
1049
|
|
|
|
|
|
|
uint16_t i, cur_label_count, next_label_count; |
1050
|
0
|
|
|
|
|
|
uint16_t soa_label_count = 0; |
1051
|
|
|
|
|
|
|
ldns_rdf *l1, *l2; |
1052
|
|
|
|
|
|
|
int lpos; |
1053
|
|
|
|
|
|
|
|
1054
|
0
|
0
|
|
|
|
|
if (!zone) { |
1055
|
0
|
|
|
|
|
|
return LDNS_STATUS_ERR; |
1056
|
|
|
|
|
|
|
} |
1057
|
0
|
0
|
|
|
|
|
if (zone->soa && zone->soa->name) { |
|
|
0
|
|
|
|
|
|
1058
|
0
|
|
|
|
|
|
soa_label_count = ldns_dname_label_count(zone->soa->name); |
1059
|
|
|
|
|
|
|
} |
1060
|
|
|
|
|
|
|
|
1061
|
0
|
|
|
|
|
|
cur_node = ldns_rbtree_first(zone->names); |
1062
|
0
|
0
|
|
|
|
|
while (cur_node != LDNS_RBTREE_NULL) { |
1063
|
0
|
|
|
|
|
|
next_node = ldns_rbtree_next(cur_node); |
1064
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
/* skip glue */ |
1066
|
0
|
0
|
|
|
|
|
while (next_node != LDNS_RBTREE_NULL && |
|
|
0
|
|
|
|
|
|
1067
|
0
|
0
|
|
|
|
|
next_node->data && |
1068
|
0
|
|
|
|
|
|
((ldns_dnssec_name *)next_node->data)->is_glue |
1069
|
|
|
|
|
|
|
) { |
1070
|
0
|
|
|
|
|
|
next_node = ldns_rbtree_next(next_node); |
1071
|
|
|
|
|
|
|
} |
1072
|
|
|
|
|
|
|
|
1073
|
0
|
0
|
|
|
|
|
if (next_node == LDNS_RBTREE_NULL) { |
1074
|
0
|
|
|
|
|
|
next_node = ldns_rbtree_first(zone->names); |
1075
|
|
|
|
|
|
|
} |
1076
|
0
|
0
|
|
|
|
|
if (! cur_node->data || ! next_node->data) { |
|
|
0
|
|
|
|
|
|
1077
|
0
|
|
|
|
|
|
return LDNS_STATUS_ERR; |
1078
|
|
|
|
|
|
|
} |
1079
|
0
|
|
|
|
|
|
cur_name = ((ldns_dnssec_name *)cur_node->data)->name; |
1080
|
0
|
|
|
|
|
|
next_name = ((ldns_dnssec_name *)next_node->data)->name; |
1081
|
0
|
|
|
|
|
|
cur_label_count = ldns_dname_label_count(cur_name); |
1082
|
0
|
|
|
|
|
|
next_label_count = ldns_dname_label_count(next_name); |
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
/* Since the names are in canonical order, we can |
1085
|
|
|
|
|
|
|
* recognize empty non-terminals by their labels; |
1086
|
|
|
|
|
|
|
* every label after the first one on the next owner |
1087
|
|
|
|
|
|
|
* name is a non-terminal if it either does not exist |
1088
|
|
|
|
|
|
|
* in the current name or is different from the same |
1089
|
|
|
|
|
|
|
* label in the current name (counting from the end) |
1090
|
|
|
|
|
|
|
*/ |
1091
|
0
|
0
|
|
|
|
|
for (i = 1; i < next_label_count - soa_label_count; i++) { |
1092
|
0
|
|
|
|
|
|
lpos = (int)cur_label_count - (int)next_label_count + (int)i; |
1093
|
0
|
0
|
|
|
|
|
if (lpos >= 0) { |
1094
|
0
|
|
|
|
|
|
l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos); |
1095
|
|
|
|
|
|
|
} else { |
1096
|
0
|
|
|
|
|
|
l1 = NULL; |
1097
|
|
|
|
|
|
|
} |
1098
|
0
|
|
|
|
|
|
l2 = ldns_dname_clone_from(next_name, i); |
1099
|
|
|
|
|
|
|
|
1100
|
0
|
0
|
|
|
|
|
if (!l1 || ldns_dname_compare(l1, l2) != 0) { |
|
|
0
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
/* We have an empty nonterminal, add it to the |
1102
|
|
|
|
|
|
|
* tree |
1103
|
|
|
|
|
|
|
*/ |
1104
|
0
|
|
|
|
|
|
ldns_rbnode_t *node = NULL; |
1105
|
|
|
|
|
|
|
ldns_rdf *ent_name; |
1106
|
|
|
|
|
|
|
|
1107
|
0
|
0
|
|
|
|
|
if (!(ent_name = ldns_dname_clone_from( |
1108
|
|
|
|
|
|
|
next_name, i))) |
1109
|
0
|
|
|
|
|
|
return LDNS_STATUS_MEM_ERR; |
1110
|
|
|
|
|
|
|
|
1111
|
0
|
0
|
|
|
|
|
if (nsec3s && zone->_nsec3params) { |
|
|
0
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
ldns_rdf *ent_hashed_name; |
1113
|
|
|
|
|
|
|
|
1114
|
0
|
0
|
|
|
|
|
if (!(ent_hashed_name = |
1115
|
|
|
|
|
|
|
ldns_nsec3_hash_name_frm_nsec3( |
1116
|
0
|
|
|
|
|
|
zone->_nsec3params, |
1117
|
|
|
|
|
|
|
ent_name))) |
1118
|
0
|
|
|
|
|
|
return LDNS_STATUS_MEM_ERR; |
1119
|
0
|
|
|
|
|
|
node = ldns_rbtree_search(nsec3s, |
1120
|
|
|
|
|
|
|
ent_hashed_name); |
1121
|
0
|
0
|
|
|
|
|
if (!node) { |
1122
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(l1); |
1123
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(l2); |
1124
|
0
|
|
|
|
|
|
continue; |
1125
|
|
|
|
|
|
|
} |
1126
|
|
|
|
|
|
|
} |
1127
|
0
|
|
|
|
|
|
new_name = ldns_dnssec_name_new(); |
1128
|
0
|
0
|
|
|
|
|
if (!new_name) { |
1129
|
0
|
|
|
|
|
|
return LDNS_STATUS_MEM_ERR; |
1130
|
|
|
|
|
|
|
} |
1131
|
0
|
|
|
|
|
|
new_name->name = ent_name; |
1132
|
0
|
0
|
|
|
|
|
if (!new_name->name) { |
1133
|
0
|
|
|
|
|
|
ldns_dnssec_name_free(new_name); |
1134
|
0
|
|
|
|
|
|
return LDNS_STATUS_MEM_ERR; |
1135
|
|
|
|
|
|
|
} |
1136
|
0
|
|
|
|
|
|
new_name->name_alloced = true; |
1137
|
0
|
|
|
|
|
|
new_node = LDNS_MALLOC(ldns_rbnode_t); |
1138
|
0
|
0
|
|
|
|
|
if (!new_node) { |
1139
|
0
|
|
|
|
|
|
ldns_dnssec_name_free(new_name); |
1140
|
0
|
|
|
|
|
|
return LDNS_STATUS_MEM_ERR; |
1141
|
|
|
|
|
|
|
} |
1142
|
0
|
|
|
|
|
|
new_node->key = new_name->name; |
1143
|
0
|
|
|
|
|
|
new_node->data = new_name; |
1144
|
0
|
|
|
|
|
|
(void)ldns_rbtree_insert(zone->names, new_node); |
1145
|
0
|
|
|
|
|
|
ldns_dnssec_name_make_hashed_name( |
1146
|
|
|
|
|
|
|
zone, new_name, NULL); |
1147
|
0
|
0
|
|
|
|
|
if (node) |
1148
|
0
|
|
|
|
|
|
(void) ldns_dnssec_zone_add_rr(zone, |
1149
|
0
|
|
|
|
|
|
(ldns_rr *)node->data); |
1150
|
|
|
|
|
|
|
} |
1151
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(l1); |
1152
|
0
|
|
|
|
|
|
ldns_rdf_deep_free(l2); |
1153
|
|
|
|
|
|
|
} |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
/* we might have inserted a new node after |
1156
|
|
|
|
|
|
|
* the current one so we can't just use next() |
1157
|
|
|
|
|
|
|
*/ |
1158
|
0
|
0
|
|
|
|
|
if (next_node != ldns_rbtree_first(zone->names)) { |
1159
|
0
|
|
|
|
|
|
cur_node = next_node; |
1160
|
|
|
|
|
|
|
} else { |
1161
|
0
|
|
|
|
|
|
cur_node = LDNS_RBTREE_NULL; |
1162
|
|
|
|
|
|
|
} |
1163
|
|
|
|
|
|
|
} |
1164
|
0
|
|
|
|
|
|
return LDNS_STATUS_OK; |
1165
|
|
|
|
|
|
|
} |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
ldns_status |
1168
|
0
|
|
|
|
|
|
ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone) |
1169
|
|
|
|
|
|
|
{ |
1170
|
0
|
|
|
|
|
|
return ldns_dnssec_zone_add_empty_nonterminals_nsec3(zone, NULL); |
1171
|
|
|
|
|
|
|
} |
1172
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
bool |
1174
|
0
|
|
|
|
|
|
ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone) |
1175
|
|
|
|
|
|
|
{ |
1176
|
|
|
|
|
|
|
ldns_rr* nsec3; |
1177
|
|
|
|
|
|
|
ldns_rbnode_t* node; |
1178
|
|
|
|
|
|
|
|
1179
|
0
|
0
|
|
|
|
|
if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) { |
1180
|
0
|
|
|
|
|
|
node = ldns_rbtree_first(zone->names); |
1181
|
0
|
0
|
|
|
|
|
while (node != LDNS_RBTREE_NULL) { |
1182
|
0
|
|
|
|
|
|
nsec3 = ((ldns_dnssec_name*)node->data)->nsec; |
1183
|
0
|
0
|
|
|
|
|
if (nsec3 &&ldns_rr_get_type(nsec3) |
|
|
0
|
|
|
|
|
|
1184
|
0
|
0
|
|
|
|
|
== LDNS_RR_TYPE_NSEC3 && |
1185
|
0
|
|
|
|
|
|
ldns_nsec3_optout(nsec3)) { |
1186
|
0
|
|
|
|
|
|
return true; |
1187
|
|
|
|
|
|
|
} |
1188
|
0
|
|
|
|
|
|
node = ldns_rbtree_next(node); |
1189
|
|
|
|
|
|
|
} |
1190
|
|
|
|
|
|
|
} |
1191
|
0
|
|
|
|
|
|
return false; |
1192
|
|
|
|
|
|
|
} |