]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
dump_infra and flush_infra commands for unbound-control.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 26 Oct 2010 09:08:33 +0000 (09:08 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 26 Oct 2010 09:08:33 +0000 (09:08 +0000)
git-svn-id: file:///svn/unbound/trunk@2306 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/remote.c
doc/Changelog
doc/unbound-control.8.in
services/cache/infra.c
services/cache/infra.h
smallapp/unbound-control.c

index 3a1c32fa76c30571155420053447a44f0423d794..3e14bc709b6492213822567e8ce1b22b4c92019e 100644 (file)
@@ -59,6 +59,7 @@
 #include "util/module.h"
 #include "services/listen_dnsport.h"
 #include "services/cache/rrset.h"
+#include "services/cache/infra.h"
 #include "services/mesh.h"
 #include "services/localzone.h"
 #include "util/storage/slabhash.h"
@@ -1097,6 +1098,25 @@ do_flush_stats(SSL* ssl, struct worker* worker)
        send_ok(ssl);
 }
 
+/** flush infra cache */
+static void
+do_flush_infra(SSL* ssl, struct worker* worker, char* arg)
+{
+       struct sockaddr_storage addr;
+       socklen_t len;
+       if(strcmp(arg, "all") == 0) {
+               slabhash_clear(worker->env.infra_cache->hosts);
+               send_ok(ssl);
+               return;
+       }
+       if(!ipstrtoaddr(arg, UNBOUND_DNS_PORT, &addr, &len)) {
+               (void)ssl_printf(ssl, "error parsing ip addr: '%s'\n", arg);
+               return;
+       }
+       infra_remove_host(worker->env.infra_cache, &addr, len);
+       send_ok(ssl);
+}
+
 /** flush requestlist */
 static void
 do_flush_requestlist(SSL* ssl, struct worker* worker)
@@ -1494,6 +1514,90 @@ do_dump_requestlist(SSL* ssl, struct worker* worker)
        }
 }
 
+/** structure for argument data for dump infra host */
+struct infra_arg {
+       /** the infra cache */
+       struct infra_cache* infra;
+       /** the SSL connection */
+       SSL* ssl;
+       /** the time now */
+       uint32_t now;
+       /** ipstr */
+       char* ipstr;
+};
+
+/** callback for every lame element in the infra cache */
+static void
+dump_infra_lame(struct lruhash_entry* e, void* arg)
+{
+       struct infra_arg* a = (struct infra_arg*)arg;
+       struct infra_lame_key* k = (struct infra_lame_key*)e->key;
+       struct infra_lame_data* d = (struct infra_lame_data*)e->data;
+       ldns_rdf* rdf;
+       size_t pos;
+       char* nm;
+       /* skip expired */
+       if(d->ttl < a->now) {
+               return;
+       }
+       /* use ldns print for domain name */
+       if(ldns_wire2dname(&rdf, k->zonename, k->namelen, &pos)
+               != LDNS_STATUS_OK)
+               return;
+       nm = ldns_rdf2str(rdf);
+       ldns_rdf_deep_free(rdf);
+       if(!ssl_printf(a->ssl, "%s lame %s ttl %d dnssec %d rec %d "
+               "A %d other %d\n", a->ipstr, nm, (int)(d->ttl - a->now),
+               d->isdnsseclame, d->rec_lame, d->lame_type_A, d->lame_other)) {
+               free(nm);
+               return;
+       }
+       free(nm);
+}
+
+/** callback for every host element in the infra cache */
+static void
+dump_infra_host(struct lruhash_entry* e, void* arg)
+{
+       struct infra_arg* a = (struct infra_arg*)arg;
+       struct infra_host_key* k = (struct infra_host_key*)e->key;
+       struct infra_host_data* d = (struct infra_host_data*)e->data;
+       char ip_str[1024];
+       addr_to_str(&k->addr, k->addrlen, ip_str, sizeof(ip_str));
+       a->ipstr = ip_str;
+       /* skip expired stuff (only backed off) */
+       if(d->ttl < a->now) {
+               if(d->backoff != INFRA_BACKOFF_INITIAL) {
+                       if(!ssl_printf(a->ssl, "%s expired, backoff is %d\n",
+                               ip_str, (int)d->backoff))
+                               return;
+               }
+               if(d->lameness)
+                       lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg);
+               return;
+       }
+       if(!ssl_printf(a->ssl, "%s ttl %d ping %d var %d rtt %d rto %d "
+               "backoff %d ednsknown %d edns %d\n",
+               ip_str, (int)(d->ttl - a->now),
+               d->rtt.srtt, d->rtt.rttvar, rtt_notimeout(&d->rtt), d->rtt.rto,
+               (int)d->backoff, (int)d->edns_lame_known, (int)d->edns_version
+               ))
+               return;
+       if(d->lameness)
+               lruhash_traverse(d->lameness, 0, &dump_infra_lame, arg);
+}
+
+/** do the dump_infra command */
+static void
+do_dump_infra(SSL* ssl, struct worker* worker)
+{
+       struct infra_arg arg;
+       arg.infra = worker->env.infra_cache;
+       arg.ssl = ssl;
+       arg.now = *worker->env.now;
+       slabhash_traverse(arg.infra->hosts, 0, &dump_infra_host, (void*)&arg);
+}
+
 /** do the log_reopen command */
 static void
 do_log_reopen(SSL* ssl, struct worker* worker)
