dns stats, support wraparound serials
authorMarko Kreen <markokr@gmail.com>
Fri, 21 Oct 2011 11:47:50 +0000 (14:47 +0300)
committerMarko Kreen <markokr@gmail.com>
Fri, 21 Oct 2011 11:47:50 +0000 (14:47 +0300)
include/dnslookup.h
src/admin.c
src/dnslookup.c

index 4c0d35fd18d2ce80f3567f873d0d1a2fe918f2bd..78d5719af49ec7952f60c89ef891b5e35c15c234 100644 (file)
@@ -33,3 +33,5 @@ const char *adns_get_backend(void);
 
 void adns_zone_cache_maint(struct DNSContext *ctx);
 
+void adns_info(struct DNSContext *ctx, int *names, int *zones, int *queries, int *pending);
+
index b51f41efa65049d681595bb29eb381a574173374..4de06c8131301d97a1c1fc3bae5964ce3948ccd3 100644 (file)
@@ -468,6 +468,14 @@ static bool admin_show_lists(PgSocket *admin, const char *arg)
        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;
 }
index 14e49329e40634b9e5532ea6a43bb32fab09c8c8..4e91c8f90483a56350e8c8da66580178863748dc 100644 (file)
@@ -114,6 +114,8 @@ struct DNSContext {
        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);
@@ -491,6 +493,11 @@ static bool impl_init(struct DNSContext *ctx)
        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;
@@ -662,11 +669,14 @@ static int impl_query_soa_serial(struct DNSContext *ctx, const char *zonename)
 
 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);
@@ -781,9 +791,11 @@ struct DNSToken *adns_resolve(struct DNSContext *ctx, const char *name, adns_cal
                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 */
@@ -800,6 +812,7 @@ struct DNSToken *adns_resolve(struct DNSContext *ctx, const char *name, adns_cal
                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);
@@ -874,6 +887,13 @@ void adns_cancel(struct DNSContext *ctx, struct DNSToken *tk)
        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
@@ -937,6 +957,8 @@ static void zone_register(struct DNSContext *ctx, struct DNSRequest *req)
                free(z);
                return;
        }
+       list_init(&z->host_list);
+       list_init(&z->lnode);
 
        /* link */
        aatree_insert(&ctx->zone_tree, (uintptr_t)z->zonename, &z->tnode);
@@ -1000,6 +1022,7 @@ static void zone_requeue(struct DNSContext *ctx, struct DNSZone *z)
                if (!req->done)
                        continue;
                req->res_ttl = 0;
+               ctx->active++;
                impl_launch_query(req);
        }
 }
@@ -1009,11 +1032,19 @@ static void got_zone_serial(struct DNSContext *ctx, uint32_t *serial)
        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;
@@ -1025,6 +1056,8 @@ static void got_zone_serial(struct DNSContext *ctx, uint32_t *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);