mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-01-02 21:09:35 -05:00
dump_requestlist feature.
git-svn-id: file:///svn/unbound/trunk@1473 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
5c0e815e73
commit
5f6eb6d58e
4 changed files with 128 additions and 0 deletions
121
daemon/remote.c
121
daemon/remote.c
|
|
@ -62,6 +62,9 @@
|
|||
#include "validator/validator.h"
|
||||
#include "validator/val_kcache.h"
|
||||
#include "validator/val_kentry.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/outside_network.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
|
|
@ -1228,6 +1231,122 @@ do_status(SSL* ssl, struct worker* worker)
|
|||
return;
|
||||
}
|
||||
|
||||
/** get age for the mesh state */
|
||||
static void
|
||||
get_mesh_age(struct mesh_state* m, char* buf, size_t len,
|
||||
struct module_env* env)
|
||||
{
|
||||
if(m->reply_list) {
|
||||
struct timeval d;
|
||||
struct mesh_reply* r = m->reply_list;
|
||||
/* last reply is the oldest */
|
||||
while(r && r->next)
|
||||
r = r->next;
|
||||
timeval_subtract(&d, env->now_tv, &r->start_time);
|
||||
snprintf(buf, len, "%d.%6.6d", (int)d.tv_sec, (int)d.tv_usec);
|
||||
} else {
|
||||
snprintf(buf, len, "-");
|
||||
}
|
||||
}
|
||||
|
||||
/** get status of a mesh state */
|
||||
static void
|
||||
get_mesh_status(struct mesh_area* mesh, struct mesh_state* m,
|
||||
char* buf, size_t len)
|
||||
{
|
||||
enum module_ext_state s = m->s.ext_state[m->s.curmod];
|
||||
const char *modname = mesh->mods.mod[m->s.curmod]->name;
|
||||
size_t l;
|
||||
if(strcmp(modname, "iterator") == 0 && s == module_wait_reply &&
|
||||
m->s.minfo[m->s.curmod]) {
|
||||
/* break into iterator to find out who its waiting for */
|
||||
struct iter_qstate* qstate = (struct iter_qstate*)
|
||||
m->s.minfo[m->s.curmod];
|
||||
struct outbound_list* ol = &qstate->outlist;
|
||||
struct outbound_entry* e;
|
||||
snprintf(buf, len, "%s wait for", modname);
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
if(ol->first == NULL)
|
||||
snprintf(buf, len, " (empty_list)");
|
||||
for(e = ol->first; e; e = e->next) {
|
||||
int af = (int)((struct sockaddr_in*)&e->qsent->addr)
|
||||
->sin_family;
|
||||
void* sinaddr = &((struct sockaddr_in*)&e->qsent->addr)
|
||||
->sin_addr;
|
||||
if(addr_is_ip6(&e->qsent->addr, e->qsent->addrlen))
|
||||
sinaddr = &((struct sockaddr_in6*)
|
||||
&e->qsent->addr)->sin6_addr;
|
||||
|
||||
snprintf(buf, len, " ");
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
|
||||
if(inet_ntop(af, sinaddr, buf, (socklen_t)len) == 0) {
|
||||
snprintf(buf, len, "(inet_ntop_error)");
|
||||
}
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
}
|
||||
} else if(s == module_wait_subquery) {
|
||||
/* look in subs from mesh state to see what */
|
||||
char nm[257];
|
||||
struct mesh_state_ref* sub;
|
||||
snprintf(buf, len, "%s wants", modname);
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
if(m->sub_set.count == 0)
|
||||
snprintf(buf, len, " (empty_list)");
|
||||
RBTREE_FOR(sub, struct mesh_state_ref*, &m->sub_set) {
|
||||
char* t = ldns_rr_type2str(sub->s->s.qinfo.qtype);
|
||||
char* c = ldns_rr_class2str(sub->s->s.qinfo.qclass);
|
||||
dname_str(sub->s->s.qinfo.qname, nm);
|
||||
snprintf(buf, len, " %s %s %s", t, c, nm);
|
||||
l = strlen(buf);
|
||||
buf += l; len -= l;
|
||||
free(t);
|
||||
free(c);
|
||||
}
|
||||
} else {
|
||||
snprintf(buf, len, "%s is %s", modname, strextstate(s));
|
||||
}
|
||||
}
|
||||
|
||||
/** do the dump_requestlist command */
|
||||
static void
|
||||
do_dump_requestlist(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
struct mesh_area* mesh;
|
||||
struct mesh_state* m;
|
||||
int num = 0;
|
||||
char buf[257];
|
||||
char timebuf[32];
|
||||
char statbuf[10240];
|
||||
if(!ssl_printf(ssl, "thread #%d\n", worker->thread_num))
|
||||
return;
|
||||
if(!ssl_printf(ssl, "# type cl name seconds module status\n"))
|
||||
return;
|
||||
/* show worker mesh contents */
|
||||
mesh = worker->env.mesh;
|
||||
if(!mesh) return;
|
||||
RBTREE_FOR(m, struct mesh_state*, &mesh->all) {
|
||||
char* t = ldns_rr_type2str(m->s.qinfo.qtype);
|
||||
char* c = ldns_rr_class2str(m->s.qinfo.qclass);
|
||||
dname_str(m->s.qinfo.qname, buf);
|
||||
get_mesh_age(m, timebuf, sizeof(timebuf), &worker->env);
|
||||
get_mesh_status(mesh, m, statbuf, sizeof(statbuf));
|
||||
if(!ssl_printf(ssl, "%3d %4s %2s %s %s %s\n",
|
||||
num, t, c, buf, timebuf, statbuf)) {
|
||||
free(t);
|
||||
free(c);
|
||||
return;
|
||||
}
|
||||
num++;
|
||||
free(t);
|
||||
free(c);
|
||||
}
|
||||
}
|
||||
|
||||
/** tell other processes to execute the command */
|
||||
void
|
||||
distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd)
|
||||
|
|
@ -1301,6 +1420,8 @@ execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd,
|
|||
do_flush_type(ssl, worker, skipwhite(p+10));
|
||||
} else if(strncmp(p, "flush", 5) == 0) {
|
||||
do_flush_name(ssl, worker, skipwhite(p+5));
|
||||
} else if(strncmp(p, "dump_requestlist", 16) == 0) {
|
||||
do_dump_requestlist(ssl, worker);
|
||||
} else {
|
||||
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
- keys with rfc5011 REVOKE flag are skipped and not considered when
|
||||
validating data.
|
||||
- iana portlist updated
|
||||
- #226: dump_requestlist feature for unbound-control.
|
||||
|
||||
6 February 2009: Wouter
|
||||
- contrib contains specfile for fedora 1.2.1 (from Paul Wouters).
|
||||
|
|
|
|||
|
|
@ -115,6 +115,11 @@ Remove the name, type information from the cache.
|
|||
Remove all information at or below the name from the cache.
|
||||
The rrsets and key entries are removed so that new lookups will be performed.
|
||||
This needs to walk and inspect the entire cache, and is a slow operation.
|
||||
.TP
|
||||
.B dump_requestlist
|
||||
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.
|
||||
.SH "EXIT CODE"
|
||||
The unbound-control program exits with status code 1 on error, 0 on success.
|
||||
.SH "SET UP"
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ usage()
|
|||
printf(" flush_type [name] [type] flush name, type from cache\n");
|
||||
printf(" flush_zone [name] flush everything at or under name\n");
|
||||
printf(" from rr and dnssec caches\n");
|
||||
printf(" dump_requestlist show what is worked on\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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue