summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--common-kex.c2
-rw-r--r--common-session.c3
-rw-r--r--configure.ac4
-rw-r--r--dbutil.c43
-rw-r--r--dbutil.h5
-rw-r--r--packet.c2
-rw-r--r--process-packet.c2
-rw-r--r--session.h7
-rw-r--r--svr-session.c2
9 files changed, 61 insertions, 9 deletions
diff --git a/common-kex.c b/common-kex.c
index 10ea554..f5119d2 100644
--- a/common-kex.c
+++ b/common-kex.c
@@ -270,7 +270,7 @@ static void kexinitialise() {
ses.kexstate.our_first_follows_matches = 0;
- ses.kexstate.lastkextime = time(NULL);
+ ses.kexstate.lastkextime = monotonic_now();
}
diff --git a/common-session.c b/common-session.c
index 998bf0e..6bcb7fa 100644
--- a/common-session.c
+++ b/common-session.c
@@ -397,8 +397,7 @@ void send_msg_ignore() {
static void checktimeouts() {
time_t now;
-
- now = time(NULL);
+ now = monotonic_now();
if (ses.connect_time != 0 && now - ses.connect_time >= AUTH_TIMEOUT) {
dropbear_close("Timeout before auth");
diff --git a/configure.ac b/configure.ac
index 8095280..29c0d40 100644
--- a/configure.ac
+++ b/configure.ac
@@ -361,6 +361,10 @@ AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline )
AC_CHECK_FUNCS(setutxent utmpxname)
AC_CHECK_FUNCS(logout updwtmp logwtmp)
+# OS X monotonic time
+AC_CHECK_HEADERS([mach/mach_time.h])
+AC_CHECK_FUNCS(mach_absolute_time)
+
AC_ARG_ENABLE(bundled-libtom,
[ --enable-bundled-libtom Force using bundled libtomcrypt/libtommath even if a system version exists.
--disable-bundled-libtom Force using system libtomcrypt/libtommath, fail if it does not exist.
diff --git a/dbutil.c b/dbutil.c
index 52bf87c..07ba512 100644
--- a/dbutil.c
+++ b/dbutil.c
@@ -48,6 +48,19 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+#include "config.h"
+
+#ifdef __linux__
+#define _GNU_SOURCE
+/* To call clock_gettime() directly */
+#include <sys/syscall.h>
+#endif /* __linux */
+
+#ifdef HAVE_MACH_MACH_TIME_H
+#include <mach/mach_time.h>
+#include <mach/mach.h>
+#endif
+
#include "includes.h"
#include "dbutil.h"
#include "buffer.h"
@@ -932,3 +945,33 @@ int constant_time_memcmp(const void* a, const void *b, size_t n)
return c;
}
+time_t monotonic_now() {
+
+#if defined(__linux__) && defined(SYS_clock_gettime)
+ /* CLOCK_MONOTONIC_COARSE was added in Linux 2.6.32. Probably cheaper. */
+#ifndef CLOCK_MONOTONIC_COARSE
+#define CLOCK_MONOTONIC_COARSE 6
+#endif
+ static clockid_t clock_source = CLOCK_MONOTONIC_COARSE;
+ struct timespec ts;
+
+ if (syscall(SYS_clock_gettime, clock_source, &ts) == EINVAL) {
+ clock_source = CLOCK_MONOTONIC;
+ syscall(SYS_clock_gettime, CLOCK_MONOTONIC, &ts);
+ }
+ return ts.tv_sec;
+#elif defined(HAVE_MACH_ABSOLUTE_TIME)
+ /* OS X, see https://developer.apple.com/library/mac/qa/qa1398/_index.html */
+ mach_timebase_info_data_t timebase_info;
+ if (timebase_info.denom == 0) {
+ mach_timebase_info(&timebase_info);
+ }
+ return mach_absolute_time() * timebase_info.numer / timebase_info.denom
+ / 1e9;
+#else
+ /* Fallback for everything else - this will sometimes go backwards */
+ return time(NULL);
+#endif
+
+}
+
diff --git a/dbutil.h b/dbutil.h
index 4c7b123..afc49ff 100644
--- a/dbutil.h
+++ b/dbutil.h
@@ -106,4 +106,9 @@ int m_str_to_uint(const char* str, unsigned int *val);
/* Returns 0 if a and b have the same contents */
int constant_time_memcmp(const void* a, const void *b, size_t n);
+/* Returns a time in seconds that doesn't go backwards - does not correspond to
+a real-world clock */
+time_t monotonic_now();
+
+
#endif /* _DBUTIL_H_ */
diff --git a/packet.c b/packet.c
index 8f7aa38..5f38f08 100644
--- a/packet.c
+++ b/packet.c
@@ -151,7 +151,7 @@ void write_packet() {
}
#endif
- now = time(NULL);
+ now = monotonic_now();
ses.last_trx_packet_time = now;
if (!all_ignore) {
diff --git a/process-packet.c b/process-packet.c
index 3659cc0..6cbcfc7 100644
--- a/process-packet.c
+++ b/process-packet.c
@@ -52,7 +52,7 @@ void process_packet() {
ses.lastpacket = type;
- ses.last_packet_time = time(NULL);
+ ses.last_packet_time = monotonic_now();
/* These packets we can receive at any time */
switch(type) {
diff --git a/session.h b/session.h
index b347700..e66fc39 100644
--- a/session.h
+++ b/session.h
@@ -106,7 +106,8 @@ struct sshsession {
time_t connect_time; /* time the connection was established
(cleared after auth once we're not
- respecting AUTH_TIMEOUT any more) */
+ respecting AUTH_TIMEOUT any more).
+ A monotonic time, not realworld */
int sock_in;
int sock_out;
@@ -147,10 +148,10 @@ struct sshsession {
race-free signal handling */
time_t last_trx_packet_time; /* time of the last packet transmission, for
- keepalive purposes */
+ keepalive purposes. Not real-world clock */
time_t last_packet_time; /* time of the last packet transmission or receive, for
- idle timeout purposes */
+ idle timeout purposes. Not real-world clock */
/* KEX/encryption related */
diff --git a/svr-session.c b/svr-session.c
index e9fde24..2adcb01 100644
--- a/svr-session.c
+++ b/svr-session.c
@@ -95,7 +95,7 @@ void svr_session(int sock, int childpipe) {
chaninitialise(svr_chantypes);
svr_chansessinitialise();
- ses.connect_time = time(NULL);
+ ses.connect_time = monotonic_now();
/* for logging the remote address */
get_socket_address(ses.sock_in, NULL, NULL, &host, &port, 0);