summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
authordtucker@openbsd.org@openbsd.org <dtucker@openbsd.org@openbsd.org>2017-11-25 06:46:22 +0000
committerDamien Miller <djm@mindrot.org>2017-11-28 12:01:49 +1100
commit5db6fbf1438b108e5df3e79a1b4de544373bc2d4 (patch)
tree95f5df8248cca30df3ab00e70e80d28410be760c /misc.c
parent2d638e986085bdf1a40310ed6e2307463db96ea0 (diff)
upstream commit
Add monotime_ts and monotime_tv that return monotonic timespec and timeval respectively. Replace calls to gettimeofday() in packet timing with monotime_tv so that the callers will work over a clock step. Should prevent integer overflow during clock steps reported by wangle6 at huawei.com. "I like" markus@ OpenBSD-Commit-ID: 74d684264814ff806f197948b87aa732cb1b0b8a
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c87
1 files changed, 48 insertions, 39 deletions
diff --git a/misc.c b/misc.c
index 2369361b3..dfa0bb33a 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.c,v 1.118 2017/10/25 00:17:08 djm Exp $ */ 1/* $OpenBSD: misc.c,v 1.119 2017/11/25 06:46:22 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -1259,8 +1259,8 @@ ms_subtract_diff(struct timeval *start, int *ms)
1259{ 1259{
1260 struct timeval diff, finish; 1260 struct timeval diff, finish;
1261 1261
1262 gettimeofday(&finish, NULL); 1262 monotime_tv(&finish);
1263 timersub(&finish, start, &diff); 1263 timersub(&finish, start, &diff);
1264 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); 1264 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
1265} 1265}
1266 1266
@@ -1273,54 +1273,63 @@ ms_to_timeval(struct timeval *tv, int ms)
1273 tv->tv_usec = (ms % 1000) * 1000; 1273 tv->tv_usec = (ms % 1000) * 1000;
1274} 1274}
1275 1275
1276time_t 1276void
1277monotime(void) 1277monotime_ts(struct timespec *ts)
1278{ 1278{
1279#if defined(HAVE_CLOCK_GETTIME) && \ 1279 struct timeval tv;
1280 (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME)) 1280#if defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_BOOTTIME) || \
1281 struct timespec ts; 1281 defined(CLOCK_MONOTONIC) || defined(CLOCK_REALTIME))
1282 static int gettime_failed = 0; 1282 static int gettime_failed = 0;
1283 1283
1284 if (!gettime_failed) { 1284 if (!gettime_failed) {
1285#if defined(CLOCK_BOOTTIME) 1285# ifdef CLOCK_BOOTTIME
1286 if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) 1286 if (clock_gettime(CLOCK_BOOTTIME, ts) == 0)
1287 return (ts.tv_sec); 1287 return;
1288#endif 1288# endif /* CLOCK_BOOTTIME */
1289#if defined(CLOCK_MONOTONIC) 1289# ifdef CLOCK_MONOTONIC
1290 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) 1290 if (clock_gettime(CLOCK_MONOTONIC, ts) == 0)
1291 return (ts.tv_sec); 1291 return;
1292#endif 1292# endif /* CLOCK_MONOTONIC */
1293# ifdef CLOCK_REALTIME
1294 /* Not monotonic, but we're almost out of options here. */
1295 if (clock_gettime(CLOCK_REALTIME, ts) == 0)
1296 return;
1297# endif /* CLOCK_REALTIME */
1293 debug3("clock_gettime: %s", strerror(errno)); 1298 debug3("clock_gettime: %s", strerror(errno));
1294 gettime_failed = 1; 1299 gettime_failed = 1;
1295 } 1300 }
1296#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */ 1301#endif /* HAVE_CLOCK_GETTIME && (BOOTTIME || MONOTONIC || REALTIME) */
1302 gettimeofday(&tv, NULL);
1303 ts->tv_sec = tv.tv_sec;
1304 ts->tv_nsec = (long)tv.tv_usec * 1000;
1305}
1297 1306
1298 return time(NULL); 1307void
1308monotime_tv(struct timeval *tv)
1309{
1310 struct timespec ts;
1311
1312 monotime_ts(&ts);
1313 tv->tv_sec = ts.tv_sec;
1314 tv->tv_usec = ts.tv_nsec / 1000;
1315}
1316
1317time_t
1318monotime(void)
1319{
1320 struct timespec ts;
1321
1322 monotime_ts(&ts);
1323 return ts.tv_sec;
1299} 1324}
1300 1325
1301double 1326double
1302monotime_double(void) 1327monotime_double(void)
1303{ 1328{
1304#if defined(HAVE_CLOCK_GETTIME) && \
1305 (defined(CLOCK_MONOTONIC) || defined(CLOCK_BOOTTIME))
1306 struct timespec ts; 1329 struct timespec ts;
1307 static int gettime_failed = 0;
1308
1309 if (!gettime_failed) {
1310#if defined(CLOCK_BOOTTIME)
1311 if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0)
1312 return (ts.tv_sec + (double)ts.tv_nsec / 1000000000);
1313#endif
1314#if defined(CLOCK_MONOTONIC)
1315 if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
1316 return (ts.tv_sec + (double)ts.tv_nsec / 1000000000);
1317#endif
1318 debug3("clock_gettime: %s", strerror(errno));
1319 gettime_failed = 1;
1320 }
1321#endif /* HAVE_CLOCK_GETTIME && (CLOCK_MONOTONIC || CLOCK_BOOTTIME */
1322 1330
1323 return (double)time(NULL); 1331 monotime_ts(&ts);
1332 return ts.tv_sec + ((double)ts.tv_nsec / 1000000000);
1324} 1333}
1325 1334
1326void 1335void
@@ -1342,7 +1351,7 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len)
1342 struct timespec ts, rm; 1351 struct timespec ts, rm;
1343 1352
1344 if (!timerisset(&bw->bwstart)) { 1353 if (!timerisset(&bw->bwstart)) {
1345 gettimeofday(&bw->bwstart, NULL); 1354 monotime_tv(&bw->bwstart);
1346 return; 1355 return;
1347 } 1356 }
1348 1357
@@ -1350,7 +1359,7 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len)
1350 if (bw->lamt < bw->thresh) 1359 if (bw->lamt < bw->thresh)
1351 return; 1360 return;
1352 1361
1353 gettimeofday(&bw->bwend, NULL); 1362 monotime_tv(&bw->bwend);
1354 timersub(&bw->bwend, &bw->bwstart, &bw->bwend); 1363 timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
1355 if (!timerisset(&bw->bwend)) 1364 if (!timerisset(&bw->bwend))
1356 return; 1365 return;
@@ -1384,7 +1393,7 @@ bandwidth_limit(struct bwlimit *bw, size_t read_len)
1384 } 1393 }
1385 1394
1386 bw->lamt = 0; 1395 bw->lamt = 0;
1387 gettimeofday(&bw->bwstart, NULL); 1396 monotime_tv(&bw->bwstart);
1388} 1397}
1389 1398
1390/* Make a template filename for mk[sd]temp() */ 1399/* Make a template filename for mk[sd]temp() */