SENDLIST("login_clients", statlist_count(&login_client_list));
SENDLIST("free_servers", slab_free_count(server_cache));
SENDLIST("used_servers", slab_active_count(server_cache));
+ {
+ int names, zones, qry, pend;
+ adns_info(adns, &names, &zones, &qry, &pend);
+ SENDLIST("dns_names", names);
+ SENDLIST("dns_zones", zones);
+ SENDLIST("dns_queries", qry);
+ SENDLIST("dns_pending", pend);
+ }
admin_flush(admin, buf, "SHOW");
return true;
}
struct DNSZone *cur_zone;
struct event ev_zone_timer;
int zone_state;
+
+ int active; /* number of in-flight queries */
};
static void deliver_info(struct DNSRequest *req);
if (!dctx)
return false;
+ dns_add_srch(dctx, NULL);
+ dns_add_serv(dctx, NULL);
+ if (dns_add_serv(dctx, "127.0.0.1") < 0)
+ fatal_perror("dns_add_serv failed");
+
udns = calloc(1, sizeof(*udns));
if (!udns)
return false;
static void deliver_info(struct DNSRequest *req)
{
+ struct DNSContext *ctx = req->ctx;
struct DNSToken *ucb;
struct List *el;
const struct addrinfo *ai = req->current;
char sabuf[128];
+ ctx->active--;
+
loop:
/* get next req */
el = list_pop(&req->ucb_list);
list_init(&req->ucb_list);
list_init(&req->znode);
aatree_insert(&ctx->req_tree, (uintptr_t)req->name, &req->node);
- impl_launch_query(req);
zone_register(ctx, req);
+
+ ctx->active++;
+ impl_launch_query(req);
}
/* remember user callback */
if (req->res_ttl < get_cached_time()) {
log_noise("dns: ttl over: %s", req->name);
req_reset(req);
+ ctx->active++;
impl_launch_query(req);
} else {
deliver_info(req);
free(tk);
}
+void adns_info(struct DNSContext *ctx, int *names, int *zones, int *queries, int *pending)
+{
+ *names = ctx->req_tree.count;
+ *zones = ctx->zone_tree.count;
+ *queries = ctx->active;
+ *pending = 0;
+}
/*
* zone code
free(z);
return;
}
+ list_init(&z->host_list);
+ list_init(&z->lnode);
/* link */
aatree_insert(&ctx->zone_tree, (uintptr_t)z->zonename, &z->tnode);
if (!req->done)
continue;
req->res_ttl = 0;
+ ctx->active++;
impl_launch_query(req);
}
}
struct DNSZone *z = ctx->cur_zone;
struct List *el;
+ ctx->active--;
+
if (!ctx->zone_state || !z)
return;
+ log_debug("got_zone_serial: %u", serial ? *serial : 0);
+
if (serial) {
- if (*serial != z->serial) {
+ /* wraparound compare */
+ int32_t s1 = z->serial;
+ int32_t s2 = *serial;
+ int32_t ds = s2 - s1;
+ if (ds > 0) {
log_info("zone '%s' serial changed: old=%u new=%u",
z->zonename, z->serial, *serial);
z->serial = *serial;
if (el != &ctx->zone_list) {
z = container_of(el, struct DNSZone, lnode);
ctx->cur_zone = z;
+
+ ctx->active++;
impl_query_soa_serial(ctx, z->zonename);
} else {
launch_zone_timer(ctx);