[PATCH] Use monotonic timer for send_dg

Kwok Cheung Yeung kcy@codesourcery.com
Sat Mar 28 15:17:00 GMT 2015


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(-)

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>
  #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
-- 
2.3.4



More information about the Libc-alpha mailing list