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