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*
/* 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;
}
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)
{
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)) {
== 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;
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);
/** 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. */
* @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.