diff options
Diffstat (limited to 'external/unbound/smallapp')
-rw-r--r-- | external/unbound/smallapp/unbound-anchor.c | 41 | ||||
-rw-r--r-- | external/unbound/smallapp/unbound-checkconf.c | 88 | ||||
-rw-r--r-- | external/unbound/smallapp/unbound-control.c | 378 | ||||
-rw-r--r-- | external/unbound/smallapp/unbound-host.c | 4 | ||||
-rw-r--r-- | external/unbound/smallapp/worker_cb.c | 26 |
5 files changed, 476 insertions, 61 deletions
diff --git a/external/unbound/smallapp/unbound-anchor.c b/external/unbound/smallapp/unbound-anchor.c index 81bb896f7..2828088d9 100644 --- a/external/unbound/smallapp/unbound-anchor.c +++ b/external/unbound/smallapp/unbound-anchor.c @@ -37,7 +37,8 @@ * \file * * This file checks to see that the current 5011 keys work to prime the - * current root anchor. If not a certificate is used to update the anchor. + * current root anchor. If not a certificate is used to update the anchor, + * with RFC7958 https xml fetch. * * This is a concept solution for distribution of the DNSSEC root * trust anchor. It is a small tool, called "unbound-anchor", that @@ -47,7 +48,7 @@ * Management-Abstract: * * first run: fill root.key file with hardcoded DS record. * * mostly: use RFC5011 tracking, quick . DNSKEY UDP query. - * * failover: use builtin certificate, do https and update. + * * failover: use RFC7958 builtin certificate, do https and update. * Special considerations: * * 30-days RFC5011 timer saves a lot of https traffic. * * DNSKEY probe must be NOERROR, saves a lot of https traffic. @@ -77,7 +78,7 @@ * the file contains a list of normal DNSKEY/DS records, and uses that to * bootstrap 5011 (the KSK is made VALID). * - * The certificate update is done by fetching root-anchors.xml and + * The certificate RFC7958 update is done by fetching root-anchors.xml and * root-anchors.p7s via SSL. The HTTPS certificate can be logged but is * not validated (https for channel security; the security comes from the * certificate). The 'data.iana.org' domain name A and AAAA are resolved @@ -171,7 +172,7 @@ struct ip_list { /** Give unbound-anchor usage, and exit (1). */ static void -usage() +usage(void) { printf("Usage: unbound-anchor [opts]\n"); printf(" Setup or update root anchor. " @@ -240,7 +241,10 @@ static const char* get_builtin_ds(void) { return -". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n"; +/* anchor 19036 is from 2010 */ +/* anchor 20326 is from 2017 */ +". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n" +". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n"; } /** print hex data */ @@ -419,8 +423,14 @@ read_builtin_cert(void) { const char* builtin_cert = get_builtin_cert(); STACK_OF(X509)* sk; - BIO *bio = BIO_new_mem_buf((void*)builtin_cert, - (int)strlen(builtin_cert)); + BIO *bio; + char* d = strdup(builtin_cert); /* to avoid const warnings in the + changed prototype of BIO_new_mem_buf */ + if(!d) { + if(verb) printf("out of memory\n"); + exit(0); + } + bio = BIO_new_mem_buf(d, (int)strlen(d)); if(!bio) { if(verb) printf("out of memory\n"); exit(0); @@ -431,6 +441,7 @@ read_builtin_cert(void) exit(0); } BIO_free(bio); + free(d); return sk; } @@ -1836,7 +1847,7 @@ write_unsigned_root(const char* root_anchor_file) #ifdef HAVE_FSYNC fsync(fileno(out)); #else - FlushFileBuffers((HANDLE)_fileno(out)); + FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(out))); #endif fclose(out); } @@ -1868,7 +1879,7 @@ write_root_anchor(const char* root_anchor_file, BIO* ds) #ifdef HAVE_FSYNC fsync(fileno(out)); #else - FlushFileBuffers((HANDLE)_fileno(out)); + FlushFileBuffers((HANDLE)_get_osfhandle(_fileno(out))); #endif fclose(out); } @@ -2310,10 +2321,22 @@ int main(int argc, char* argv[]) if(argc != 0) usage(); +#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS ERR_load_crypto_strings(); +#endif ERR_load_SSL_strings(); +#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO) OpenSSL_add_all_algorithms(); +#else + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS + | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); +#endif +#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) (void)SSL_library_init(); +#else + (void)OPENSSL_init_ssl(0, NULL); +#endif if(dolist) do_list_builtin(); diff --git a/external/unbound/smallapp/unbound-checkconf.c b/external/unbound/smallapp/unbound-checkconf.c index ec0771306..ddf8b3a75 100644 --- a/external/unbound/smallapp/unbound-checkconf.c +++ b/external/unbound/smallapp/unbound-checkconf.c @@ -53,6 +53,8 @@ #include "iterator/iter_hints.h" #include "validator/validator.h" #include "services/localzone.h" +#include "services/view.h" +#include "respip/respip.h" #include "sldns/sbuffer.h" #ifdef HAVE_GETOPT_H #include <getopt.h> @@ -72,7 +74,7 @@ /** Give checkconf usage, and exit (1). */ static void -usage() +usage(void) { printf("Usage: unbound-checkconf [file]\n"); printf(" Checks unbound configuration file for errors.\n"); @@ -97,7 +99,10 @@ static void print_option(struct config_file* cfg, const char* opt, int final) { if(strcmp(opt, "pidfile") == 0 && final) { - printf("%s\n", fname_after_chroot(cfg->pidfile, cfg, 1)); + char *p = fname_after_chroot(cfg->pidfile, cfg, 1); + if(!p) fatal_exit("out of memory"); + printf("%s\n", p); + free(p); return; } if(!config_get_option(cfg, opt, config_print_func, stdout)) @@ -115,12 +120,15 @@ check_mod(struct config_file* cfg, struct module_func_block* fb) env.scratch_buffer = sldns_buffer_new(BUFSIZ); if(!env.scratch || !env.scratch_buffer) fatal_exit("out of memory"); + if(!edns_known_options_init(&env)) + fatal_exit("out of memory"); if(!(*fb->init)(&env, 0)) { fatal_exit("bad config for %s module", fb->name); } (*fb->deinit)(&env, 0); sldns_buffer_free(env.scratch_buffer); regional_destroy(env.scratch); + edns_known_options_delete(&env); } /** check localzones */ @@ -135,6 +143,27 @@ localzonechecks(struct config_file* cfg) local_zones_delete(zs); } +/** check view and response-ip configuration */ +static void +view_and_respipchecks(struct config_file* cfg) +{ + struct views* views = NULL; + struct respip_set* respip = NULL; + int ignored = 0; + if(!(views = views_create())) + fatal_exit("Could not create views: out of memory"); + if(!(respip = respip_set_create())) + fatal_exit("Could not create respip set: out of memory"); + if(!views_apply_cfg(views, cfg)) + fatal_exit("Could not set up views"); + if(!respip_global_apply_cfg(respip, cfg)) + fatal_exit("Could not setup respip set"); + if(!respip_views_apply_cfg(views, cfg, &ignored)) + fatal_exit("Could not setup per-view respip sets"); + views_delete(views); + respip_set_delete(respip); +} + /** emit warnings for IP in hosts */ static void warn_hosts(const char* typ, struct config_stub* list) @@ -161,6 +190,7 @@ warn_hosts(const char* typ, struct config_stub* list) static void interfacechecks(struct config_file* cfg) { + int d; struct sockaddr_storage a; socklen_t alen; int i, j; @@ -177,8 +207,8 @@ interfacechecks(struct config_file* cfg) } } for(i=0; i<cfg->num_out_ifs; i++) { - if(!ipstrtoaddr(cfg->out_ifs[i], UNBOUND_DNS_PORT, - &a, &alen)) { + if(!ipstrtoaddr(cfg->out_ifs[i], UNBOUND_DNS_PORT, &a, &alen) && + !netblockstrtoaddr(cfg->out_ifs[i], UNBOUND_DNS_PORT, &a, &alen, &d)) { fatal_exit("cannot parse outgoing-interface " "specified as '%s'", cfg->out_ifs[i]); } @@ -330,6 +360,8 @@ morechecks(struct config_file* cfg, const char* fname) fatal_exit("num_threads value weird"); if(!cfg->do_ip4 && !cfg->do_ip6) fatal_exit("ip4 and ip6 are both disabled, pointless"); + if(!cfg->do_ip6 && cfg->prefer_ip6) + fatal_exit("cannot prefer and disable ip6, pointless"); if(!cfg->do_udp && !cfg->do_tcp) fatal_exit("udp and tcp are both disabled, pointless"); if(cfg->edns_buffer_size > cfg->msg_buffer_size) @@ -397,11 +429,17 @@ morechecks(struct config_file* cfg, const char* fname) /* remove chroot setting so that modules are not stripping pathnames*/ free(cfg->chrootdir); cfg->chrootdir = NULL; - + + /* There should be no reason for 'respip' module not to work with + * dns64, but it's not explicitly confirmed, so the combination is + * excluded below. It's simply unknown yet for the combination of + * respip and other modules. */ if(strcmp(cfg->module_conf, "iterator") != 0 && strcmp(cfg->module_conf, "validator iterator") != 0 && strcmp(cfg->module_conf, "dns64 validator iterator") != 0 && strcmp(cfg->module_conf, "dns64 iterator") != 0 + && strcmp(cfg->module_conf, "respip iterator") != 0 + && strcmp(cfg->module_conf, "respip validator iterator") != 0 #ifdef WITH_PYTHONMODULE && strcmp(cfg->module_conf, "python iterator") != 0 && strcmp(cfg->module_conf, "python validator iterator") != 0 @@ -412,6 +450,35 @@ morechecks(struct config_file* cfg, const char* fname) && strcmp(cfg->module_conf, "python dns64 iterator") != 0 && strcmp(cfg->module_conf, "python dns64 validator iterator") != 0 #endif +#ifdef USE_CACHEDB + && strcmp(cfg->module_conf, "validator cachedb iterator") != 0 + && strcmp(cfg->module_conf, "cachedb iterator") != 0 + && strcmp(cfg->module_conf, "dns64 validator cachedb iterator") != 0 + && strcmp(cfg->module_conf, "dns64 cachedb iterator") != 0 +#endif +#if defined(WITH_PYTHONMODULE) && defined(USE_CACHEDB) + && strcmp(cfg->module_conf, "python dns64 cachedb iterator") != 0 + && strcmp(cfg->module_conf, "python dns64 validator cachedb iterator") != 0 + && strcmp(cfg->module_conf, "dns64 python cachedb iterator") != 0 + && strcmp(cfg->module_conf, "dns64 python validator cachedb iterator") != 0 + && strcmp(cfg->module_conf, "python cachedb iterator") != 0 + && strcmp(cfg->module_conf, "python validator cachedb iterator") != 0 + && strcmp(cfg->module_conf, "cachedb python iterator") != 0 + && strcmp(cfg->module_conf, "validator cachedb python iterator") != 0 + && strcmp(cfg->module_conf, "validator python cachedb iterator") != 0 +#endif +#ifdef CLIENT_SUBNET + && strcmp(cfg->module_conf, "subnetcache iterator") != 0 + && strcmp(cfg->module_conf, "subnetcache validator iterator") != 0 +#endif +#if defined(WITH_PYTHONMODULE) && defined(CLIENT_SUBNET) + && strcmp(cfg->module_conf, "python subnetcache iterator") != 0 + && strcmp(cfg->module_conf, "subnetcache python iterator") != 0 + && strcmp(cfg->module_conf, "subnetcache validator iterator") != 0 + && strcmp(cfg->module_conf, "python subnetcache validator iterator") != 0 + && strcmp(cfg->module_conf, "subnetcache python validator iterator") != 0 + && strcmp(cfg->module_conf, "subnetcache validator python iterator") != 0 +#endif ) { fatal_exit("module conf '%s' is not known to work", cfg->module_conf); @@ -421,7 +488,9 @@ morechecks(struct config_file* cfg, const char* fname) if(cfg->username && cfg->username[0]) { if(getpwnam(cfg->username) == NULL) fatal_exit("user '%s' does not exist.", cfg->username); +# ifdef HAVE_ENDPWENT endpwent(); +# endif } #endif if(cfg->remote_control_enable && cfg->remote_control_use_cert) { @@ -438,6 +507,7 @@ morechecks(struct config_file* cfg, const char* fname) } localzonechecks(cfg); + view_and_respipchecks(cfg); } /** check forwards */ @@ -466,14 +536,22 @@ check_hints(struct config_file* cfg) static void checkconf(const char* cfgfile, const char* opt, int final) { + char oldwd[4096]; struct config_file* cfg = config_create(); if(!cfg) fatal_exit("out of memory"); + oldwd[0] = 0; + if(!getcwd(oldwd, sizeof(oldwd))) { + log_err("cannot getcwd: %s", strerror(errno)); + oldwd[0] = 0; + } if(!config_read(cfg, cfgfile, NULL)) { /* config_read prints messages to stderr */ config_delete(cfg); exit(1); } + if(oldwd[0] && chdir(oldwd) == -1) + log_err("cannot chdir(%s): %s", oldwd, strerror(errno)); if(opt) { print_option(cfg, opt, final); config_delete(cfg); diff --git a/external/unbound/smallapp/unbound-control.c b/external/unbound/smallapp/unbound-control.c index fac73b099..6cd4e7086 100644 --- a/external/unbound/smallapp/unbound-control.c +++ b/external/unbound/smallapp/unbound-control.c @@ -58,14 +58,24 @@ #include "util/config_file.h" #include "util/locks.h" #include "util/net_help.h" +#include "util/shm_side/shm_main.h" +#include "daemon/stats.h" +#include "sldns/wire2str.h" +#include "sldns/pkthdr.h" +#ifdef HAVE_SYS_IPC_H +#include "sys/ipc.h" +#endif +#ifdef HAVE_SYS_SHM_H +#include "sys/shm.h" +#endif #ifdef HAVE_SYS_UN_H #include <sys/un.h> #endif /** Give unbound-control usage, and exit (1). */ static void -usage() +usage(void) { printf("Usage: unbound-control [options] command\n"); printf(" Remote control utility for unbound server.\n"); @@ -81,6 +91,9 @@ usage() printf(" (this flushes data, stats, requestlist)\n"); printf(" stats print statistics\n"); printf(" stats_noreset peek at statistics\n"); +#ifdef HAVE_SHMGET + printf(" stats_shm print statistics using shm\n"); +#endif printf(" status display status of server\n"); printf(" verbosity <number> change logging detail\n"); printf(" log_reopen close and open the logfile\n"); @@ -89,6 +102,9 @@ usage() printf(" local_data <RR data...> add local data, for example\n"); printf(" local_data www.example.com A 192.0.2.1\n"); printf(" local_data_remove <name> remove local RR data from name\n"); + printf(" local_zones, local_zones_remove, local_datas, local_datas_remove\n"); + printf(" same, but read list from stdin\n"); + printf(" (one entry per line).\n"); printf(" dump_cache print cache to stdout\n"); printf(" load_cache load cache from stdin\n"); printf(" lookup <name> print nameservers for name\n"); @@ -102,7 +118,7 @@ usage() printf(" flush_negative flush all negative data\n"); printf(" flush_stats flush statistics, make zero\n"); printf(" flush_requestlist drop queries that are worked on\n"); - printf(" dump_requestlist show what is worked on\n"); + printf(" dump_requestlist show what is worked on by first thread\n"); printf(" flush_infra [all | ip] remove ping, edns for one IP or all\n"); printf(" dump_infra show ping and edns entries\n"); printf(" set_option opt: val set option to value, no reload\n"); @@ -124,13 +140,270 @@ usage() printf(" or off to turn off root forwarding\n"); printf(" or give list of ip addresses\n"); printf(" ratelimit_list [+a] list ratelimited domains\n"); + printf(" ip_ratelimit_list [+a] list ratelimited ip addresses\n"); printf(" +a list all, also not ratelimited\n"); + printf(" view_list_local_zones view list local-zones in view\n"); + printf(" view_list_local_data view list local-data RRs in view\n"); + printf(" view_local_zone view name type add local-zone in view\n"); + printf(" view_local_zone_remove view name remove local-zone in view\n"); + printf(" view_local_data view RR... add local-data in view\n"); + printf(" view_local_data_remove view name remove local-data in view\n"); printf("Version %s\n", PACKAGE_VERSION); printf("BSD licensed, see LICENSE in source package for details.\n"); printf("Report bugs to %s\n", PACKAGE_BUGREPORT); exit(1); } +#ifdef HAVE_SHMGET +/** what to put on statistics lines between var and value, ": " or "=" */ +#define SQ "=" +/** if true, inhibits a lot of =0 lines from the stats output */ +static const int inhibit_zero = 1; +/** divide sum of timers to get average */ +static void +timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d) +{ +#ifndef S_SPLINT_S + size_t leftover; + if(d == 0) { + avg->tv_sec = 0; + avg->tv_usec = 0; + return; + } + avg->tv_sec = sum->tv_sec / d; + avg->tv_usec = sum->tv_usec / d; + /* handle fraction from seconds divide */ + leftover = sum->tv_sec - avg->tv_sec*d; + avg->tv_usec += (leftover*1000000)/d; +#endif +} + +/** print unsigned long stats value */ +#define PR_UL_NM(str, var) printf("%s."str SQ"%lu\n", nm, (unsigned long)(var)); +#define PR_UL(str, var) printf(str SQ"%lu\n", (unsigned long)(var)); +#define PR_UL_SUB(str, nm, var) printf(str".%s"SQ"%lu\n", nm, (unsigned long)(var)); +#define PR_TIMEVAL(str, var) printf(str SQ ARG_LL "d.%6.6d\n", \ + (long long)var.tv_sec, (int)var.tv_usec); +#define PR_LL(str, var) printf(str SQ ARG_LL"d\n", (long long)(var)); + +/** print stat block */ +static void pr_stats(const char* nm, struct stats_info* s) +{ + struct timeval avg; + PR_UL_NM("num.queries", s->svr.num_queries); + PR_UL_NM("num.queries_ip_ratelimited", + s->svr.num_queries_ip_ratelimited); + PR_UL_NM("num.cachehits", + s->svr.num_queries - s->svr.num_queries_missed_cache); + PR_UL_NM("num.cachemiss", s->svr.num_queries_missed_cache); + PR_UL_NM("num.prefetch", s->svr.num_queries_prefetch); + PR_UL_NM("num.zero_ttl", s->svr.zero_ttl_responses); + PR_UL_NM("num.recursivereplies", s->mesh_replies_sent); +#ifdef USE_DNSCRYPT + PR_UL_NM("num.dnscrypt.crypted", s->svr.num_query_dnscrypt_crypted); + PR_UL_NM("num.dnscrypt.cert", s->svr.num_query_dnscrypt_cert); + PR_UL_NM("num.dnscrypt.cleartext", s->svr.num_query_dnscrypt_cleartext); + PR_UL_NM("num.dnscrypt.malformed", + s->svr.num_query_dnscrypt_crypted_malformed); +#endif + printf("%s.requestlist.avg"SQ"%g\n", nm, + (s->svr.num_queries_missed_cache+s->svr.num_queries_prefetch)? + (double)s->svr.sum_query_list_size/ + (s->svr.num_queries_missed_cache+ + s->svr.num_queries_prefetch) : 0.0); + PR_UL_NM("requestlist.max", s->svr.max_query_list_size); + PR_UL_NM("requestlist.overwritten", s->mesh_jostled); + PR_UL_NM("requestlist.exceeded", s->mesh_dropped); + PR_UL_NM("requestlist.current.all", s->mesh_num_states); + PR_UL_NM("requestlist.current.user", s->mesh_num_reply_states); + timeval_divide(&avg, &s->mesh_replies_sum_wait, s->mesh_replies_sent); + printf("%s.", nm); + PR_TIMEVAL("recursion.time.avg", avg); + printf("%s.recursion.time.median"SQ"%g\n", nm, s->mesh_time_median); + PR_UL_NM("tcpusage", s->svr.tcp_accept_usage); +} + +/** print uptime */ +static void print_uptime(struct shm_stat_info* shm_stat) +{ + PR_TIMEVAL("time.now", shm_stat->time.now); + PR_TIMEVAL("time.up", shm_stat->time.up); + PR_TIMEVAL("time.elapsed", shm_stat->time.elapsed); +} + +/** print memory usage */ +static void print_mem(struct shm_stat_info* shm_stat) +{ + PR_LL("mem.cache.rrset", shm_stat->mem.rrset); + PR_LL("mem.cache.message", shm_stat->mem.msg); + PR_LL("mem.cache.iterator", shm_stat->mem.iter); + PR_LL("mem.cache.validator", shm_stat->mem.val); +#ifdef CLIENT_SUBNET + PR_LL("mem.cache.subnet", shm_stat->mem.subnet); +#endif +} + +/** print histogram */ +static void print_hist(struct stats_info* s) +{ + struct timehist* hist; + size_t i; + hist = timehist_setup(); + if(!hist) + fatal_exit("out of memory"); + timehist_import(hist, s->svr.hist, NUM_BUCKETS_HIST); + for(i=0; i<hist->num; i++) { + printf("histogram.%6.6d.%6.6d.to.%6.6d.%6.6d=%lu\n", + (int)hist->buckets[i].lower.tv_sec, + (int)hist->buckets[i].lower.tv_usec, + (int)hist->buckets[i].upper.tv_sec, + (int)hist->buckets[i].upper.tv_usec, + (unsigned long)hist->buckets[i].count); + } + timehist_delete(hist); +} + +/** print extended */ +static void print_extended(struct stats_info* s) +{ + int i; + char nm[16]; + + /* TYPE */ + for(i=0; i<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<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<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.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<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); + } + /* 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); + /* 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); +} + +/** print statistics out of memory structures */ +static void do_stats_shm(struct config_file* cfg, struct stats_info* stats, + struct shm_stat_info* shm_stat) +{ + int i; + char nm[16]; + for(i=0; i<cfg->num_threads; i++) { + snprintf(nm, sizeof(nm), "thread%d", i); + pr_stats(nm, &stats[i+1]); + } + pr_stats("total", &stats[0]); + print_uptime(shm_stat); + if(cfg->stat_extended) { + print_mem(shm_stat); + print_hist(stats); + print_extended(stats); + } +} +#endif /* HAVE_SHMGET */ + +/** print statistics from shm memory segment */ +static void print_stats_shm(const char* cfgfile) +{ +#ifdef HAVE_SHMGET + struct config_file* cfg; + struct stats_info* stats; + struct shm_stat_info* shm_stat; + int id_ctl, id_arr; + /* read config */ + if(!(cfg = config_create())) + fatal_exit("out of memory"); + if(!config_read(cfg, cfgfile, NULL)) + fatal_exit("could not read config file"); + /* get shm segments */ + id_ctl = shmget(cfg->shm_key, sizeof(int), SHM_R|SHM_W); + if(id_ctl == -1) { + fatal_exit("shmget(%d): %s", cfg->shm_key, strerror(errno)); + } + id_arr = shmget(cfg->shm_key+1, sizeof(int), SHM_R|SHM_W); + if(id_arr == -1) { + fatal_exit("shmget(%d): %s", cfg->shm_key+1, strerror(errno)); + } + shm_stat = (struct shm_stat_info*)shmat(id_ctl, NULL, 0); + if(shm_stat == (void*)-1) { + fatal_exit("shmat(%d): %s", id_ctl, strerror(errno)); + } + stats = (struct stats_info*)shmat(id_arr, NULL, 0); + if(stats == (void*)-1) { + fatal_exit("shmat(%d): %s", id_arr, strerror(errno)); + } + + /* print the stats */ + do_stats_shm(cfg, stats, shm_stat); + + /* shutdown */ + shmdt(shm_stat); + shmdt(stats); + config_delete(cfg); +#else + (void)cfgfile; +#endif /* HAVE_SHMGET */ +} + /** exit with ssl error */ static void ssl_err(const char* s) { @@ -153,13 +426,13 @@ setup_ctx(struct config_file* cfg) if(!s_cert || !c_key || !c_cert) fatal_exit("out of memory"); } - ctx = SSL_CTX_new(SSLv23_client_method()); + ctx = SSL_CTX_new(SSLv23_client_method()); if(!ctx) ssl_err("could not allocate SSL_CTX pointer"); - if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) + if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) != SSL_OP_NO_SSLv2) ssl_err("could not set SSL_OP_NO_SSLv2"); - if(cfg->remote_control_use_cert) { + if(cfg->remote_control_use_cert) { if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) != SSL_OP_NO_SSLv3) ssl_err("could not set SSL_OP_NO_SSLv3"); @@ -176,7 +449,10 @@ setup_ctx(struct config_file* cfg) free(c_cert); } else { /* Use ciphers that don't require authentication */ - if(!SSL_CTX_set_cipher_list(ctx, "aNULL")) +#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL + SSL_CTX_set_security_level(ctx, 0); +#endif + if(!SSL_CTX_set_cipher_list(ctx, "aNULL, eNULL")) ssl_err("Error setting NULL cipher!"); } return ctx; @@ -192,9 +468,13 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd) int fd; /* use svr or the first config entry */ if(!svr) { - if(cfg->control_ifs) + if(cfg->control_ifs) { svr = cfg->control_ifs->str; - else svr = "127.0.0.1"; + } else if(cfg->do_ip4) { + svr = "127.0.0.1"; + } else { + svr = "::1"; + } /* config 0 addr (everything), means ask localhost */ if(strcmp(svr, "0.0.0.0") == 0) svr = "127.0.0.1"; @@ -212,7 +492,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd) struct sockaddr_un* usock = (struct sockaddr_un *) &addr; usock->sun_family = AF_LOCAL; #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN - usock->sun_len = (socklen_t)sizeof(usock); + usock->sun_len = (unsigned)sizeof(usock); #endif (void)strlcpy(usock->sun_path, svr, sizeof(usock->sun_path)); addrlen = (socklen_t)sizeof(struct sockaddr_un); @@ -300,6 +580,15 @@ send_file(SSL* ssl, FILE* in, char* buf, size_t sz) } } +/** send end-of-file marker to server */ +static void +send_eof(SSL* ssl) +{ + char e[] = {0x04, 0x0a}; + if(SSL_write(ssl, e, (int)sizeof(e)) <= 0) + ssl_err("could not SSL_write end-of-file marker"); +} + /** send command and display result */ static int go_cmd(SSL* ssl, int quiet, int argc, char* argv[]) @@ -325,6 +614,13 @@ go_cmd(SSL* ssl, int quiet, int argc, char* argv[]) if(argc == 1 && strcmp(argv[0], "load_cache") == 0) { send_file(ssl, stdin, buf, sizeof(buf)); } + else if(argc == 1 && (strcmp(argv[0], "local_zones") == 0 || + strcmp(argv[0], "local_zones_remove") == 0 || + strcmp(argv[0], "local_datas") == 0 || + strcmp(argv[0], "local_datas_remove") == 0)) { + send_file(ssl, stdin, buf, sizeof(buf)); + send_eof(ssl); + } while(1) { ERR_clear_error(); @@ -411,32 +707,10 @@ int main(int argc, char* argv[]) log_init(NULL, 0, NULL); checklock_start(); #ifdef USE_WINSOCK - if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) - fatal_exit("WSAStartup failed: %s", wsa_strerror(r)); /* use registry config file in preference to compiletime location */ if(!(cfgfile=w_lookup_reg_str("Software\\Unbound", "ConfigFile"))) cfgfile = CONFIGFILE; #endif - - ERR_load_crypto_strings(); - ERR_load_SSL_strings(); - OpenSSL_add_all_algorithms(); - (void)SSL_library_init(); - - if(!RAND_status()) { - /* try to seed it */ - unsigned char buf[256]; - unsigned int seed=(unsigned)time(NULL) ^ (unsigned)getpid(); - unsigned int v = seed; - size_t i; - for(i=0; i<256/sizeof(v); i++) { - memmove(buf+i*sizeof(v), &v, sizeof(v)); - v = v*seed + (unsigned int)i; - } - RAND_seed(buf, 256); - log_warn("no entropy, seeding openssl PRNG with time\n"); - } - /* parse the options */ while( (c=getopt(argc, argv, "c:s:qh")) != -1) { switch(c) { @@ -466,11 +740,51 @@ int main(int argc, char* argv[]) strerror(errno)); } } + if(argc >= 1 && strcmp(argv[0], "stats_shm")==0) { + print_stats_shm(cfgfile); + return 0; + } + +#ifdef USE_WINSOCK + if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0) + fatal_exit("WSAStartup failed: %s", wsa_strerror(r)); +#endif + +#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS + ERR_load_crypto_strings(); +#endif + ERR_load_SSL_strings(); +#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO) + OpenSSL_add_all_algorithms(); +#else + OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS + | OPENSSL_INIT_ADD_ALL_DIGESTS + | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); +#endif +#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) + (void)SSL_library_init(); +#else + (void)OPENSSL_init_ssl(0, NULL); +#endif + + if(!RAND_status()) { + /* try to seed it */ + unsigned char buf[256]; + unsigned int seed=(unsigned)time(NULL) ^ (unsigned)getpid(); + unsigned int v = seed; + size_t i; + for(i=0; i<256/sizeof(v); i++) { + memmove(buf+i*sizeof(v), &v, sizeof(v)); + v = v*seed + (unsigned int)i; + } + RAND_seed(buf, 256); + log_warn("no entropy, seeding openssl PRNG with time\n"); + } ret = go(cfgfile, svr, quiet, argc, argv); #ifdef USE_WINSOCK - WSACleanup(); + WSACleanup(); #endif checklock_stop(); return ret; diff --git a/external/unbound/smallapp/unbound-host.c b/external/unbound/smallapp/unbound-host.c index 30fef51fd..d7a36a231 100644 --- a/external/unbound/smallapp/unbound-host.c +++ b/external/unbound/smallapp/unbound-host.c @@ -72,7 +72,7 @@ static int verb = 0; /** Give unbound-host usage, and exit (1). */ static void -usage() +usage(void) { printf("Usage: unbound-host [-vdhr46] [-c class] [-t type] hostname\n"); printf(" [-y key] [-f keyfile] [-F namedkeyfile]\n"); @@ -91,7 +91,7 @@ usage() printf(" -F keyfile read named.conf-style trust anchors.\n"); printf(" -C config use the specified unbound.conf (none read by default)\n"); printf(" -r read forwarder information from /etc/resolv.conf\n"); - printf(" breaks validation if the fwder does not do DNSSEC.\n"); + printf(" breaks validation if the forwarder does not do DNSSEC.\n"); printf(" -v be more verbose, shows nodata and security.\n"); printf(" -d debug, traces the action, -d -d shows more.\n"); printf(" -4 use ipv4 network, avoid ipv6.\n"); diff --git a/external/unbound/smallapp/worker_cb.c b/external/unbound/smallapp/worker_cb.c index 8193bec1b..e88e8c8d7 100644 --- a/external/unbound/smallapp/worker_cb.c +++ b/external/unbound/smallapp/worker_cb.c @@ -99,13 +99,13 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg)) log_assert(0); } -struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname), - size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype), - uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags), +struct outbound_entry* worker_send_query( + struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), - int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), + int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), - size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q)) + size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream), + struct module_qstate* ATTR_UNUSED(q)) { log_assert(0); return 0; @@ -131,13 +131,13 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg)) log_assert(0); } -struct outbound_entry* libworker_send_query(uint8_t* ATTR_UNUSED(qname), - size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype), - uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags), +struct outbound_entry* libworker_send_query( + struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), - int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), + int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), - size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q)) + size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(ssl_upstream), + struct module_qstate* ATTR_UNUSED(q)) { log_assert(0); return 0; @@ -223,8 +223,8 @@ struct order_id { int order_lock_cmp(const void* e1, const void* e2) { - struct order_id* o1 = (struct order_id*)e1; - struct order_id* o2 = (struct order_id*)e2; + const struct order_id* o1 = e1; + const struct order_id* o2 = e2; if(o1->thr < o2->thr) return -1; if(o1->thr > o2->thr) return 1; if(o1->instance < o2->instance) return -1; @@ -235,7 +235,7 @@ int order_lock_cmp(const void* e1, const void* e2) int codeline_cmp(const void* a, const void* b) { - return strcmp((const char*)a, (const char*)b); + return strcmp(a, b); } int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b)) |