Use monotonic timer for send_dg

Message ID 5516C5EB.9080106@codesourcery.com
State New, archived
Headers

Commit Message

Kwok Cheung Yeung March 28, 2015, 3:16 p.m. UTC
  This patch addresses a rare scenario where a change in the system clock 
may result in an incorrect timeout.

In send_dg (in resolv/res_send.c), eventually called from functions such 
as getaddrinfo:

	evNowTime(&now);
	evConsTime(&timeout, seconds, 0);
	evAddTime(&finish, &now, &timeout);
	...
	recompute_resend:
		evNowTime(&now);
		...
		evSubTime(&timeout, &finish, &now);
		...
	ptimeout = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
	...
		n = __poll (pfd, 1, ptimeout);

If in between the first and second calls to evNowTime the system clock 
changes, then the updated value of timeout will also be modified (e.g. 
if the time shifts back an hour, then the timeout would be extended by 
an hour).

This patch addresses this by making evNowTime use a monotonic clock if 
available, since it cannot go backwards in time. If not available, then 
it falls back to using the realtime clock as before. I have run a full 
'make xcheck' before and after, with no regressions found.

Kwok


Use monotonic timer for send_dg

* resolv/res_send.c: Include time.h instead of sys/time.h.
   (evNowTime): Obtain current time from monotonic clock if possible.
---
  resolv/res_send.c | 7 ++++++-
  1 file changed, 6 insertions(+), 1 deletion(-)

  #include <sys/poll.h>
@@ -169,6 +169,11 @@ static void
  evNowTime(struct timespec *res) {
  	struct timeval now;

+#ifdef _POSIX_MONOTONIC_CLOCK
+	if (clock_gettime(CLOCK_MONOTONIC, res) == 0)
+		return;
+#endif
+
  	if (gettimeofday(&now, NULL) < 0)
  		evConsTime(res, 0, 0);
  	else
  

Patch

diff --git a/resolv/res_send.c b/resolv/res_send.c
index c35fb66..b7176dd 100644
--- a/resolv/res_send.c
+++ b/resolv/res_send.c
@@ -76,7 +76,7 @@  static const char rcsid[] = "$BINDId: res_send.c,v 
8.38 2000/03/30 20:16:51 vixi
  #include <assert.h>
  #include <sys/types.h>
  #include <sys/param.h>
-#include <sys/time.h>
+#include <time.h>
  #include <sys/socket.h>
  #include <sys/uio.h>