@@ -1725,10 +1829,14 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
                do_flush_zone(ssl, worker, skipwhite(p+10));
        } else if(cmdcmp(p, "flush_type", 10)) {
                do_flush_type(ssl, worker, skipwhite(p+10));
+       } else if(cmdcmp(p, "flush_infra", 11)) {
+               do_flush_infra(ssl, worker, skipwhite(p+11));
        } else if(cmdcmp(p, "flush", 5)) {
                do_flush_name(ssl, worker, skipwhite(p+5));
        } else if(cmdcmp(p, "dump_requestlist", 16)) {
                do_dump_requestlist(ssl, worker);
+       } else if(cmdcmp(p, "dump_infra", 10)) {
+               do_dump_infra(ssl, worker);
        } else if(cmdcmp(p, "log_reopen", 10)) {
                do_log_reopen(ssl, worker);
        } else if(cmdcmp(p, "set_option", 10)) {
index 1c52aa83520f5ce7426fcdadececd854c78f0d47..3b37ad762d4c8c0ec3234f2831410ff01f734a21 100644 (file)
@@ -1,3 +1,6 @@
+26 October 2010: Wouter
+       - dump_infra and flush_infra commands for unbound-control.
+
 25 October 2010: Wouter
        - Configure errors if ldns is not found.
 
index 5c6cb2c1bd1599814e3778900ffbe4ff6e06c98f..29a4502bce6cfeb5a549c1917f072ddeb21b7543 100644 (file)
@@ -142,6 +142,14 @@ Show what is worked on.  Prints all queries that the server is currently
 working on.  Prints the time that users have been waiting.  For internal
 requests, no time is printed.  And then prints out the module status.
 .TP
+.B flush_infra \fIall|IP
+If all then entire infra cache is emptied.  If a specific IP address, the
+entry for that address is removed from the cache.  It contains EDNS, ping
+and lameness data.
+.TP
+.B dump_infra
+Show the contents of the infra cache.
+.TP
 .B set_option \fIopt: val
 Set the option to the given value without a reload.  The cache is therefore
 not flushed.  The option must end with a ':' and whitespace must be between the
index a2cd5996fbd501bd3656290d96638a71459a3f93..6f28283c1c0a1bcf964117e28fe3bc71fd59dbbf 100644 (file)
@@ -155,6 +155,19 @@ hash_addr(struct sockaddr_storage* addr, socklen_t addrlen)
        return h;
 }
 
+void 
+infra_remove_host(struct infra_cache* infra,
+        struct sockaddr_storage* addr, socklen_t addrlen)
+{
+       struct infra_host_key k;
+       k.addrlen = addrlen;
+       memcpy(&k.addr, addr, addrlen);
+       k.entry.hash = hash_addr(addr, addrlen);
+       k.entry.key = (void*)&k;
+       k.entry.data = NULL;
+       slabhash_remove(infra->hosts, k.entry.hash, &k);
+}
+
 /** lookup version that does not check host ttl (you check it) */
 static struct lruhash_entry* 
 infra_lookup_host_nottl(struct infra_cache* infra,
index 956edd23ffe6e8f541be1b8277d1ef7cd8add3b6..58ea7190c1f337555a4f9fd94c6bb3c3ca47ad84 100644 (file)
@@ -144,6 +144,10 @@ struct infra_cache* infra_create(struct config_file* cfg);
  */
 void infra_delete(struct infra_cache* infra);
 
+/** explicitly delete an infra host element */
+void infra_remove_host(struct infra_cache* infra,
+        struct sockaddr_storage* addr, socklen_t addrlen);
+
 /**
  * Adjust infra cache to use updated configuration settings.
  * This may clean the cache. Operates a bit like realloc.
index 57741dd2edb03686afc3d64c6c3d5348c9ec7716..6b719f84e88eb65ba6d703a852e25b7b88ec191d 100644 (file)
@@ -96,6 +96,8 @@ usage()
        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("  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");
        printf("  get_option opt                get option value\n");
        printf("  list_stubs                    list stub-zones and root hints in use\n");