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" 43*a39a5a69SCy Schubert #include "util/config_file.h" 44*a39a5a69SCy Schubert #include "util/regional.h" 45*a39a5a69SCy Schubert #include "util/data/dname.h" 46*a39a5a69SCy 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 78*a39a5a69SCy Schubert void errinf(struct module_qstate* qstate, const char* str) 79*a39a5a69SCy Schubert { 80*a39a5a69SCy Schubert errinf_ede(qstate, str, LDNS_EDE_NONE); 81*a39a5a69SCy Schubert } 82*a39a5a69SCy Schubert 83*a39a5a69SCy Schubert void errinf_ede(struct module_qstate* qstate, 84*a39a5a69SCy Schubert const char* str, sldns_ede_code reason_bogus) 85*a39a5a69SCy Schubert { 86*a39a5a69SCy Schubert struct errinf_strlist* p; 87*a39a5a69SCy Schubert if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str) 88*a39a5a69SCy Schubert return; 89*a39a5a69SCy Schubert p = (struct errinf_strlist*)regional_alloc(qstate->region, sizeof(*p)); 90*a39a5a69SCy Schubert if(!p) { 91*a39a5a69SCy Schubert log_err("malloc failure in validator-error-info string"); 92*a39a5a69SCy Schubert return; 93*a39a5a69SCy Schubert } 94*a39a5a69SCy Schubert p->next = NULL; 95*a39a5a69SCy Schubert p->str = regional_strdup(qstate->region, str); 96*a39a5a69SCy Schubert p->reason_bogus = reason_bogus; 97*a39a5a69SCy Schubert if(!p->str) { 98*a39a5a69SCy Schubert log_err("malloc failure in validator-error-info string"); 99*a39a5a69SCy Schubert return; 100*a39a5a69SCy Schubert } 101*a39a5a69SCy Schubert /* add at end */ 102*a39a5a69SCy Schubert if(qstate->errinf) { 103*a39a5a69SCy Schubert struct errinf_strlist* q = qstate->errinf; 104*a39a5a69SCy Schubert while(q->next) 105*a39a5a69SCy Schubert q = q->next; 106*a39a5a69SCy Schubert q->next = p; 107*a39a5a69SCy Schubert } else qstate->errinf = p; 108*a39a5a69SCy Schubert } 109*a39a5a69SCy Schubert 110*a39a5a69SCy Schubert void errinf_origin(struct module_qstate* qstate, struct sock_list *origin) 111*a39a5a69SCy Schubert { 112*a39a5a69SCy Schubert struct sock_list* p; 113*a39a5a69SCy Schubert if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) 114*a39a5a69SCy Schubert return; 115*a39a5a69SCy Schubert for(p=origin; p; p=p->next) { 116*a39a5a69SCy Schubert char buf[256]; 117*a39a5a69SCy Schubert if(p == origin) 118*a39a5a69SCy Schubert snprintf(buf, sizeof(buf), "from "); 119*a39a5a69SCy Schubert else snprintf(buf, sizeof(buf), "and "); 120*a39a5a69SCy Schubert if(p->len == 0) 121*a39a5a69SCy Schubert snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), 122*a39a5a69SCy Schubert "cache"); 123*a39a5a69SCy Schubert else 124*a39a5a69SCy Schubert addr_to_str(&p->addr, p->len, buf+strlen(buf), 125*a39a5a69SCy Schubert sizeof(buf)-strlen(buf)); 126*a39a5a69SCy Schubert errinf(qstate, buf); 127*a39a5a69SCy Schubert } 128*a39a5a69SCy Schubert } 129*a39a5a69SCy Schubert 130*a39a5a69SCy Schubert char* errinf_to_str_bogus(struct module_qstate* qstate) 131*a39a5a69SCy Schubert { 132*a39a5a69SCy Schubert char buf[20480]; 133*a39a5a69SCy Schubert char* p = buf; 134*a39a5a69SCy Schubert size_t left = sizeof(buf); 135*a39a5a69SCy Schubert struct errinf_strlist* s; 136*a39a5a69SCy Schubert char dname[LDNS_MAX_DOMAINLEN+1]; 137*a39a5a69SCy Schubert char t[16], c[16]; 138*a39a5a69SCy Schubert sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t)); 139*a39a5a69SCy Schubert sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c)); 140*a39a5a69SCy Schubert dname_str(qstate->qinfo.qname, dname); 141*a39a5a69SCy Schubert snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c); 142*a39a5a69SCy Schubert left -= strlen(p); p += strlen(p); 143*a39a5a69SCy Schubert if(!qstate->errinf) 144*a39a5a69SCy Schubert snprintf(p, left, " misc failure"); 145*a39a5a69SCy Schubert else for(s=qstate->errinf; s; s=s->next) { 146*a39a5a69SCy Schubert snprintf(p, left, " %s", s->str); 147*a39a5a69SCy Schubert left -= strlen(p); p += strlen(p); 148*a39a5a69SCy Schubert } 149*a39a5a69SCy Schubert p = strdup(buf); 150*a39a5a69SCy Schubert if(!p) 151*a39a5a69SCy Schubert log_err("malloc failure in errinf_to_str"); 152*a39a5a69SCy Schubert return p; 153*a39a5a69SCy Schubert } 154*a39a5a69SCy Schubert 155*a39a5a69SCy Schubert sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate) 156*a39a5a69SCy Schubert { 157*a39a5a69SCy Schubert struct errinf_strlist* s; 158*a39a5a69SCy Schubert for(s=qstate->errinf; s; s=s->next) { 159*a39a5a69SCy Schubert if (s->reason_bogus != LDNS_EDE_NONE) { 160*a39a5a69SCy Schubert return s->reason_bogus; 161*a39a5a69SCy Schubert } 162*a39a5a69SCy Schubert } 163*a39a5a69SCy Schubert return LDNS_EDE_NONE; 164*a39a5a69SCy Schubert } 165*a39a5a69SCy Schubert 166*a39a5a69SCy Schubert char* errinf_to_str_servfail(struct module_qstate* qstate) 167*a39a5a69SCy Schubert { 168*a39a5a69SCy Schubert char buf[20480]; 169*a39a5a69SCy Schubert char* p = buf; 170*a39a5a69SCy Schubert size_t left = sizeof(buf); 171*a39a5a69SCy Schubert struct errinf_strlist* s; 172*a39a5a69SCy Schubert char dname[LDNS_MAX_DOMAINLEN+1]; 173*a39a5a69SCy Schubert char t[16], c[16]; 174*a39a5a69SCy Schubert sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t)); 175*a39a5a69SCy Schubert sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c)); 176*a39a5a69SCy Schubert dname_str(qstate->qinfo.qname, dname); 177*a39a5a69SCy Schubert snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c); 178*a39a5a69SCy Schubert left -= strlen(p); p += strlen(p); 179*a39a5a69SCy Schubert if(!qstate->errinf) 180*a39a5a69SCy Schubert snprintf(p, left, " misc failure"); 181*a39a5a69SCy Schubert else for(s=qstate->errinf; s; s=s->next) { 182*a39a5a69SCy Schubert snprintf(p, left, " %s", s->str); 183*a39a5a69SCy Schubert left -= strlen(p); p += strlen(p); 184*a39a5a69SCy Schubert } 185*a39a5a69SCy Schubert p = strdup(buf); 186*a39a5a69SCy Schubert if(!p) 187*a39a5a69SCy Schubert log_err("malloc failure in errinf_to_str"); 188*a39a5a69SCy Schubert return p; 189*a39a5a69SCy Schubert } 190*a39a5a69SCy Schubert 191*a39a5a69SCy Schubert void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) 192*a39a5a69SCy Schubert { 193*a39a5a69SCy Schubert char buf[1024]; 194*a39a5a69SCy Schubert char dname[LDNS_MAX_DOMAINLEN+1]; 195*a39a5a69SCy Schubert char t[16], c[16]; 196*a39a5a69SCy Schubert if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !rr) 197*a39a5a69SCy Schubert return; 198*a39a5a69SCy Schubert sldns_wire2str_type_buf(ntohs(rr->rk.type), t, sizeof(t)); 199*a39a5a69SCy Schubert sldns_wire2str_class_buf(ntohs(rr->rk.rrset_class), c, sizeof(c)); 200*a39a5a69SCy Schubert dname_str(rr->rk.dname, dname); 201*a39a5a69SCy Schubert snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c); 202*a39a5a69SCy Schubert errinf(qstate, buf); 203*a39a5a69SCy Schubert } 204*a39a5a69SCy Schubert 205*a39a5a69SCy Schubert void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname) 206*a39a5a69SCy Schubert { 207*a39a5a69SCy Schubert char b[1024]; 208*a39a5a69SCy Schubert char buf[LDNS_MAX_DOMAINLEN+1]; 209*a39a5a69SCy Schubert if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str || !dname) 210*a39a5a69SCy Schubert return; 211*a39a5a69SCy Schubert dname_str(dname, buf); 212*a39a5a69SCy Schubert snprintf(b, sizeof(b), "%s %s", str, buf); 213*a39a5a69SCy Schubert errinf(qstate, b); 214*a39a5a69SCy Schubert } 215*a39a5a69SCy Schubert 216bc892140SDag-Erling Smørgrav int 217bc892140SDag-Erling Smørgrav edns_known_options_init(struct module_env* env) 218bc892140SDag-Erling Smørgrav { 219bc892140SDag-Erling Smørgrav env->edns_known_options_num = 0; 220bc892140SDag-Erling Smørgrav env->edns_known_options = (struct edns_known_option*)calloc( 221bc892140SDag-Erling Smørgrav MAX_KNOWN_EDNS_OPTS, sizeof(struct edns_known_option)); 222bc892140SDag-Erling Smørgrav if(!env->edns_known_options) return 0; 223bc892140SDag-Erling Smørgrav return 1; 224bc892140SDag-Erling Smørgrav } 225bc892140SDag-Erling Smørgrav 226bc892140SDag-Erling Smørgrav void 227bc892140SDag-Erling Smørgrav edns_known_options_delete(struct module_env* env) 228bc892140SDag-Erling Smørgrav { 229bc892140SDag-Erling Smørgrav free(env->edns_known_options); 230bc892140SDag-Erling Smørgrav env->edns_known_options = NULL; 231bc892140SDag-Erling Smørgrav env->edns_known_options_num = 0; 232bc892140SDag-Erling Smørgrav } 233bc892140SDag-Erling Smørgrav 234bc892140SDag-Erling Smørgrav int 235bc892140SDag-Erling Smørgrav edns_register_option(uint16_t opt_code, int bypass_cache_stage, 236bc892140SDag-Erling Smørgrav int no_aggregation, struct module_env* env) 237bc892140SDag-Erling Smørgrav { 238bc892140SDag-Erling Smørgrav size_t i; 239bc892140SDag-Erling Smørgrav if(env->worker) { 240bc892140SDag-Erling Smørgrav log_err("invalid edns registration: " 241bc892140SDag-Erling Smørgrav "trying to register option after module init phase"); 242bc892140SDag-Erling Smørgrav return 0; 243bc892140SDag-Erling Smørgrav } 244bc892140SDag-Erling Smørgrav 245bc892140SDag-Erling Smørgrav /** 246bc892140SDag-Erling Smørgrav * Checking if we are full first is faster but it does not provide 247bc892140SDag-Erling Smørgrav * the option to change the flags when the array is full. 248bc892140SDag-Erling Smørgrav * It only impacts unbound initialization, leave it for now. 249bc892140SDag-Erling Smørgrav */ 250bc892140SDag-Erling Smørgrav /* Check if the option is already registered. */ 251bc892140SDag-Erling Smørgrav for(i=0; i<env->edns_known_options_num; i++) 252bc892140SDag-Erling Smørgrav if(env->edns_known_options[i].opt_code == opt_code) 253bc892140SDag-Erling Smørgrav break; 254bc892140SDag-Erling Smørgrav /* If it is not yet registered check if we have space to add a new one. */ 255bc892140SDag-Erling Smørgrav if(i == env->edns_known_options_num) { 256bc892140SDag-Erling Smørgrav if(env->edns_known_options_num >= MAX_KNOWN_EDNS_OPTS) { 257bc892140SDag-Erling Smørgrav log_err("invalid edns registration: maximum options reached"); 258bc892140SDag-Erling Smørgrav return 0; 259bc892140SDag-Erling Smørgrav } 260bc892140SDag-Erling Smørgrav env->edns_known_options_num++; 261bc892140SDag-Erling Smørgrav } 262bc892140SDag-Erling Smørgrav env->edns_known_options[i].opt_code = opt_code; 263bc892140SDag-Erling Smørgrav env->edns_known_options[i].bypass_cache_stage = bypass_cache_stage; 264bc892140SDag-Erling Smørgrav env->edns_known_options[i].no_aggregation = no_aggregation; 265bc892140SDag-Erling Smørgrav return 1; 266bc892140SDag-Erling Smørgrav } 267bc892140SDag-Erling Smørgrav 26865b390aaSDag-Erling Smørgrav int 26965b390aaSDag-Erling Smørgrav inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg, 27065b390aaSDag-Erling Smørgrav struct module_env* env, int id) 271bc892140SDag-Erling Smørgrav { 27265b390aaSDag-Erling Smørgrav struct inplace_cb* callback; 27365b390aaSDag-Erling Smørgrav struct inplace_cb** prevp; 274bc892140SDag-Erling Smørgrav if(env->worker) { 275bc892140SDag-Erling Smørgrav log_err("invalid edns callback registration: " 276bc892140SDag-Erling Smørgrav "trying to register callback after module init phase"); 277bc892140SDag-Erling Smørgrav return 0; 278bc892140SDag-Erling Smørgrav } 279bc892140SDag-Erling Smørgrav 28065b390aaSDag-Erling Smørgrav callback = (struct inplace_cb*)calloc(1, sizeof(*callback)); 281bc892140SDag-Erling Smørgrav if(callback == NULL) { 282bc892140SDag-Erling Smørgrav log_err("out of memory during edns callback registration."); 283bc892140SDag-Erling Smørgrav return 0; 284bc892140SDag-Erling Smørgrav } 28565b390aaSDag-Erling Smørgrav callback->id = id; 286bc892140SDag-Erling Smørgrav callback->next = NULL; 287bc892140SDag-Erling Smørgrav callback->cb = cb; 28865b390aaSDag-Erling Smørgrav callback->cb_arg = cbarg; 289bc892140SDag-Erling Smørgrav 29065b390aaSDag-Erling Smørgrav prevp = (struct inplace_cb**) &env->inplace_cb_lists[type]; 291bc892140SDag-Erling Smørgrav /* append at end of list */ 292bc892140SDag-Erling Smørgrav while(*prevp != NULL) 293bc892140SDag-Erling Smørgrav prevp = &((*prevp)->next); 294bc892140SDag-Erling Smørgrav *prevp = callback; 295bc892140SDag-Erling Smørgrav return 1; 296bc892140SDag-Erling Smørgrav } 297bc892140SDag-Erling Smørgrav 298bc892140SDag-Erling Smørgrav void 29965b390aaSDag-Erling Smørgrav inplace_cb_delete(struct module_env* env, enum inplace_cb_list_type type, 30065b390aaSDag-Erling Smørgrav int id) 301bc892140SDag-Erling Smørgrav { 30265b390aaSDag-Erling Smørgrav struct inplace_cb* temp = env->inplace_cb_lists[type]; 30365b390aaSDag-Erling Smørgrav struct inplace_cb* prev = NULL; 304bc892140SDag-Erling Smørgrav 30565b390aaSDag-Erling Smørgrav while(temp) { 30665b390aaSDag-Erling Smørgrav if(temp->id == id) { 30765b390aaSDag-Erling Smørgrav if(!prev) { 30865b390aaSDag-Erling Smørgrav env->inplace_cb_lists[type] = temp->next; 30965b390aaSDag-Erling Smørgrav free(temp); 31065b390aaSDag-Erling Smørgrav temp = env->inplace_cb_lists[type]; 31165b390aaSDag-Erling Smørgrav } 31265b390aaSDag-Erling Smørgrav else { 31365b390aaSDag-Erling Smørgrav prev->next = temp->next; 31465b390aaSDag-Erling Smørgrav free(temp); 31565b390aaSDag-Erling Smørgrav temp = prev->next; 31665b390aaSDag-Erling Smørgrav } 31765b390aaSDag-Erling Smørgrav } 31865b390aaSDag-Erling Smørgrav else { 31965b390aaSDag-Erling Smørgrav prev = temp; 32065b390aaSDag-Erling Smørgrav temp = temp->next; 32165b390aaSDag-Erling Smørgrav } 32265b390aaSDag-Erling Smørgrav } 323bc892140SDag-Erling Smørgrav } 324bc892140SDag-Erling Smørgrav 325bc892140SDag-Erling Smørgrav struct edns_known_option* 326bc892140SDag-Erling Smørgrav edns_option_is_known(uint16_t opt_code, struct module_env* env) 327bc892140SDag-Erling Smørgrav { 328bc892140SDag-Erling Smørgrav size_t i; 329bc892140SDag-Erling Smørgrav for(i=0; i<env->edns_known_options_num; i++) 330bc892140SDag-Erling Smørgrav if(env->edns_known_options[i].opt_code == opt_code) 331bc892140SDag-Erling Smørgrav return env->edns_known_options + i; 332bc892140SDag-Erling Smørgrav return NULL; 333bc892140SDag-Erling Smørgrav } 334bc892140SDag-Erling Smørgrav 335bc892140SDag-Erling Smørgrav int 336bc892140SDag-Erling Smørgrav edns_bypass_cache_stage(struct edns_option* list, struct module_env* env) 337bc892140SDag-Erling Smørgrav { 338bc892140SDag-Erling Smørgrav size_t i; 339bc892140SDag-Erling Smørgrav for(; list; list=list->next) 340bc892140SDag-Erling Smørgrav for(i=0; i<env->edns_known_options_num; i++) 341bc892140SDag-Erling Smørgrav if(env->edns_known_options[i].opt_code == list->opt_code && 342bc892140SDag-Erling Smørgrav env->edns_known_options[i].bypass_cache_stage == 1) 343bc892140SDag-Erling Smørgrav return 1; 344bc892140SDag-Erling Smørgrav return 0; 345bc892140SDag-Erling Smørgrav } 346bc892140SDag-Erling Smørgrav 347bc892140SDag-Erling Smørgrav int 34865b390aaSDag-Erling Smørgrav unique_mesh_state(struct edns_option* list, struct module_env* env) 349bc892140SDag-Erling Smørgrav { 350bc892140SDag-Erling Smørgrav size_t i; 35165b390aaSDag-Erling Smørgrav if(env->unique_mesh) 35265b390aaSDag-Erling Smørgrav return 1; 353bc892140SDag-Erling Smørgrav for(; list; list=list->next) 354bc892140SDag-Erling Smørgrav for(i=0; i<env->edns_known_options_num; i++) 355bc892140SDag-Erling Smørgrav if(env->edns_known_options[i].opt_code == list->opt_code && 356bc892140SDag-Erling Smørgrav env->edns_known_options[i].no_aggregation == 1) 357bc892140SDag-Erling Smørgrav return 1; 358bc892140SDag-Erling Smørgrav return 0; 359bc892140SDag-Erling Smørgrav } 360bc892140SDag-Erling Smørgrav 361bc892140SDag-Erling Smørgrav void 362bc892140SDag-Erling Smørgrav log_edns_known_options(enum verbosity_value level, struct module_env* env) 363bc892140SDag-Erling Smørgrav { 364bc892140SDag-Erling Smørgrav size_t i; 365bc892140SDag-Erling Smørgrav char str[32], *s; 366bc892140SDag-Erling Smørgrav size_t slen; 367bc892140SDag-Erling Smørgrav if(env->edns_known_options_num > 0 && verbosity >= level) { 368bc892140SDag-Erling Smørgrav verbose(level, "EDNS known options:"); 369bc892140SDag-Erling Smørgrav verbose(level, " Code: Bypass_cache_stage: Aggregate_mesh:"); 370bc892140SDag-Erling Smørgrav for(i=0; i<env->edns_known_options_num; i++) { 371bc892140SDag-Erling Smørgrav s = str; 372bc892140SDag-Erling Smørgrav slen = sizeof(str); 373bc892140SDag-Erling Smørgrav (void)sldns_wire2str_edns_option_code_print(&s, &slen, 374bc892140SDag-Erling Smørgrav env->edns_known_options[i].opt_code); 375bc892140SDag-Erling Smørgrav verbose(level, " %-8.8s %-19s %-15s", str, 376bc892140SDag-Erling Smørgrav env->edns_known_options[i].bypass_cache_stage?"YES":"NO", 377bc892140SDag-Erling Smørgrav env->edns_known_options[i].no_aggregation?"NO":"YES"); 378bc892140SDag-Erling Smørgrav } 379bc892140SDag-Erling Smørgrav } 380bc892140SDag-Erling Smørgrav } 3814c75e3aaSDag-Erling Smørgrav 3824c75e3aaSDag-Erling Smørgrav void 3834c75e3aaSDag-Erling Smørgrav copy_state_to_super(struct module_qstate* qstate, int ATTR_UNUSED(id), 3844c75e3aaSDag-Erling Smørgrav struct module_qstate* super) 3854c75e3aaSDag-Erling Smørgrav { 3864c75e3aaSDag-Erling Smørgrav /* Overwrite super's was_ratelimited only when it was not set */ 3874c75e3aaSDag-Erling Smørgrav if(!super->was_ratelimited) { 3884c75e3aaSDag-Erling Smørgrav super->was_ratelimited = qstate->was_ratelimited; 3894c75e3aaSDag-Erling Smørgrav } 3904c75e3aaSDag-Erling Smørgrav } 391