From d708ef6731445a84a3d0499a4b13fd09a0dd0520 Mon Sep 17 00:00:00 2001 From: Yang Tse Date: Fri, 9 May 2008 16:30:24 +0000 Subject: [PATCH] Use monotonic time source if available. --- ares/CHANGES | 4 ++ ares/Makefile.inc | 2 +- ares/Makefile.vc6 | 5 +- ares/RELEASE-NOTES | 1 + ares/ares__timeval.c | 95 +++++++++++++++++++++++++++++++++++++ ares/ares_private.h | 2 + ares/configure.ac | 2 + ares/nameser.h | 7 --- ares/vc/areslib/areslib.dsp | 4 ++ ares/windows_port.c | 31 ------------ 10 files changed, 113 insertions(+), 40 deletions(-) create mode 100644 ares/ares__timeval.c diff --git a/ares/CHANGES b/ares/CHANGES index 0acc94c15..3d44b190a 100644 --- a/ares/CHANGES +++ b/ares/CHANGES @@ -1,5 +1,9 @@ Changelog for the c-ares project +* May 9 2008 (Yang Tse) + +- Use monotonic time source if available, for private function ares__tvnow() + * May 7 2008 (Daniel Stenberg) - Sebastian made c-ares able to return all PTR-records when doing reverse diff --git a/ares/Makefile.inc b/ares/Makefile.inc index 58a27bb21..c524802e1 100644 --- a/ares/Makefile.inc +++ b/ares/Makefile.inc @@ -6,7 +6,7 @@ ares_timeout.c ares_destroy.c ares_mkquery.c ares_version.c \ ares_expand_name.c ares_parse_a_reply.c windows_port.c \ ares_expand_string.c ares_parse_ptr_reply.c ares_parse_aaaa_reply.c \ ares_getnameinfo.c inet_net_pton.c bitncmp.c inet_ntop.c \ -ares_parse_ns_reply.c ares_llist.c +ares_parse_ns_reply.c ares_llist.c ares__timeval.c HHEADERS = ares.h ares_private.h setup.h ares_dns.h ares_version.h \ nameser.h inet_net_pton.h inet_ntop.h ares_ipv6.h bitncmp.h \ diff --git a/ares/Makefile.vc6 b/ares/Makefile.vc6 index 8bc8efb59..cfa3fada0 100644 --- a/ares/Makefile.vc6 +++ b/ares/Makefile.vc6 @@ -62,6 +62,7 @@ OBJECTS = $(OBJ_DIR)\ares_fds.obj \ $(OBJ_DIR)\ares_init.obj \ $(OBJ_DIR)\ares_llist.obj \ $(OBJ_DIR)\ares_timeout.obj \ + $(OBJ_DIR)\ares__timeval.obj \ $(OBJ_DIR)\ares_destroy.obj \ $(OBJ_DIR)\ares_mkquery.obj \ $(OBJ_DIR)\ares_version.obj \ @@ -122,7 +123,6 @@ $(DEF_FILE): $(OBJECTS) Makefile.VC6 @echo ares_inet_pton >> $@ @echo ares_writev >> $@ @echo ares_getnameinfo >> $@ - @echo ares_gettimeofday >> $@ @echo ares_parse_aaaa_reply >> $@ ahost.exe: $(OBJ_DIR) $(OBJ_DIR)\ahost.obj $(OBJ_DIR)\ares_getopt.obj cares_imp.lib @@ -193,6 +193,9 @@ $(OBJ_DIR)\ares_init.obj: ares_init.c setup.h setup_once.h nameser.h ares.h \ $(OBJ_DIR)\ares_timeout.obj: ares_timeout.c setup.h setup_once.h ares.h \ ares_private.h ares_ipv6.h +$(OBJ_DIR)\ares__timeval.obj: ares__timeval.c setup.h setup_once.h ares.h \ + ares_private.h ares_ipv6.h + $(OBJ_DIR)\ares_destroy.obj: ares_destroy.c setup.h setup_once.h ares.h \ ares_private.h ares_ipv6.h diff --git a/ares/RELEASE-NOTES b/ares/RELEASE-NOTES index 5387ae9ab..2d67041f5 100644 --- a/ares/RELEASE-NOTES +++ b/ares/RELEASE-NOTES @@ -1,6 +1,7 @@ This is what's new and changed in the c-ares 1.5.2 release: o improved parsing of resolver configuration files + o use monotonic time source if available Thanks go to these friendly people for their efforts and contributions: diff --git a/ares/ares__timeval.c b/ares/ares__timeval.c new file mode 100644 index 000000000..0d8bbfa65 --- /dev/null +++ b/ares/ares__timeval.c @@ -0,0 +1,95 @@ +/* $Id$ */ + +/* Copyright (C) 2008 by Daniel Stenberg et al + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. M.I.T. makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "setup.h" +#include "ares.h" +#include "ares_private.h" + +#if defined(WIN32) && !defined(MSDOS) + +struct timeval ares__tvnow(void) +{ + /* + ** GetTickCount() is available on _all_ Windows versions from W95 up + ** to nowadays. Returns milliseconds elapsed since last system boot, + ** increases monotonically and wraps once 49.7 days have elapsed. + */ + struct timeval now; + DWORD milliseconds = GetTickCount(); + now.tv_sec = milliseconds / 1000; + now.tv_usec = (milliseconds % 1000) * 1000; + return now; +} + +#elif defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) + +struct timeval ares__tvnow(void) +{ + /* + ** clock_gettime() is granted to be increased monotonically when the + ** monotonic clock is queried. Time starting point is unspecified, it + ** could be the system start-up time, the Epoch, or something else, + ** in any case the time starting point does not change once that the + ** system has started up. + */ + struct timeval now; + struct timespec tsnow; + (void)clock_gettime(CLOCK_MONOTONIC, &tsnow) + now.tv_sec = tsnow.tv_sec; + now.tv_usec = tsnow.tv_nsec / 1000; + return now; +} + +#elif defined(HAVE_GETTIMEOFDAY) + +struct timeval ares__tvnow(void) +{ + /* + ** gettimeofday() is not granted to be increased monotonically, due to + ** clock drifting and external source time synchronization it can jump + ** forward or backward in time. + */ + struct timeval now; + (void)gettimeofday(&now, NULL); + return now; +} + +#else + +struct timeval ares__tvnow(void) +{ + /* + ** time() returns the value of time in seconds since the Epoch. + */ + struct timeval now; + now.tv_sec = (long)time(NULL); + now.tv_usec = 0; + return now; +} + +#endif + +/* + * Make sure that the first argument is the more recent time, as otherwise + * we'll get a weird negative time-diff back... + * + * Returns: the time difference in number of milliseconds. + */ +long ares__tvdiff(struct timeval newer, struct timeval older) +{ + return (newer.tv_sec-older.tv_sec)*1000+ + (newer.tv_usec-older.tv_usec)/1000; +} + diff --git a/ares/ares_private.h b/ares/ares_private.h index d5ffbb382..9354e6300 100644 --- a/ares/ares_private.h +++ b/ares/ares_private.h @@ -266,6 +266,8 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host); int ares__read_line(FILE *fp, char **buf, int *bufsize); void ares__free_query(struct query *query); short ares__generate_new_id(rc4_key* key); +struct timeval ares__tvnow(void); +long ares__tvdiff(struct timeval t1, struct timeval t2); #define ARES_SWAP_BYTE(a,b) \ { unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; } diff --git a/ares/configure.ac b/ares/configure.ac index 4315f5c2e..a7af5a183 100644 --- a/ares/configure.ac +++ b/ares/configure.ac @@ -384,6 +384,7 @@ AC_CHECK_HEADERS( errno.h \ strings.h \ stdbool.h \ + time.h \ arpa/nameser.h \ arpa/nameser_compat.h \ arpa/inet.h, @@ -643,6 +644,7 @@ AC_CHECK_MEMBER(struct addrinfo.ai_flags, AC_CHECK_FUNCS( bitncmp \ gettimeofday \ + clock_gettime \ if_indextoname, dnl if found [], diff --git a/ares/nameser.h b/ares/nameser.h index 154941450..dc8c86e34 100644 --- a/ares/nameser.h +++ b/ares/nameser.h @@ -29,13 +29,6 @@ struct iovec int ares_writev (SOCKET s, const struct iovec *vector, size_t count); #define writev(s,vect,count) ares_writev(s,vect,count) -#ifndef HAVE_GETTIMEOFDAY -struct timezone { int dummy; }; -#endif - -int ares_gettimeofday(struct timeval *tv, struct timezone *tz); -#define gettimeofday(tv,tz) ares_gettimeofday(tv,tz) - #endif /* !NETWARE */ #define NS_CMPRSFLGS 0xc0 diff --git a/ares/vc/areslib/areslib.dsp b/ares/vc/areslib/areslib.dsp index 940dce062..71d64f88f 100644 --- a/ares/vc/areslib/areslib.dsp +++ b/ares/vc/areslib/areslib.dsp @@ -97,6 +97,10 @@ SOURCE=..\..\ares__read_line.c # End Source File # Begin Source File +SOURCE=..\..\ares__timeval.c +# End Source File +# Begin Source File + SOURCE=..\..\ares_cancel.c # End Source File # Begin Source File diff --git a/ares/windows_port.c b/ares/windows_port.c index 02bb4cbf8..7ea6579fd 100644 --- a/ares/windows_port.c +++ b/ares/windows_port.c @@ -55,37 +55,6 @@ ares_strcasecmp(const char *a, const char *b) } #endif -/* - * Number of micro-seconds between the beginning of the Windows epoch - * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970). - */ -#if defined(_MSC_VER) || defined(__WATCOMC__) -#define EPOCH_FILETIME 11644473600000000Ui64 -#else -#define EPOCH_FILETIME 11644473600000000ULL -#endif - -int -ares_gettimeofday(struct timeval *tv, struct timezone *tz) -{ - FILETIME ft; - LARGE_INTEGER li; - __int64 t; - - if (tv) - { - GetSystemTimeAsFileTime(&ft); - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - t = li.QuadPart / 10; /* In micro-second intervals */ - t -= EPOCH_FILETIME; /* Offset to the Epoch time */ - tv->tv_sec = (long)(t / 1000000); - tv->tv_usec = (long)(t % 1000000); - } - (void) tz; - return 0; -} - int ares_writev (ares_socket_t s, const struct iovec *vector, size_t count) {