1 /*
2 * util/module.c - module interface
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 /**
36 * \file
37 * Implementation of module.h.
38 */
39
40 #include "config.h"
41 #include "util/module.h"
42 #include "sldns/wire2str.h"
43 #include "util/config_file.h"
44 #include "util/regional.h"
45 #include "util/data/dname.h"
46 #include "util/net_help.h"
47
48 const char*
strextstate(enum module_ext_state s)49 strextstate(enum module_ext_state s)
50 {
51 switch(s) {
52 case module_state_initial: return "module_state_initial";
53 case module_wait_reply: return "module_wait_reply";
54 case module_wait_module: return "module_wait_module";
55 case module_restart_next: return "module_restart_next";
56 case module_wait_subquery: return "module_wait_subquery";
57 case module_error: return "module_error";
58 case module_finished: return "module_finished";
59 }
60 return "bad_extstate_value";
61 }
62
63 const char*
strmodulevent(enum module_ev e)64 strmodulevent(enum module_ev e)
65 {
66 switch(e) {
67 case module_event_new: return "module_event_new";
68 case module_event_pass: return "module_event_pass";
69 case module_event_reply: return "module_event_reply";
70 case module_event_noreply: return "module_event_noreply";
71 case module_event_capsfail: return "module_event_capsfail";
72 case module_event_moddone: return "module_event_moddone";
73 case module_event_error: return "module_event_error";
74 }
75 return "bad_event_value";
76 }
77
errinf(struct module_qstate * qstate,const char * str)78 void errinf(struct module_qstate* qstate, const char* str)
79 {
80 errinf_ede(qstate, str, LDNS_EDE_NONE);
81 }
82
errinf_ede(struct module_qstate * qstate,const char * str,sldns_ede_code reason_bogus)83 void errinf_ede(struct module_qstate* qstate,
84 const char* str, sldns_ede_code reason_bogus)
85 {
86 struct errinf_strlist* p;
87 if(!str || (qstate->env->cfg->val_log_level < 2 &&
88 !qstate->env->cfg->log_servfail)) {
89 return;
90 }
91 p = (struct errinf_strlist*)regional_alloc(qstate->region, sizeof(*p));
92 if(!p) {
93 log_err("malloc failure in validator-error-info string");
94 return;
95 }
96 p->next = NULL;
97 p->str = regional_strdup(qstate->region, str);
98 p->reason_bogus = reason_bogus;
99 if(!p->str) {
100 log_err("malloc failure in validator-error-info string");
101 return;
102 }
103 /* add at end */
104 if(qstate->errinf) {
105 struct errinf_strlist* q = qstate->errinf;
106 while(q->next)
107 q = q->next;
108 q->next = p;
109 } else qstate->errinf = p;
110 }
111
errinf_origin(struct module_qstate * qstate,struct sock_list * origin)112 void errinf_origin(struct module_qstate* qstate, struct sock_list *origin)
113 {
114 struct sock_list* p;
115 if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
116 return;
117 for(p=origin; p; p=p->next) {
118 char buf[256];
119 if(p == origin)
120 snprintf(buf, sizeof(buf), "from ");
121 else snprintf(buf, sizeof(buf), "and ");
122 if(p->len == 0)
123 snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf),
124 "cache");
125 else
126 addr_to_str(&p->addr, p->len, buf+strlen(buf),
127 sizeof(buf)-strlen(buf));
128 errinf(qstate, buf);
129 }
130 }
131
errinf_to_str_bogus(struct module_qstate * qstate,struct regional * region)132 char* errinf_to_str_bogus(struct module_qstate* qstate, struct regional* region)
133 {
134 char buf[20480];
135 char* p = buf;
136 size_t left = sizeof(buf);
137 struct errinf_strlist* s;
138 char dname[LDNS_MAX_DOMAINLEN+1];
139 char t[16], c[16];
140 sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
141 sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
142 dname_str(qstate->qinfo.qname, dname);
143 snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c);
144 left -= strlen(p); p += strlen(p);
145 if(!qstate->errinf)
146 snprintf(p, left, " misc failure");
147 else for(s=qstate->errinf; s; s=s->next) {
148 snprintf(p, left, " %s", s->str);
149 left -= strlen(p); p += strlen(p);
150 }
151 if(region)
152 p = regional_strdup(region, buf);
153 else
154 p = strdup(buf);
155 if(!p)
156 log_err("malloc failure in errinf_to_str");
157 return p;
158 }
159
160 /* Try to find the latest (most specific) dnssec failure */
errinf_to_reason_bogus(struct module_qstate * qstate)161 sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate)
162 {
163 struct errinf_strlist* s;
164 sldns_ede_code ede = LDNS_EDE_NONE;
165 for(s=qstate->errinf; s; s=s->next) {
166 if(s->reason_bogus == LDNS_EDE_NONE) continue;
167 if(ede != LDNS_EDE_NONE
168 && ede != LDNS_EDE_DNSSEC_BOGUS
169 && s->reason_bogus == LDNS_EDE_DNSSEC_BOGUS) continue;
170 ede = s->reason_bogus;
171 }
172 return ede;
173 }
174
errinf_to_str_servfail(struct module_qstate * qstate)175 char* errinf_to_str_servfail(struct module_qstate* qstate)
176 {
177 char buf[20480];
178 char* p = buf;
179 size_t left = sizeof(buf);
180 struct errinf_strlist* s;
181 char dname[LDNS_MAX_DOMAINLEN+1];
182 char t[16], c[16];
183 sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
184 sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
185 dname_str(qstate->qinfo.qname, dname);
186 snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c);
187 left -= strlen(p); p += strlen(p);
188 if(!qstate->errinf)
189 snprintf(p, left, " misc failure");
190 else for(s=qstate->errinf; s; s=s->next) {
191 snprintf(p, left, " %s", s->str);
192 left -= strlen(p); p += strlen(p);
193 }
194 p = regional_strdup(qstate->region, buf);
195 if(!p)
196 log_err("malloc failure in errinf_to_str");
197 return p;
198 }
199
errinf_to_str_misc(struct module_qstate * qstate)200 char* errinf_to_str_misc(struct module_qstate* qstate)
201 {
202 char buf[20480];
203 char* p = buf;
204 size_t left = sizeof(buf);
205 struct errinf_strlist* s;
206 if(!qstate->errinf)
207 snprintf(p, left, "misc failure");
208 else for(s=qstate->errinf; s; s=s->next) {
209 snprintf(p, left, "%s%s", (s==qstate->errinf?"":" "), s->str);
210 left -= strlen(p); p += strlen(p);
211 }
212 p = regional_strdup(qstate->region, buf);
213 if(!p)
214 log_err("malloc failure in errinf_to_str");
215 return p;
216 }
217
errinf_rrset(struct module_qstate * qstate,struct ub_packed_rrset_key * rr)218 void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr)
219 {
220 char buf[1024];
221 char dname[LDNS_MAX_DOMAINLEN+1];
222 char t[16], c[16];
223 if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !rr)
224 return;
225 sldns_wire2str_type_buf(ntohs(rr->rk.type), t, sizeof(t));
226 sldns_wire2str_class_buf(ntohs(rr->rk.rrset_class), c, sizeof(c));
227 dname_str(rr->rk.dname, dname);
228 snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c);
229 errinf(qstate, buf);
230 }
231
errinf_dname(struct module_qstate * qstate,const char * str,uint8_t * dname)232 void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname)
233 {
234 char b[1024];
235 char buf[LDNS_MAX_DOMAINLEN+1];
236 if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str || !dname)
237 return;
238 dname_str(dname, buf);
239 snprintf(b, sizeof(b), "%s %s", str, buf);
240 errinf(qstate, b);
241 }
242
243 int
edns_known_options_init(struct module_env * env)244 edns_known_options_init(struct module_env* env)
245 {
246 env->edns_known_options_num = 0;
247 env->edns_known_options = (struct edns_known_option*)calloc(
248 MAX_KNOWN_EDNS_OPTS, sizeof(struct edns_known_option));
249 if(!env->edns_known_options) return 0;
250 return 1;
251 }
252
253 void
edns_known_options_delete(struct module_env * env)254 edns_known_options_delete(struct module_env* env)
255 {
256 free(env->edns_known_options);
257 env->edns_known_options = NULL;
258 env->edns_known_options_num = 0;
259 }
260
261 int
edns_register_option(uint16_t opt_code,int bypass_cache_stage,int no_aggregation,struct module_env * env)262 edns_register_option(uint16_t opt_code, int bypass_cache_stage,
263 int no_aggregation, struct module_env* env)
264 {
265 size_t i;
266 if(env->worker) {
267 log_err("invalid edns registration: "
268 "trying to register option after module init phase");
269 return 0;
270 }
271
272 /**
273 * Checking if we are full first is faster but it does not provide
274 * the option to change the flags when the array is full.
275 * It only impacts unbound initialization, leave it for now.
276 */
277 /* Check if the option is already registered. */
278 for(i=0; i<env->edns_known_options_num; i++)
279 if(env->edns_known_options[i].opt_code == opt_code)
280 break;
281 /* If it is not yet registered check if we have space to add a new one. */
282 if(i == env->edns_known_options_num) {
283 if(env->edns_known_options_num >= MAX_KNOWN_EDNS_OPTS) {
284 log_err("invalid edns registration: maximum options reached");
285 return 0;
286 }
287 env->edns_known_options_num++;
288 }
289 env->edns_known_options[i].opt_code = opt_code;
290 env->edns_known_options[i].bypass_cache_stage = bypass_cache_stage;
291 env->edns_known_options[i].no_aggregation = no_aggregation;
292 return 1;
293 }
294
295 int
inplace_cb_register(void * cb,enum inplace_cb_list_type type,void * cbarg,struct module_env * env,int id)296 inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
297 struct module_env* env, int id)
298 {
299 struct inplace_cb* callback;
300 struct inplace_cb** prevp;
301 if(env->worker) {
302 log_err("invalid edns callback registration: "
303 "trying to register callback after module init phase");
304 return 0;
305 }
306
307 callback = (struct inplace_cb*)calloc(1, sizeof(*callback));
308 if(callback == NULL) {
309 log_err("out of memory during edns callback registration.");
310 return 0;
311 }
312 callback->id = id;
313 callback->next = NULL;
314 callback->cb = cb;
315 callback->cb_arg = cbarg;
316
317 prevp = (struct inplace_cb**) &env->inplace_cb_lists[type];
318 /* append at end of list */
319 while(*prevp != NULL)
320 prevp = &((*prevp)->next);
321 *prevp = callback;
322 return 1;
323 }
324
325 void
inplace_cb_delete(struct module_env * env,enum inplace_cb_list_type type,int id)326 inplace_cb_delete(struct module_env* env, enum inplace_cb_list_type type,
327 int id)
328 {
329 struct inplace_cb* temp = env->inplace_cb_lists[type];
330 struct inplace_cb* prev = NULL;
331
332 while(temp) {
333 if(temp->id == id) {
334 if(!prev) {
335 env->inplace_cb_lists[type] = temp->next;
336 free(temp);
337 temp = env->inplace_cb_lists[type];
338 }
339 else {
340 prev->next = temp->next;
341 free(temp);
342 temp = prev->next;
343 }
344 }
345 else {
346 prev = temp;
347 temp = temp->next;
348 }
349 }
350 }
351
352 struct edns_known_option*
edns_option_is_known(uint16_t opt_code,struct module_env * env)353 edns_option_is_known(uint16_t opt_code, struct module_env* env)
354 {
355 size_t i;
356 for(i=0; i<env->edns_known_options_num; i++)
357 if(env->edns_known_options[i].opt_code == opt_code)
358 return env->edns_known_options + i;
359 return NULL;
360 }
361
362 int
edns_bypass_cache_stage(struct edns_option * list,struct module_env * env)363 edns_bypass_cache_stage(struct edns_option* list, struct module_env* env)
364 {
365 size_t i;
366 for(; list; list=list->next)
367 for(i=0; i<env->edns_known_options_num; i++)
368 if(env->edns_known_options[i].opt_code == list->opt_code &&
369 env->edns_known_options[i].bypass_cache_stage == 1)
370 return 1;
371 return 0;
372 }
373
374 int
unique_mesh_state(struct edns_option * list,struct module_env * env)375 unique_mesh_state(struct edns_option* list, struct module_env* env)
376 {
377 size_t i;
378 if(env->unique_mesh)
379 return 1;
380 for(; list; list=list->next)
381 for(i=0; i<env->edns_known_options_num; i++)
382 if(env->edns_known_options[i].opt_code == list->opt_code &&
383 env->edns_known_options[i].no_aggregation == 1)
384 return 1;
385 return 0;
386 }
387
388 void
log_edns_known_options(enum verbosity_value level,struct module_env * env)389 log_edns_known_options(enum verbosity_value level, struct module_env* env)
390 {
391 size_t i;
392 char str[32], *s;
393 size_t slen;
394 if(env->edns_known_options_num > 0 && verbosity >= level) {
395 verbose(level, "EDNS known options:");
396 verbose(level, " Code: Bypass_cache_stage: Aggregate_mesh:");
397 for(i=0; i<env->edns_known_options_num; i++) {
398 s = str;
399 slen = sizeof(str);
400 (void)sldns_wire2str_edns_option_code_print(&s, &slen,
401 env->edns_known_options[i].opt_code);
402 verbose(level, " %-8.8s %-19s %-15s", str,
403 env->edns_known_options[i].bypass_cache_stage?"YES":"NO",
404 env->edns_known_options[i].no_aggregation?"NO":"YES");
405 }
406 }
407 }
408
409 void
copy_state_to_super(struct module_qstate * qstate,int ATTR_UNUSED (id),struct module_qstate * super)410 copy_state_to_super(struct module_qstate* qstate, int ATTR_UNUSED(id),
411 struct module_qstate* super)
412 {
413 /* Overwrite super's was_ratelimited only when it was not set */
414 if(!super->was_ratelimited) {
415 super->was_ratelimited = qstate->was_ratelimited;
416 }
417 }
418