void log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, uint16_t type, uint16_t dclass) { char buf[LDNS_MAX_DOMAINLEN+1]; char t[12], c[12]; const char *ts, *cs; if(verbosity < v) return; dname_str(name, buf); if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG"; else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR"; else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR"; else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB"; else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA"; else if(type == LDNS_RR_TYPE_ANY) ts = "ANY"; else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name) ts = sldns_rr_descript(type)->_name; else { snprintf(t, sizeof(t), "TYPE%d", (int)type); ts = t; } if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) && sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name) cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name; else { snprintf(c, sizeof(c), "CLASS%d", (int)dclass); cs = c; } log_info("%s %s %s %s", str, buf, ts, cs); }
/** * Return an error * @param qstate: our query state * @param id: module id * @param rcode: error code (DNS errcode). * @return: 0 for use by caller, to make notation easy, like: * return error_response(..). */ static int error_response(struct module_qstate* qstate, int id, int rcode) { verbose(VERB_QUERY, "return error response %s", sldns_lookup_by_id(sldns_rcodes, rcode)? sldns_lookup_by_id(sldns_rcodes, rcode)->name:"??"); qstate->return_rcode = rcode; qstate->return_msg = NULL; qstate->ext_state[id] = module_finished; return 0; }
/** * Handle a cachedb module event with a query * @param qstate: query state (from the mesh), passed between modules. * contains qstate->env module environment with global caches and so on. * @param iq: query state specific for this module. per-query. * @param ie: environment specific for this module. global. * @param id: module id. */ static void cachedb_handle_query(struct module_qstate* qstate, struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id) { /* check if we are enabled, and skip if so */ if(!ie->enabled) { /* pass request to next module */ qstate->ext_state[id] = module_wait_module; return; } if(qstate->blacklist || qstate->no_cache_lookup) { /* cache is blacklisted or we are instructed from edns to not look */ /* pass request to next module */ qstate->ext_state[id] = module_wait_module; return; } /* lookup inside unbound's internal cache */ if(cachedb_intcache_lookup(qstate)) { if(verbosity >= VERB_ALGO) { if(qstate->return_msg->rep) log_dns_msg("cachedb internal cache lookup", &qstate->return_msg->qinfo, qstate->return_msg->rep); else log_info("cachedb internal cache lookup: rcode %s", sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)? sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name:"??"); } /* we are done with the query */ qstate->ext_state[id] = module_finished; return; } /* ask backend cache to see if we have data */ if(cachedb_extcache_lookup(qstate, ie)) { if(verbosity >= VERB_ALGO) log_dns_msg(ie->backend->name, &qstate->return_msg->qinfo, qstate->return_msg->rep); /* store this result in internal cache */ cachedb_intcache_store(qstate); /* we are done with the query */ qstate->ext_state[id] = module_finished; return; } /* no cache fetches */ /* pass request to next module */ qstate->ext_state[id] = module_wait_module; }
void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s) { char buf[256]; sldns_lookup_table *t = sldns_lookup_by_id(sldns_algorithms, alg); if(t&&t->name) snprintf(buf, sizeof(buf), "%s with algorithm %s", s, t->name); else snprintf(buf, sizeof(buf), "%s with algorithm ALG%u", s, (unsigned)alg); *reason = regional_strdup(env->scratch, buf); if(!*reason) *reason = s; }
/** analyze rr in packet */ static void analyze_rr(sldns_buffer* pkt, int q) { uint16_t type, dclass, len; uint32_t ttl; analyze_dname(pkt); type = sldns_buffer_read_u16(pkt); dclass = sldns_buffer_read_u16(pkt); printf("type %s(%d)", sldns_rr_descript(type)? sldns_rr_descript(type)->_name: "??" , (int)type); printf(" class %s(%d) ", sldns_lookup_by_id(sldns_rr_classes, (int)dclass)?sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name:"??", (int)dclass); if(q) { printf("\n"); } else { ttl = sldns_buffer_read_u32(pkt); printf(" ttl %d (0x%x)", (int)ttl, (unsigned)ttl); len = sldns_buffer_read_u16(pkt); printf(" rdata len %d:\n", (int)len); if(sldns_rr_descript(type)) analyze_rdata(pkt, sldns_rr_descript(type), len); else sldns_buffer_skip(pkt, (ssize_t)len); } }
/** * Parse packet RR section, for answer, authority and additional sections. * @param pkt: packet, position at call must be at start of section. * at end position is after section. * @param msg: store results here. * @param region: how to alloc results. * @param section: section enum. * @param num_rrs: how many rrs are in the section. * @param num_rrsets: returns number of rrsets in the section. * @return: 0 if OK, or rcode on error. */ static int parse_section(sldns_buffer* pkt, struct msg_parse* msg, struct regional* region, sldns_pkt_section section, uint16_t num_rrs, size_t* num_rrsets) { uint16_t i; uint8_t* dname, *prev_dname_f = NULL, *prev_dname_l = NULL; size_t dnamelen, prev_dnamelen = 0; uint16_t type, prev_type = 0; uint16_t dclass, prev_dclass = 0; uint32_t rrset_flags = 0; hashvalue_t hash = 0; struct rrset_parse* rrset = NULL; int r; if(num_rrs == 0) return 0; if(sldns_buffer_remaining(pkt) <= 0) return LDNS_RCODE_FORMERR; for(i=0; i<num_rrs; i++) { /* parse this RR. */ dname = sldns_buffer_current(pkt); if((dnamelen = pkt_dname_len(pkt)) == 0) return LDNS_RCODE_FORMERR; if(sldns_buffer_remaining(pkt) < 10) /* type, class, ttl, len */ return LDNS_RCODE_FORMERR; type = sldns_buffer_read_u16(pkt); sldns_buffer_read(pkt, &dclass, sizeof(dclass)); if(0) { /* debug show what is being parsed. */ if(type == LDNS_RR_TYPE_RRSIG) { uint16_t t; if(pkt_rrsig_covered(pkt, sldns_buffer_current(pkt), &t)) fprintf(stderr, "parse of %s(%d) [%s(%d)]", sldns_rr_descript(type)? sldns_rr_descript(type)->_name: "??", (int)type, sldns_rr_descript(t)? sldns_rr_descript(t)->_name: "??", (int)t); } else fprintf(stderr, "parse of %s(%d)", sldns_rr_descript(type)? sldns_rr_descript(type)->_name: "??", (int)type); fprintf(stderr, " %s(%d) ", sldns_lookup_by_id(sldns_rr_classes, (int)ntohs(dclass))?sldns_lookup_by_id( sldns_rr_classes, (int)ntohs(dclass))->name: "??", (int)ntohs(dclass)); dname_print(stderr, pkt, dname); fprintf(stderr, "\n"); } /* see if it is part of an existing RR set */ if(!find_rrset(msg, pkt, dname, dnamelen, type, dclass, &hash, &rrset_flags, &prev_dname_f, &prev_dname_l, &prev_dnamelen, &prev_type, &prev_dclass, &rrset, section, region)) return LDNS_RCODE_SERVFAIL; if(!rrset) { /* it is a new RR set. hash&flags already calculated.*/ (*num_rrsets)++; rrset = new_rrset(msg, dname, dnamelen, type, dclass, hash, rrset_flags, section, region); if(!rrset) return LDNS_RCODE_SERVFAIL; } else if(0) { fprintf(stderr, "is part of existing: "); dname_print(stderr, pkt, rrset->dname); fprintf(stderr, " type %s(%d)\n", sldns_rr_descript(rrset->type)? sldns_rr_descript(rrset->type)->_name: "??", (int)rrset->type); } /* add to rrset. */ if((r=add_rr_to_rrset(rrset, pkt, msg, region, section, type)) != 0) return r; } return 0; }