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* 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* 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 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 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 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 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 */ 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 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 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 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 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 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 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 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 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 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* 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 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 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 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 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