]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
precise timers for roundtrip UDP timeouts.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 May 2007 06:24:01 +0000 (06:24 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 23 May 2007 06:24:01 +0000 (06:24 +0000)
git-svn-id: file:///svn/unbound/trunk@332 be551aaa-1e26-0410-a405-d3ace91eadb9

daemon/worker.c
doc/Changelog
services/outside_network.c
services/outside_network.h
testcode/fake_event.c
util/mini_event.c

index f3d51d1e374e6ee698fc9a8b108091eb5aa860ac..165cc9a593c7200261a45af14ea24351247f53fe 100644 (file)
@@ -730,8 +730,9 @@ worker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr,
                        timeout, worker_handle_reply, q->work_info, 
                        worker->rndstate) != 0;
        }
-       return pending_udp_query(worker->back, pkt, addr, addrlen, timeout,
-               worker_handle_reply, q->work_info, worker->rndstate) != 0;
+       return pending_udp_query(worker->back, pkt, addr, addrlen, 
+               timeout*1000, worker_handle_reply, q->work_info, 
+               worker->rndstate) != 0;
 }
 
 struct outbound_entry*
index 53b8af6a50337d092fbf74043ec034aae7919e11..e1fa1339bad1d3fdb056312a82748c285c6803e8 100644 (file)
@@ -1,3 +1,7 @@
+23 May 2007: Wouter
+       - outside network does precise timers for roundtrip estimates for rtt
+         and for setting timeout for UDP. Pending_udp takes milliseconds.
+
 22 May 2007: Wouter
        - outbound query list for modules and support to callback with the
          outbound entry to the module.
index 0fcb7a4a1d32bb3fe34b36036684a5a285433102..e312ebe5781f155881a5364da38eaf24b22225b6 100644 (file)
@@ -745,8 +745,8 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
 
        /* system calls to set timeout after sending UDP to make roundtrip
           smaller. */
-       tv.tv_sec = timeout;
-       tv.tv_usec = 0;
+       tv.tv_sec = timeout/1000;
+       tv.tv_usec = (timeout%1000)*1000;
        comm_timer_set(pend->timer, &tv);
        return pend;
 }
@@ -988,9 +988,11 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
                else    sq->status = serviced_query_UDP;
        }
        serviced_encode(sq, buff, sq->status == serviced_query_UDP_EDNS);
-       sq->last_sent_time = now;
-       /* round rtt to whole seconds for now. TODO better timing */
-       rtt = rtt/1000 + 1;
+       if(gettimeofday(&sq->last_sent_time, NULL) < 0) {
+               log_err("gettimeofday: %s", strerror(errno));
+               return 0;
+       }
+       verbose(VERB_DETAIL, "serviced query UDP timeout=%d msec", rtt);
        sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr, 
                sq->addrlen, rtt, serviced_udp_callback, sq, sq->outnet->rnd);
        if(!sq->pending)
@@ -1058,13 +1060,17 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
 {
        struct serviced_query* sq = (struct serviced_query*)arg;
        struct outside_network* outnet = sq->outnet;
-       time_t now = time(NULL);
-       int roundtime;
+       struct timeval now;
+       if(gettimeofday(&now, NULL) < 0) {
+               log_err("gettimeofday: %s", strerror(errno));
+               /* this option does not need current time */
+               error = NETEVENT_CLOSED; 
+       }
        sq->pending = NULL; /* removed after callback */
        if(error == NETEVENT_TIMEOUT) {
                sq->retry++;
                if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
-                       -1, now))
+                       -1, now.tv_sec))
                        log_err("out of memory in UDP exponential backoff");
                if(sq->retry < OUTBOUND_UDP_RETRY) {
                        if(!serviced_udp_send(sq, c->buffer)) {
@@ -1082,7 +1088,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
                        == LDNS_RCODE_FORMERR) {
                /* note no EDNS, fallback without EDNS */
                if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
-                       -1, now)) {
+                       -1, now.tv_sec)) {
                        log_err("Out of memory caching no edns for host");
                }
                sq->status = serviced_query_UDP;
@@ -1105,11 +1111,17 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
                return 0;
        }
        /* yay! an answer */
-       roundtime = (int)now - (int)sq->last_sent_time;
-       if(roundtime >= 0)
+       if(now.tv_sec > sq->last_sent_time.tv_sec ||
+               (now.tv_sec == sq->last_sent_time.tv_sec &&
+               now.tv_usec > sq->last_sent_time.tv_usec)) {
+               /* convert from microseconds to milliseconds */
+               int roundtime = (now.tv_sec - sq->last_sent_time.tv_sec)*1000
+                 + ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000;
+               log_info("measured roundtrip at %d msec", roundtime);
                if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, 
-                       roundtime*1000, now))
+                       roundtime, now.tv_sec))
                        log_err("out of memory noting rtt.");
+       }
        (void)rbtree_delete(outnet->serviced, sq);
        serviced_callbacks(sq, error, c, rep);
        serviced_delete(sq);
index e1a565278af6d02ebcd7f46c024a9bbc18447994..45d0d2dae7953a7c4df810b8a3472ad550f81b17 100644 (file)
@@ -226,7 +226,7 @@ struct serviced_query {
        /** number of UDP retries */
        int retry;
        /** time last UDP was sent */
-       time_t last_sent_time;
+       struct timeval last_sent_time;
        /** outside network this is part of */
        struct outside_network* outnet;
        /** list of interested parties that need callback on results. */
@@ -270,7 +270,7 @@ void outside_network_delete(struct outside_network* outnet);
  * @param packet: wireformat query to send to destination.
  * @param addr: address to send to.
  * @param addrlen: length of addr.
- * @param timeout: in seconds from now.
+ * @param timeout: in milliseconds from now.
  * @param callback: function to call on error, timeout or reply.
  * @param callback_arg: user argument for callback function.
  * @param rnd: random state for generating ID and port.
index 0255c9df31646d609946d16e870db0ac19c07ba2..ee60f11669bc7f35ab9256060319c879d68df88d 100644 (file)
@@ -687,7 +687,7 @@ pending_udp_query(struct outside_network* outnet, ldns_buffer* packet,
        pend->addrlen = addrlen;
        pend->callback = callback;
        pend->cb_arg = callback_arg;
-       pend->timeout = timeout;
+       pend->timeout = timeout/1000;
        pend->transport = transport_udp;
        pend->pkt = NULL;
        pend->runtime = runtime;
index 6eb5b500c885afae92c4b029c838188876d3e492..d33faabab56b9d2dbe1235d8205200823125f304 100644 (file)
@@ -159,8 +159,6 @@ static int handle_select(struct event_base* base, struct timeval* wait)
        if(wait->tv_sec==(time_t)-1)
                wait = NULL;
 #endif
-       if(wait) log_info("waiting for %d %d", wait->tv_sec, wait->tv_usec);
-       else log_info("wait forever");
        memmove(&r, &base->reads, sizeof(fd_set));
        memmove(&w, &base->writes, sizeof(fd_set));