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, timeout, worker_handle_reply, q->work_info,
worker->rndstate) != 0; worker->rndstate) != 0;
} }
return pending_udp_query(worker->back, pkt, addr, addrlen, timeout, return pending_udp_query(worker->back, pkt, addr, addrlen,
worker_handle_reply, q->work_info, worker->rndstate) != 0; timeout*1000, worker_handle_reply, q->work_info,
worker->rndstate) != 0;
} }
struct outbound_entry* 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 22 May 2007: Wouter
- outbound query list for modules and support to callback with the - outbound query list for modules and support to callback with the
outbound entry to the module. 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 /* system calls to set timeout after sending UDP to make roundtrip
smaller. */ smaller. */
tv.tv_sec = timeout; tv.tv_sec = timeout/1000;
tv.tv_usec = 0; tv.tv_usec = (timeout%1000)*1000;
comm_timer_set(pend->timer, &tv); comm_timer_set(pend->timer, &tv);
return pend; return pend;
} }
@ -988,9 +988,11 @@ serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff)
else sq->status = serviced_query_UDP; else sq->status = serviced_query_UDP;
} }
serviced_encode(sq, buff, sq->status == serviced_query_UDP_EDNS); serviced_encode(sq, buff, sq->status == serviced_query_UDP_EDNS);
sq->last_sent_time = now; if(gettimeofday(&sq->last_sent_time, NULL) < 0) {
/* round rtt to whole seconds for now. TODO better timing */ log_err("gettimeofday: %s", strerror(errno));
rtt = rtt/1000 + 1; return 0;
}
verbose(VERB_DETAIL, "serviced query UDP timeout=%d msec", rtt);
sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr, sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr,
sq->addrlen, rtt, serviced_udp_callback, sq, sq->outnet->rnd); sq->addrlen, rtt, serviced_udp_callback, sq, sq->outnet->rnd);
if(!sq->pending) 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 serviced_query* sq = (struct serviced_query*)arg;
struct outside_network* outnet = sq->outnet; struct outside_network* outnet = sq->outnet;
time_t now = time(NULL); struct timeval now;
int roundtime; 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 */ sq->pending = NULL; /* removed after callback */
if(error == NETEVENT_TIMEOUT) { if(error == NETEVENT_TIMEOUT) {
sq->retry++; sq->retry++;
if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, 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"); log_err("out of memory in UDP exponential backoff");
if(sq->retry < OUTBOUND_UDP_RETRY) { if(sq->retry < OUTBOUND_UDP_RETRY) {
if(!serviced_udp_send(sq, c->buffer)) { 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) { == LDNS_RCODE_FORMERR) {
/* note no EDNS, fallback without EDNS */ /* note no EDNS, fallback without EDNS */
if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, 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"); log_err("Out of memory caching no edns for host");
} }
sq->status = serviced_query_UDP; sq->status = serviced_query_UDP;
@ -1105,11 +1111,17 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
return 0; return 0;
} }
/* yay! an answer */ /* yay! an answer */
roundtime = (int)now - (int)sq->last_sent_time; if(now.tv_sec > sq->last_sent_time.tv_sec ||
if(roundtime >= 0) (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, if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen,
roundtime*1000, now)) roundtime, now.tv_sec))
log_err("out of memory noting rtt."); log_err("out of memory noting rtt.");
}
(void)rbtree_delete(outnet->serviced, sq); (void)rbtree_delete(outnet->serviced, sq);
serviced_callbacks(sq, error, c, rep); serviced_callbacks(sq, error, c, rep);
serviced_delete(sq); serviced_delete(sq);

View file

@ -226,7 +226,7 @@ struct serviced_query {
/** number of UDP retries */ /** number of UDP retries */
int retry; int retry;
/** time last UDP was sent */ /** time last UDP was sent */
time_t last_sent_time; struct timeval last_sent_time;
/** outside network this is part of */ /** outside network this is part of */
struct outside_network* outnet; struct outside_network* outnet;
/** list of interested parties that need callback on results. */ /** 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 packet: wireformat query to send to destination.
* @param addr: address to send to. * @param addr: address to send to.
* @param addrlen: length of addr. * @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: function to call on error, timeout or reply.
* @param callback_arg: user argument for callback function. * @param callback_arg: user argument for callback function.
* @param rnd: random state for generating ID and port. * @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->addrlen = addrlen;
pend->callback = callback; pend->callback = callback;
pend->cb_arg = callback_arg; pend->cb_arg = callback_arg;
pend->timeout = timeout; pend->timeout = timeout/1000;
pend->transport = transport_udp; pend->transport = transport_udp;
pend->pkt = NULL; pend->pkt = NULL;
pend->runtime = runtime; 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) if(wait->tv_sec==(time_t)-1)
wait = NULL; wait = NULL;
#endif #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(&r, &base->reads, sizeof(fd_set));
memmove(&w, &base->writes, sizeof(fd_set)); memmove(&w, &base->writes, sizeof(fd_set));