/** nice string for type */ static void pretty_type(char* s, size_t len, int t) { char d[16]; sldns_wire2str_type_buf((uint16_t)t, d, sizeof(d)); snprintf(s, len, "%s", d); }
/** print result to file */ static void do_print(struct ub_result* result, char* file) { FILE* out = fopen(file, "w"); char s[65535], t[32]; int i; if(!out) { perror(file); fatal("fopen failed"); } i = 0; if(result->havedata) while(result->data[i]) { sldns_wire2str_rdata_buf((uint8_t*)result->data[i], (size_t)result->len[i], s, sizeof(s), (uint16_t)result->qtype); sldns_wire2str_type_buf((uint16_t)result->qtype, t, sizeof(t)); fprintf(out, "%s\t%s\t%s\n", result->qname, t, s); i++; } fclose(out); }
/** read root hints from file */ static int read_root_hints(struct iter_hints* hints, char* fname) { struct sldns_file_parse_state pstate; struct delegpt* dp; uint8_t rr[LDNS_RR_BUF_SIZE]; size_t rr_len, dname_len; int status; uint16_t c = LDNS_RR_CLASS_IN; FILE* f = fopen(fname, "r"); if(!f) { log_err("could not read root hints %s: %s", fname, strerror(errno)); return 0; } dp = delegpt_create_mlc(NULL); if(!dp) { log_err("out of memory reading root hints"); fclose(f); return 0; } verbose(VERB_QUERY, "Reading root hints from %s", fname); memset(&pstate, 0, sizeof(pstate)); pstate.lineno = 1; dp->has_parent_side_NS = 1; while(!feof(f)) { rr_len = sizeof(rr); dname_len = 0; status = sldns_fp2wire_rr_buf(f, rr, &rr_len, &dname_len, &pstate); if(status != 0) { log_err("reading root hints %s %d:%d: %s", fname, pstate.lineno, LDNS_WIREPARSE_OFFSET(status), sldns_get_errorstr_parse(status)); goto stop_read; } if(rr_len == 0) continue; /* EMPTY line, TTL or ORIGIN */ if(sldns_wirerr_get_type(rr, rr_len, dname_len) == LDNS_RR_TYPE_NS) { if(!delegpt_add_ns_mlc(dp, sldns_wirerr_get_rdata(rr, rr_len, dname_len), 0)) { log_err("out of memory reading root hints"); goto stop_read; } c = sldns_wirerr_get_class(rr, rr_len, dname_len); if(!dp->name) { if(!delegpt_set_name_mlc(dp, rr)) { log_err("out of memory."); goto stop_read; } } } else if(sldns_wirerr_get_type(rr, rr_len, dname_len) == LDNS_RR_TYPE_A && sldns_wirerr_get_rdatalen(rr, rr_len, dname_len) == INET_SIZE) { struct sockaddr_in sa; socklen_t len = (socklen_t)sizeof(sa); memset(&sa, 0, len); sa.sin_family = AF_INET; sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT); memmove(&sa.sin_addr, sldns_wirerr_get_rdata(rr, rr_len, dname_len), INET_SIZE); if(!delegpt_add_target_mlc(dp, rr, dname_len, (struct sockaddr_storage*)&sa, len, 0, 0)) { log_err("out of memory reading root hints"); goto stop_read; } } else if(sldns_wirerr_get_type(rr, rr_len, dname_len) == LDNS_RR_TYPE_AAAA && sldns_wirerr_get_rdatalen(rr, rr_len, dname_len) == INET6_SIZE) { struct sockaddr_in6 sa; socklen_t len = (socklen_t)sizeof(sa); memset(&sa, 0, len); sa.sin6_family = AF_INET6; sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT); memmove(&sa.sin6_addr, sldns_wirerr_get_rdata(rr, rr_len, dname_len), INET6_SIZE); if(!delegpt_add_target_mlc(dp, rr, dname_len, (struct sockaddr_storage*)&sa, len, 0, 0)) { log_err("out of memory reading root hints"); goto stop_read; } } else { char buf[17]; sldns_wire2str_type_buf(sldns_wirerr_get_type(rr, rr_len, dname_len), buf, sizeof(buf)); log_warn("root hints %s:%d skipping type %s", fname, pstate.lineno, buf); } } fclose(f); if(!dp->name) { log_warn("root hints %s: no NS content", fname); delegpt_free_mlc(dp); return 1; } if(!hints_insert(hints, c, dp, 0)) { return 0; } delegpt_log(VERB_QUERY, dp); return 1; stop_read: delegpt_free_mlc(dp); fclose(f); return 0; }
/** print extended */ static void print_extended(struct ub_stats_info* s) { int i; char nm[16]; /* TYPE */ for(i=0; i<UB_STATS_QTYPE_NUM; i++) { if(inhibit_zero && s->svr.qtype[i] == 0) continue; sldns_wire2str_type_buf((uint16_t)i, nm, sizeof(nm)); PR_UL_SUB("num.query.type", nm, s->svr.qtype[i]); } if(!inhibit_zero || s->svr.qtype_big) { PR_UL("num.query.type.other", s->svr.qtype_big); } /* CLASS */ for(i=0; i<UB_STATS_QCLASS_NUM; i++) { if(inhibit_zero && s->svr.qclass[i] == 0) continue; sldns_wire2str_class_buf((uint16_t)i, nm, sizeof(nm)); PR_UL_SUB("num.query.class", nm, s->svr.qclass[i]); } if(!inhibit_zero || s->svr.qclass_big) { PR_UL("num.query.class.other", s->svr.qclass_big); } /* OPCODE */ for(i=0; i<UB_STATS_OPCODE_NUM; i++) { if(inhibit_zero && s->svr.qopcode[i] == 0) continue; sldns_wire2str_opcode_buf(i, nm, sizeof(nm)); PR_UL_SUB("num.query.opcode", nm, s->svr.qopcode[i]); } /* transport */ PR_UL("num.query.tcp", s->svr.qtcp); PR_UL("num.query.tcpout", s->svr.qtcp_outgoing); PR_UL("num.query.tls", s->svr.qtls); PR_UL("num.query.ipv6", s->svr.qipv6); /* flags */ PR_UL("num.query.flags.QR", s->svr.qbit_QR); PR_UL("num.query.flags.AA", s->svr.qbit_AA); PR_UL("num.query.flags.TC", s->svr.qbit_TC); PR_UL("num.query.flags.RD", s->svr.qbit_RD); PR_UL("num.query.flags.RA", s->svr.qbit_RA); PR_UL("num.query.flags.Z", s->svr.qbit_Z); PR_UL("num.query.flags.AD", s->svr.qbit_AD); PR_UL("num.query.flags.CD", s->svr.qbit_CD); PR_UL("num.query.edns.present", s->svr.qEDNS); PR_UL("num.query.edns.DO", s->svr.qEDNS_DO); /* RCODE */ for(i=0; i<UB_STATS_RCODE_NUM; i++) { /* Always include RCODEs 0-5 */ if(inhibit_zero && i > LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0) continue; sldns_wire2str_rcode_buf(i, nm, sizeof(nm)); PR_UL_SUB("num.answer.rcode", nm, s->svr.ans_rcode[i]); } if(!inhibit_zero || s->svr.ans_rcode_nodata) { PR_UL("num.answer.rcode.nodata", s->svr.ans_rcode_nodata); } /* iteration */ PR_UL("num.query.ratelimited", s->svr.queries_ratelimited); /* validation */ PR_UL("num.answer.secure", s->svr.ans_secure); PR_UL("num.answer.bogus", s->svr.ans_bogus); PR_UL("num.rrset.bogus", s->svr.rrset_bogus); PR_UL("num.query.aggressive.NOERROR", s->svr.num_neg_cache_noerror); PR_UL("num.query.aggressive.NXDOMAIN", s->svr.num_neg_cache_nxdomain); /* threat detection */ PR_UL("unwanted.queries", s->svr.unwanted_queries); PR_UL("unwanted.replies", s->svr.unwanted_replies); /* cache counts */ PR_UL("msg.cache.count", s->svr.msg_cache_count); PR_UL("rrset.cache.count", s->svr.rrset_cache_count); PR_UL("infra.cache.count", s->svr.infra_cache_count); PR_UL("key.cache.count", s->svr.key_cache_count); #ifdef USE_DNSCRYPT PR_UL("dnscrypt_shared_secret.cache.count", s->svr.shared_secret_cache_count); PR_UL("num.query.dnscrypt.shared_secret.cachemiss", s->svr.num_query_dnscrypt_secret_missed_cache); PR_UL("dnscrypt_nonce.cache.count", s->svr.nonce_cache_count); PR_UL("num.query.dnscrypt.replay", s->svr.num_query_dnscrypt_replay); #endif /* USE_DNSCRYPT */ PR_UL("num.query.authzone.up", s->svr.num_query_authzone_up); PR_UL("num.query.authzone.down", s->svr.num_query_authzone_down); #ifdef CLIENT_SUBNET PR_UL("num.query.subnet", s->svr.num_query_subnet); PR_UL("num.query.subnet_cache", s->svr.num_query_subnet_cache); #endif }