precise timers for roundtrip UDP timeouts.

git-svn-id: file:///svn/unbound/trunk@332 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-05-23 06:24:01 +00:00
parent d48aa65684
commit c4096b8654
6 changed files with 34 additions and 19 deletions

View 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*

View 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.

View 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);

View 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.

View 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;

View 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));