aboutsummaryrefslogtreecommitdiff
path: root/external/unbound/smallapp
diff options
context:
space:
mode:
Diffstat (limited to 'external/unbound/smallapp')
-rw-r--r--external/unbound/smallapp/unbound-anchor.c41
-rw-r--r--external/unbound/smallapp/unbound-checkconf.c88
-rw-r--r--external/unbound/smallapp/unbound-control.c378
-rw-r--r--external/unbound/smallapp/unbound-host.c4
-rw-r--r--external/unbound/smallapp/worker_cb.c26
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))