summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt3
-rw-r--r--auto_tests/TCP_test.c1
-rw-r--r--auto_tests/onion_test.c1
-rw-r--r--auto_tests/toxav_many_test.c2
-rw-r--r--other/DHT_bootstrap.c1
-rw-r--r--other/bootstrap_daemon/src/tox-bootstrapd.c1
-rw-r--r--other/monolith.h1
-rw-r--r--other/travis/env-freebsd.sh3
-rw-r--r--other/travis/env.sh1
-rwxr-xr-xother/travis/toxcore-script4
-rw-r--r--testing/av_test.c2
-rw-r--r--toxav/audio.c1
-rw-r--r--toxav/bwcontroller.c1
-rw-r--r--toxav/groupav.c1
-rw-r--r--toxav/rtp.c1
-rw-r--r--toxav/toxav.c1
-rw-r--r--toxav/video.c1
-rw-r--r--toxcore/BUILD.bazel17
-rw-r--r--toxcore/DHT.c1
-rw-r--r--toxcore/Makefile.inc2
-rw-r--r--toxcore/Messenger.c5
-rw-r--r--toxcore/TCP_client.c1
-rw-r--r--toxcore/TCP_connection.c1
-rw-r--r--toxcore/TCP_server.c1
-rw-r--r--toxcore/friend_connection.c1
-rw-r--r--toxcore/group.c1
-rw-r--r--toxcore/mono_time.c157
-rw-r--r--toxcore/mono_time.h35
-rw-r--r--toxcore/mono_time_test.cc30
-rw-r--r--toxcore/net_crypto.c1
-rw-r--r--toxcore/network.c69
-rw-r--r--toxcore/network.h3
-rw-r--r--toxcore/onion.c1
-rw-r--r--toxcore/onion_announce.c1
-rw-r--r--toxcore/onion_client.c1
-rw-r--r--toxcore/ping.c1
-rw-r--r--toxcore/ping_array.c1
-rw-r--r--toxcore/tox.c7
-rw-r--r--toxcore/util.c63
-rw-r--r--toxcore/util.h15
-rw-r--r--toxcore/util_test.cc25
41 files changed, 285 insertions, 181 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d3266e2f..9fe1c3c5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -171,6 +171,8 @@ set(toxcore_PKGCONFIG_REQUIRES ${toxcore_PKGCONFIG_REQUIRES} libsodium)
171set(toxcore_SOURCES ${toxcore_SOURCES} 171set(toxcore_SOURCES ${toxcore_SOURCES}
172 toxcore/logger.c 172 toxcore/logger.c
173 toxcore/logger.h 173 toxcore/logger.h
174 toxcore/mono_time.c
175 toxcore/mono_time.h
174 toxcore/network.c 176 toxcore/network.c
175 toxcore/network.h 177 toxcore/network.h
176 toxcore/state.c 178 toxcore/state.c
@@ -343,6 +345,7 @@ include(CompileGTest)
343unit_test(toxav ring_buffer) 345unit_test(toxav ring_buffer)
344unit_test(toxav rtp) 346unit_test(toxav rtp)
345unit_test(toxcore crypto_core) 347unit_test(toxcore crypto_core)
348unit_test(toxcore mono_time)
346unit_test(toxcore util) 349unit_test(toxcore util)
347 350
348################################################################################ 351################################################################################
diff --git a/auto_tests/TCP_test.c b/auto_tests/TCP_test.c
index 134bdf9b..f5bc2471 100644
--- a/auto_tests/TCP_test.c
+++ b/auto_tests/TCP_test.c
@@ -18,6 +18,7 @@
18#include "../toxcore/TCP_server.h" 18#include "../toxcore/TCP_server.h"
19 19
20#include "../toxcore/crypto_core.h" 20#include "../toxcore/crypto_core.h"
21#include "../toxcore/mono_time.h"
21#include "../toxcore/util.h" 22#include "../toxcore/util.h"
22 23
23#include "helpers.h" 24#include "helpers.h"
diff --git a/auto_tests/onion_test.c b/auto_tests/onion_test.c
index a4f20cba..45679205 100644
--- a/auto_tests/onion_test.c
+++ b/auto_tests/onion_test.c
@@ -14,6 +14,7 @@
14#include <sys/types.h> 14#include <sys/types.h>
15#include <time.h> 15#include <time.h>
16 16
17#include "../toxcore/mono_time.h"
17#include "../toxcore/onion.h" 18#include "../toxcore/onion.h"
18#include "../toxcore/onion_announce.h" 19#include "../toxcore/onion_announce.h"
19#include "../toxcore/onion_client.h" 20#include "../toxcore/onion_client.h"
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c
index e89a6823..94183421 100644
--- a/auto_tests/toxav_many_test.c
+++ b/auto_tests/toxav_many_test.c
@@ -176,6 +176,8 @@ static void *call_thread(void *pd)
176 176
177 printf("Closing thread\n"); 177 printf("Closing thread\n");
178 pthread_exit(nullptr); 178 pthread_exit(nullptr);
179
180 return nullptr;
179} 181}
180 182
181static void test_av_three_calls(void) 183static void test_av_three_calls(void)
diff --git a/other/DHT_bootstrap.c b/other/DHT_bootstrap.c
index f263b471..b71ab0b1 100644
--- a/other/DHT_bootstrap.c
+++ b/other/DHT_bootstrap.c
@@ -33,6 +33,7 @@
33#include "../toxcore/LAN_discovery.h" 33#include "../toxcore/LAN_discovery.h"
34#include "../toxcore/friend_requests.h" 34#include "../toxcore/friend_requests.h"
35#include "../toxcore/logger.h" 35#include "../toxcore/logger.h"
36#include "../toxcore/mono_time.h"
36#include "../toxcore/tox.h" 37#include "../toxcore/tox.h"
37#include "../toxcore/util.h" 38#include "../toxcore/util.h"
38 39
diff --git a/other/bootstrap_daemon/src/tox-bootstrapd.c b/other/bootstrap_daemon/src/tox-bootstrapd.c
index 3c6d5d2c..fd05f8a2 100644
--- a/other/bootstrap_daemon/src/tox-bootstrapd.c
+++ b/other/bootstrap_daemon/src/tox-bootstrapd.c
@@ -38,6 +38,7 @@
38#include "../../../toxcore/LAN_discovery.h" 38#include "../../../toxcore/LAN_discovery.h"
39#include "../../../toxcore/TCP_server.h" 39#include "../../../toxcore/TCP_server.h"
40#include "../../../toxcore/logger.h" 40#include "../../../toxcore/logger.h"
41#include "../../../toxcore/mono_time.h"
41#include "../../../toxcore/onion_announce.h" 42#include "../../../toxcore/onion_announce.h"
42#include "../../../toxcore/util.h" 43#include "../../../toxcore/util.h"
43 44
diff --git a/other/monolith.h b/other/monolith.h
index 426ba0d9..356252f2 100644
--- a/other/monolith.h
+++ b/other/monolith.h
@@ -13,6 +13,7 @@
13#include "../toxcore/group.c" 13#include "../toxcore/group.c"
14#include "../toxcore/list.c" 14#include "../toxcore/list.c"
15#include "../toxcore/logger.c" 15#include "../toxcore/logger.c"
16#include "../toxcore/mono_time.c"
16#include "../toxcore/network.c" 17#include "../toxcore/network.c"
17#include "../toxcore/net_crypto.c" 18#include "../toxcore/net_crypto.c"
18#include "../toxcore/onion.c" 19#include "../toxcore/onion.c"
diff --git a/other/travis/env-freebsd.sh b/other/travis/env-freebsd.sh
index f9aa0cbf..882e9da5 100644
--- a/other/travis/env-freebsd.sh
+++ b/other/travis/env-freebsd.sh
@@ -1,9 +1,6 @@
1#!/bin/sh 1#!/bin/sh
2 2
3CMAKE=cmake 3CMAKE=cmake
4# Asan is disabled because it's currently broken in FreeBSD 11.
5# We should try enabling it in the next FreeBSD release and see if it works.
6CMAKE_EXTRA_FLAGS="$CMAKE_EXTRA_FLAGS -DASAN=OFF"
7NPROC=`nproc` 4NPROC=`nproc`
8CURDIR=/root 5CURDIR=/root
9RUN_TESTS=true 6RUN_TESTS=true
diff --git a/other/travis/env.sh b/other/travis/env.sh
index 7d90d395..2d3e646c 100644
--- a/other/travis/env.sh
+++ b/other/travis/env.sh
@@ -8,7 +8,6 @@ export PKG_CONFIG_PATH=$CACHE_DIR/lib/pkgconfig
8export ASTYLE=$CACHE_DIR/astyle/build/gcc/bin/astyle 8export ASTYLE=$CACHE_DIR/astyle/build/gcc/bin/astyle
9export CFLAGS="-O3 -DTRAVIS_ENV=1" 9export CFLAGS="-O3 -DTRAVIS_ENV=1"
10export CXXFLAGS="-O3 -DTRAVIS_ENV=1" 10export CXXFLAGS="-O3 -DTRAVIS_ENV=1"
11export CMAKE_EXTRA_FLAGS="-DERROR_ON_WARNING=ON"
12export MAKE=make 11export MAKE=make
13 12
14BUILD_DIR=_build 13BUILD_DIR=_build
diff --git a/other/travis/toxcore-script b/other/travis/toxcore-script
index f82fd978..ae2af416 100755
--- a/other/travis/toxcore-script
+++ b/other/travis/toxcore-script
@@ -28,14 +28,12 @@ RUN $CMAKE \
28 -B$BUILD_DIR \ 28 -B$BUILD_DIR \
29 -H. \ 29 -H. \
30 -DCMAKE_INSTALL_PREFIX:PATH=$CURDIR/_install \ 30 -DCMAKE_INSTALL_PREFIX:PATH=$CURDIR/_install \
31 -DASAN=ON \
32 -DDEBUG=ON \ 31 -DDEBUG=ON \
33 -DMUST_BUILD_TOXAV=ON \ 32 -DMUST_BUILD_TOXAV=ON \
34 -DSTRICT_ABI=ON \ 33 -DSTRICT_ABI=ON \
35 -DTEST_TIMEOUT_SECONDS=120 \ 34 -DTEST_TIMEOUT_SECONDS=120 \
36 -DTRACE=ON \ 35 -DTRACE=ON \
37 -DUSE_IPV6=$USE_IPV6 \ 36 -DUSE_IPV6=$USE_IPV6
38 $CMAKE_EXTRA_FLAGS
39 37
40export CTEST_OUTPUT_ON_FAILURE=1 38export CTEST_OUTPUT_ON_FAILURE=1
41 39
diff --git a/testing/av_test.c b/testing/av_test.c
index 5cc3b5dd..87a01871 100644
--- a/testing/av_test.c
+++ b/testing/av_test.c
@@ -45,7 +45,7 @@ extern "C" {
45#include "../toxav/ring_buffer.c" 45#include "../toxav/ring_buffer.c"
46 46
47#include "../toxav/toxav.h" 47#include "../toxav/toxav.h"
48#include "../toxcore/network.h" /* current_time_monotonic() */ 48#include "../toxcore/mono_time.h" /* current_time_monotonic() */
49#include "../toxcore/tox.h" 49#include "../toxcore/tox.h"
50#include "../toxcore/util.h" 50#include "../toxcore/util.h"
51 51
diff --git a/toxav/audio.c b/toxav/audio.c
index 75d3d477..6889ef09 100644
--- a/toxav/audio.c
+++ b/toxav/audio.c
@@ -29,6 +29,7 @@
29#include "rtp.h" 29#include "rtp.h"
30 30
31#include "../toxcore/logger.h" 31#include "../toxcore/logger.h"
32#include "../toxcore/mono_time.h"
32 33
33static struct JitterBuffer *jbuf_new(uint32_t capacity); 34static struct JitterBuffer *jbuf_new(uint32_t capacity);
34static void jbuf_clear(struct JitterBuffer *q); 35static void jbuf_clear(struct JitterBuffer *q);
diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c
index 2d7dd659..05fac704 100644
--- a/toxav/bwcontroller.c
+++ b/toxav/bwcontroller.c
@@ -31,6 +31,7 @@
31#include "ring_buffer.h" 31#include "ring_buffer.h"
32 32
33#include "../toxcore/logger.h" 33#include "../toxcore/logger.h"
34#include "../toxcore/mono_time.h"
34#include "../toxcore/util.h" 35#include "../toxcore/util.h"
35 36
36#define BWC_PACKET_ID 196 37#define BWC_PACKET_ID 196
diff --git a/toxav/groupav.c b/toxav/groupav.c
index 8936801a..15fdd534 100644
--- a/toxav/groupav.c
+++ b/toxav/groupav.c
@@ -27,6 +27,7 @@
27#include <string.h> 27#include <string.h>
28 28
29#include "../toxcore/logger.h" 29#include "../toxcore/logger.h"
30#include "../toxcore/mono_time.h"
30#include "../toxcore/util.h" 31#include "../toxcore/util.h"
31 32
32#define GROUP_JBUF_SIZE 6 33#define GROUP_JBUF_SIZE 6
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 1e178720..3d563a1f 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -32,6 +32,7 @@
32 32
33#include "../toxcore/Messenger.h" 33#include "../toxcore/Messenger.h"
34#include "../toxcore/logger.h" 34#include "../toxcore/logger.h"
35#include "../toxcore/mono_time.h"
35#include "../toxcore/util.h" 36#include "../toxcore/util.h"
36 37
37enum { 38enum {
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 36bf9cc2..5abe1130 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -28,6 +28,7 @@
28 28
29#include "../toxcore/Messenger.h" 29#include "../toxcore/Messenger.h"
30#include "../toxcore/logger.h" 30#include "../toxcore/logger.h"
31#include "../toxcore/mono_time.h"
31#include "../toxcore/util.h" 32#include "../toxcore/util.h"
32 33
33#include <assert.h> 34#include <assert.h>
diff --git a/toxav/video.c b/toxav/video.c
index 1126b8e6..5145c29c 100644
--- a/toxav/video.c
+++ b/toxav/video.c
@@ -32,6 +32,7 @@
32#include "rtp.h" 32#include "rtp.h"
33 33
34#include "../toxcore/logger.h" 34#include "../toxcore/logger.h"
35#include "../toxcore/mono_time.h"
35#include "../toxcore/network.h" 36#include "../toxcore/network.h"
36 37
37/** 38/**
diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel
index 381a1255..543bb59f 100644
--- a/toxcore/BUILD.bazel
+++ b/toxcore/BUILD.bazel
@@ -59,6 +59,22 @@ cc_library(
59) 59)
60 60
61cc_library( 61cc_library(
62 name = "mono_time",
63 srcs = ["mono_time.c"],
64 hdrs = ["mono_time.h"],
65 deps = [":ccompat"],
66)
67
68cc_test(
69 name = "mono_time_test",
70 srcs = ["mono_time_test.cc"],
71 deps = [
72 ":mono_time",
73 "@com_google_googletest//:gtest_main",
74 ],
75)
76
77cc_library(
62 name = "network", 78 name = "network",
63 srcs = [ 79 srcs = [
64 "network.c", 80 "network.c",
@@ -77,6 +93,7 @@ cc_library(
77 ":ccompat", 93 ":ccompat",
78 ":crypto_core", 94 ":crypto_core",
79 ":logger", 95 ":logger",
96 ":mono_time",
80 ], 97 ],
81) 98)
82 99
diff --git a/toxcore/DHT.c b/toxcore/DHT.c
index fe3c1159..2572b28a 100644
--- a/toxcore/DHT.c
+++ b/toxcore/DHT.c
@@ -29,6 +29,7 @@
29 29
30#include "LAN_discovery.h" 30#include "LAN_discovery.h"
31#include "logger.h" 31#include "logger.h"
32#include "mono_time.h"
32#include "network.h" 33#include "network.h"
33#include "ping.h" 34#include "ping.h"
34#include "state.h" 35#include "state.h"
diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc
index 4a007a66..a68b2a7d 100644
--- a/toxcore/Makefile.inc
+++ b/toxcore/Makefile.inc
@@ -8,6 +8,8 @@ libtoxcore_la_includedir = $(includedir)/tox
8libtoxcore_la_SOURCES = ../toxcore/ccompat.h \ 8libtoxcore_la_SOURCES = ../toxcore/ccompat.h \
9 ../toxcore/DHT.h \ 9 ../toxcore/DHT.h \
10 ../toxcore/DHT.c \ 10 ../toxcore/DHT.c \
11 ../toxcore/mono_time.h \
12 ../toxcore/mono_time.c \
11 ../toxcore/network.h \ 13 ../toxcore/network.h \
12 ../toxcore/network.c \ 14 ../toxcore/network.c \
13 ../toxcore/crypto_core.h \ 15 ../toxcore/crypto_core.h \
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 404827c6..a5d15a34 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -34,6 +34,7 @@
34#include <time.h> 34#include <time.h>
35 35
36#include "logger.h" 36#include "logger.h"
37#include "mono_time.h"
37#include "network.h" 38#include "network.h"
38#include "state.h" 39#include "state.h"
39#include "util.h" 40#include "util.h"
@@ -1764,8 +1765,8 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv
1764 1765
1765 if (position >= ft->size) { 1766 if (position >= ft->size) {
1766 LOGGER_DEBUG(m->log, 1767 LOGGER_DEBUG(m->log,
1767 "file control (friend %d, file %d): seek position %lld exceeds file size %lld", 1768 "file control (friend %d, file %d): seek position %ld exceeds file size %ld",
1768 friendnumber, filenumber, (unsigned long long)position, (unsigned long long)ft->size); 1769 friendnumber, filenumber, (unsigned long)position, (unsigned long)ft->size);
1769 return -1; 1770 return -1;
1770 } 1771 }
1771 1772
diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c
index d1cd4d66..1291d276 100644
--- a/toxcore/TCP_client.c
+++ b/toxcore/TCP_client.c
@@ -31,6 +31,7 @@
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
33 33
34#include "mono_time.h"
34#include "util.h" 35#include "util.h"
35 36
36struct TCP_Client_Connection { 37struct TCP_Client_Connection {
diff --git a/toxcore/TCP_connection.c b/toxcore/TCP_connection.c
index 06cb6e34..cd1fb565 100644
--- a/toxcore/TCP_connection.c
+++ b/toxcore/TCP_connection.c
@@ -31,6 +31,7 @@
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
33 33
34#include "mono_time.h"
34#include "util.h" 35#include "util.h"
35 36
36 37
diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c
index b31fab72..032b07b3 100644
--- a/toxcore/TCP_server.c
+++ b/toxcore/TCP_server.c
@@ -39,6 +39,7 @@
39#include <unistd.h> 39#include <unistd.h>
40#endif 40#endif
41 41
42#include "mono_time.h"
42#include "util.h" 43#include "util.h"
43 44
44typedef struct TCP_Secure_Connection { 45typedef struct TCP_Secure_Connection {
diff --git a/toxcore/friend_connection.c b/toxcore/friend_connection.c
index 64a04773..4d245871 100644
--- a/toxcore/friend_connection.c
+++ b/toxcore/friend_connection.c
@@ -31,6 +31,7 @@
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
33 33
34#include "mono_time.h"
34#include "util.h" 35#include "util.h"
35 36
36#define PORTS_PER_DISCOVERY 10 37#define PORTS_PER_DISCOVERY 10
diff --git a/toxcore/group.c b/toxcore/group.c
index b7042f2f..4942d872 100644
--- a/toxcore/group.c
+++ b/toxcore/group.c
@@ -30,6 +30,7 @@
30#include <stdlib.h> 30#include <stdlib.h>
31#include <string.h> 31#include <string.h>
32 32
33#include "mono_time.h"
33#include "util.h" 34#include "util.h"
34 35
35/* return 1 if the groupnumber is not valid. 36/* return 1 if the groupnumber is not valid.
diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c
new file mode 100644
index 00000000..6f54731b
--- /dev/null
+++ b/toxcore/mono_time.c
@@ -0,0 +1,157 @@
1#ifndef _XOPEN_SOURCE
2#define _XOPEN_SOURCE 600
3#endif
4
5#if !defined(OS_WIN32) && (defined(_WIN32) || defined(__WIN32__) || defined(WIN32))
6#define OS_WIN32
7#define WIN32_LEAN_AND_MEAN
8#include <windows.h>
9#endif
10
11#ifdef __APPLE__
12#include <mach/clock.h>
13#include <mach/mach.h>
14#endif
15
16#ifndef OS_WIN32
17#include <sys/time.h>
18#endif
19
20#include "mono_time.h"
21
22#include <stdlib.h>
23#include <time.h>
24
25#include "ccompat.h"
26
27/* don't call into system billions of times for no reason */
28struct Mono_Time {
29 uint64_t time;
30 uint64_t base_time;
31};
32
33Mono_Time *mono_time_new(void)
34{
35 Mono_Time *monotime = (Mono_Time *)malloc(sizeof(Mono_Time));
36
37 if (monotime == nullptr) {
38 return nullptr;
39 }
40
41 monotime->time = 0;
42 monotime->base_time = 0;
43
44 return monotime;
45}
46
47void mono_time_free(Mono_Time *monotime)
48{
49 free(monotime);
50}
51
52void mono_time_update(Mono_Time *monotime)
53{
54 if (monotime->base_time == 0) {
55 monotime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL));
56 }
57
58 monotime->time = (current_time_monotonic() / 1000ULL) + monotime->base_time;
59}
60
61uint64_t mono_time_get(const Mono_Time *monotime)
62{
63 return monotime->time;
64}
65
66bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout)
67{
68 return timestamp + timeout <= mono_time_get(monotime);
69}
70
71
72static Mono_Time global_time;
73
74/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of
75 * unix_time() may fail to increase monotonically with increasing time */
76void unix_time_update(void)
77{
78 mono_time_update(&global_time);
79}
80uint64_t unix_time(void)
81{
82 return mono_time_get(&global_time);
83}
84int is_timeout(uint64_t timestamp, uint64_t timeout)
85{
86 return mono_time_is_timeout(&global_time, timestamp, timeout);
87}
88
89
90
91/* return current UNIX time in microseconds (us). */
92uint64_t current_time_actual(void)
93{
94 uint64_t time;
95#ifdef OS_WIN32
96 /* This probably works fine */
97 FILETIME ft;
98 GetSystemTimeAsFileTime(&ft);
99 time = ft.dwHighDateTime;
100 time <<= 32;
101 time |= ft.dwLowDateTime;
102 time -= 116444736000000000ULL;
103 return time / 10;
104#else
105 struct timeval a;
106 gettimeofday(&a, nullptr);
107 time = 1000000ULL * a.tv_sec + a.tv_usec;
108 return time;
109#endif
110}
111
112
113#ifdef OS_WIN32
114static uint64_t last_monotime;
115static uint64_t add_monotime;
116#endif
117
118/* return current monotonic time in milliseconds (ms). */
119uint64_t current_time_monotonic(void)
120{
121 uint64_t time;
122#ifdef OS_WIN32
123 uint64_t old_add_monotime = add_monotime;
124 time = (uint64_t)GetTickCount() + add_monotime;
125
126 /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race
127 * conditions when multiple threads call this function at once */
128 if (time + 0x10000 < last_monotime) {
129 uint32_t add = ~0;
130 /* use old_add_monotime rather than simply incrementing add_monotime, to handle the case that many threads
131 * simultaneously detect an overflow */
132 add_monotime = old_add_monotime + add;
133 time += add;
134 }
135
136 last_monotime = time;
137#else
138 struct timespec monotime;
139#if defined(__linux__) && defined(CLOCK_MONOTONIC_RAW)
140 clock_gettime(CLOCK_MONOTONIC_RAW, &monotime);
141#elif defined(__APPLE__)
142 clock_serv_t muhclock;
143 mach_timespec_t machtime;
144
145 host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock);
146 clock_get_time(muhclock, &machtime);
147 mach_port_deallocate(mach_task_self(), muhclock);
148
149 monotime.tv_sec = machtime.tv_sec;
150 monotime.tv_nsec = machtime.tv_nsec;
151#else
152 clock_gettime(CLOCK_MONOTONIC, &monotime);
153#endif
154 time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL);
155#endif
156 return time;
157}
diff --git a/toxcore/mono_time.h b/toxcore/mono_time.h
new file mode 100644
index 00000000..63e0f49d
--- /dev/null
+++ b/toxcore/mono_time.h
@@ -0,0 +1,35 @@
1#ifndef C_TOXCORE_TOXCORE_MONO_TIME_H
2#define C_TOXCORE_TOXCORE_MONO_TIME_H
3
4#include <stdbool.h>
5#include <stdint.h>
6
7#ifdef __cplusplus
8extern "C" {
9#endif
10
11typedef struct Mono_Time Mono_Time;
12
13Mono_Time *mono_time_new(void);
14void mono_time_free(Mono_Time *monotime);
15
16void mono_time_update(Mono_Time *monotime);
17uint64_t mono_time_get(const Mono_Time *monotime);
18bool mono_time_is_timeout(const Mono_Time *monotime, uint64_t timestamp, uint64_t timeout);
19
20// TODO(#405): Use per-tox monotime, delete these functions.
21void unix_time_update(void);
22uint64_t unix_time(void);
23int is_timeout(uint64_t timestamp, uint64_t timeout);
24
25/* return current UNIX time in microseconds (us). */
26uint64_t current_time_actual(void);
27
28/* return current monotonic time in milliseconds (ms). */
29uint64_t current_time_monotonic(void);
30
31#ifdef __cplusplus
32}
33#endif
34
35#endif // C_TOXCORE_TOXCORE_MONO_TIME_H
diff --git a/toxcore/mono_time_test.cc b/toxcore/mono_time_test.cc
new file mode 100644
index 00000000..5ad91322
--- /dev/null
+++ b/toxcore/mono_time_test.cc
@@ -0,0 +1,30 @@
1#include "mono_time.h"
2
3#include <gtest/gtest.h>
4
5namespace {
6
7TEST(Util, UnixTimeIncreasesOverTime) {
8 unix_time_update();
9 uint64_t const start = unix_time();
10
11 while (start == unix_time()) {
12 unix_time_update();
13 }
14
15 uint64_t const end = unix_time();
16 EXPECT_GT(end, start);
17}
18
19TEST(Util, IsTimeout) {
20 uint64_t const start = unix_time();
21 EXPECT_FALSE(is_timeout(start, 1));
22
23 while (start == unix_time()) {
24 unix_time_update();
25 }
26
27 EXPECT_TRUE(is_timeout(start, 1));
28}
29
30} // namespace
diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c
index f4c6335b..b9ffaf21 100644
--- a/toxcore/net_crypto.c
+++ b/toxcore/net_crypto.c
@@ -33,6 +33,7 @@
33#include <stdlib.h> 33#include <stdlib.h>
34#include <string.h> 34#include <string.h>
35 35
36#include "mono_time.h"
36#include "util.h" 37#include "util.h"
37 38
38typedef struct Packet_Data { 39typedef struct Packet_Data {
diff --git a/toxcore/network.c b/toxcore/network.c
index 2a32a170..24e53c47 100644
--- a/toxcore/network.c
+++ b/toxcore/network.c
@@ -170,6 +170,7 @@ static int inet_pton(int family, const char *addrString, void *addrbuf)
170#include <string.h> 170#include <string.h>
171 171
172#include "logger.h" 172#include "logger.h"
173#include "mono_time.h"
173#include "util.h" 174#include "util.h"
174 175
175// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD 176// Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD
@@ -418,74 +419,6 @@ int set_socket_dualstack(Socket sock)
418} 419}
419 420
420 421
421/* return current UNIX time in microseconds (us). */
422static uint64_t current_time_actual(void)
423{
424 uint64_t time;
425#ifdef OS_WIN32
426 /* This probably works fine */
427 FILETIME ft;
428 GetSystemTimeAsFileTime(&ft);
429 time = ft.dwHighDateTime;
430 time <<= 32;
431 time |= ft.dwLowDateTime;
432 time -= 116444736000000000ULL;
433 return time / 10;
434#else
435 struct timeval a;
436 gettimeofday(&a, nullptr);
437 time = 1000000ULL * a.tv_sec + a.tv_usec;
438 return time;
439#endif
440}
441
442
443#ifdef OS_WIN32
444static uint64_t last_monotime;
445static uint64_t add_monotime;
446#endif
447
448/* return current monotonic time in milliseconds (ms). */
449uint64_t current_time_monotonic(void)
450{
451 uint64_t time;
452#ifdef OS_WIN32
453 uint64_t old_add_monotime = add_monotime;
454 time = (uint64_t)GetTickCount() + add_monotime;
455
456 /* Check if time has decreased because of 32 bit wrap from GetTickCount(), while avoiding false positives from race
457 * conditions when multiple threads call this function at once */
458 if (time + 0x10000 < last_monotime) {
459 uint32_t add = ~0;
460 /* use old_add_monotime rather than simply incrementing add_monotime, to handle the case that many threads
461 * simultaneously detect an overflow */
462 add_monotime = old_add_monotime + add;
463 time += add;
464 }
465
466 last_monotime = time;
467#else
468 struct timespec monotime;
469#if defined(__linux__) && defined(CLOCK_MONOTONIC_RAW)
470 clock_gettime(CLOCK_MONOTONIC_RAW, &monotime);
471#elif defined(__APPLE__)
472 clock_serv_t muhclock;
473 mach_timespec_t machtime;
474
475 host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock);
476 clock_get_time(muhclock, &machtime);
477 mach_port_deallocate(mach_task_self(), muhclock);
478
479 monotime.tv_sec = machtime.tv_sec;
480 monotime.tv_nsec = machtime.tv_nsec;
481#else
482 clock_gettime(CLOCK_MONOTONIC, &monotime);
483#endif
484 time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL);
485#endif
486 return time;
487}
488
489static uint32_t data_0(uint16_t buflen, const uint8_t *buffer) 422static uint32_t data_0(uint16_t buflen, const uint8_t *buffer)
490{ 423{
491 return buflen > 4 ? net_ntohl(*(const uint32_t *)&buffer[1]) : 0; 424 return buflen > 4 ? net_ntohl(*(const uint32_t *)&buffer[1]) : 0;
diff --git a/toxcore/network.h b/toxcore/network.h
index fbd12bb7..8f166c67 100644
--- a/toxcore/network.h
+++ b/toxcore/network.h
@@ -381,9 +381,6 @@ int set_socket_reuseaddr(Socket sock);
381 */ 381 */
382int set_socket_dualstack(Socket sock); 382int set_socket_dualstack(Socket sock);
383 383
384/* return current monotonic time in milliseconds (ms). */
385uint64_t current_time_monotonic(void);
386
387/* Basic network functions: */ 384/* Basic network functions: */
388 385
389/* Function to send packet(data) of length length to ip_port. */ 386/* Function to send packet(data) of length length to ip_port. */
diff --git a/toxcore/onion.c b/toxcore/onion.c
index cfe12a05..5ba716fd 100644
--- a/toxcore/onion.c
+++ b/toxcore/onion.c
@@ -30,6 +30,7 @@
30#include <stdlib.h> 30#include <stdlib.h>
31#include <string.h> 31#include <string.h>
32 32
33#include "mono_time.h"
33#include "util.h" 34#include "util.h"
34 35
35#define RETURN_1 ONION_RETURN_1 36#define RETURN_1 ONION_RETURN_1
diff --git a/toxcore/onion_announce.c b/toxcore/onion_announce.c
index 8f122fe6..d368face 100644
--- a/toxcore/onion_announce.c
+++ b/toxcore/onion_announce.c
@@ -31,6 +31,7 @@
31#include <string.h> 31#include <string.h>
32 32
33#include "LAN_discovery.h" 33#include "LAN_discovery.h"
34#include "mono_time.h"
34#include "util.h" 35#include "util.h"
35 36
36#define PING_ID_TIMEOUT ONION_ANNOUNCE_TIMEOUT 37#define PING_ID_TIMEOUT ONION_ANNOUNCE_TIMEOUT
diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c
index 483d6409..9c59343d 100644
--- a/toxcore/onion_client.c
+++ b/toxcore/onion_client.c
@@ -32,6 +32,7 @@
32#include <string.h> 32#include <string.h>
33 33
34#include "LAN_discovery.h" 34#include "LAN_discovery.h"
35#include "mono_time.h"
35#include "util.h" 36#include "util.h"
36 37
37/* defines for the array size and 38/* defines for the array size and
diff --git a/toxcore/ping.c b/toxcore/ping.c
index 3767805d..1bf096bf 100644
--- a/toxcore/ping.c
+++ b/toxcore/ping.c
@@ -33,6 +33,7 @@
33#include <string.h> 33#include <string.h>
34 34
35#include "DHT.h" 35#include "DHT.h"
36#include "mono_time.h"
36#include "network.h" 37#include "network.h"
37#include "ping_array.h" 38#include "ping_array.h"
38#include "util.h" 39#include "util.h"
diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c
index ded3ed3a..142640dd 100644
--- a/toxcore/ping_array.c
+++ b/toxcore/ping_array.c
@@ -31,6 +31,7 @@
31#include <string.h> 31#include <string.h>
32 32
33#include "crypto_core.h" 33#include "crypto_core.h"
34#include "mono_time.h"
34#include "util.h" 35#include "util.h"
35 36
36 37
diff --git a/toxcore/tox.c b/toxcore/tox.c
index c121eb2e..4c764aeb 100644
--- a/toxcore/tox.c
+++ b/toxcore/tox.c
@@ -518,6 +518,11 @@ static void set_friend_error(int32_t ret, Tox_Err_Friend_Add *error)
518 case FAERR_NOMEM: 518 case FAERR_NOMEM:
519 SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_MALLOC); 519 SET_ERROR_PARAMETER(error, TOX_ERR_FRIEND_ADD_MALLOC);
520 break; 520 break;
521
522 default:
523 /* can't happen */
524 assert(!"impossible: unknown friend-add error");
525 break;
521 } 526 }
522} 527}
523 528
@@ -826,7 +831,9 @@ static void set_message_error(int ret, Tox_Err_Friend_Send_Message *error)
826 break; 831 break;
827 832
828 case -5: 833 case -5:
834 default:
829 /* can't happen */ 835 /* can't happen */
836 assert(!"impossible: unknown send-message error");
830 break; 837 break;
831 } 838 }
832} 839}
diff --git a/toxcore/util.c b/toxcore/util.c
index 0bc77c05..5ab092ce 100644
--- a/toxcore/util.c
+++ b/toxcore/util.c
@@ -34,75 +34,12 @@
34#include "util.h" 34#include "util.h"
35 35
36#include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */ 36#include "crypto_core.h" /* for CRYPTO_PUBLIC_KEY_SIZE */
37#include "network.h" /* for current_time_monotonic */
38 37
39#include <stdlib.h> 38#include <stdlib.h>
40#include <string.h> 39#include <string.h>
41#include <time.h> 40#include <time.h>
42 41
43 42
44/* don't call into system billions of times for no reason */
45struct Unix_Time {
46 uint64_t time;
47 uint64_t base_time;
48};
49
50Unix_Time *unix_time_new(void)
51{
52 Unix_Time *unixtime = (Unix_Time *)malloc(sizeof(Unix_Time));
53
54 if (unixtime == nullptr) {
55 return nullptr;
56 }
57
58 unixtime->time = 0;
59 unixtime->base_time = 0;
60
61 return unixtime;
62}
63
64void unix_time_free(Unix_Time *unixtime)
65{
66 free(unixtime);
67}
68
69void unix_time_update_r(Unix_Time *unixtime)
70{
71 if (unixtime->base_time == 0) {
72 unixtime->base_time = ((uint64_t)time(nullptr) - (current_time_monotonic() / 1000ULL));
73 }
74
75 unixtime->time = (current_time_monotonic() / 1000ULL) + unixtime->base_time;
76}
77
78uint64_t unix_time_get(const Unix_Time *unixtime)
79{
80 return unixtime->time;
81}
82
83int unix_time_is_timeout(const Unix_Time *unixtime, uint64_t timestamp, uint64_t timeout)
84{
85 return timestamp + timeout <= unix_time_get(unixtime);
86}
87
88static Unix_Time global_time;
89
90/* XXX: note that this is not thread-safe; if multiple threads call unix_time_update() concurrently, the return value of
91 * unix_time() may fail to increase monotonically with increasing time */
92void unix_time_update(void)
93{
94 unix_time_update_r(&global_time);
95}
96uint64_t unix_time(void)
97{
98 return unix_time_get(&global_time);
99}
100int is_timeout(uint64_t timestamp, uint64_t timeout)
101{
102 return unix_time_is_timeout(&global_time, timestamp, timeout);
103}
104
105
106/* id functions */ 43/* id functions */
107bool id_equal(const uint8_t *dest, const uint8_t *src) 44bool id_equal(const uint8_t *dest, const uint8_t *src)
108{ 45{
diff --git a/toxcore/util.h b/toxcore/util.h
index de493ebe..4c5023cf 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -39,21 +39,6 @@ extern "C" {
39#define MIN(a,b) (((a)<(b))?(a):(b)) 39#define MIN(a,b) (((a)<(b))?(a):(b))
40#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; } 40#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; }
41 41
42typedef struct Unix_Time Unix_Time;
43
44Unix_Time *unix_time_new(void);
45void unix_time_free(Unix_Time *unixtime);
46
47// TODO(#405): Use per-tox unixtime, remove unix_time_update, and rename
48// unix_time_update_r to unix_time_update.
49void unix_time_update_r(Unix_Time *unixtime);
50uint64_t unix_time_get(const Unix_Time *unixtime);
51int unix_time_is_timeout(const Unix_Time *unixtime, uint64_t timestamp, uint64_t timeout);
52
53void unix_time_update(void);
54uint64_t unix_time(void);
55int is_timeout(uint64_t timestamp, uint64_t timeout);
56
57/* id functions */ 42/* id functions */
58bool id_equal(const uint8_t *dest, const uint8_t *src); 43bool id_equal(const uint8_t *dest, const uint8_t *src);
59uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */ 44uint32_t id_copy(uint8_t *dest, const uint8_t *src); /* return value is CLIENT_ID_SIZE */
diff --git a/toxcore/util_test.cc b/toxcore/util_test.cc
index 541aa61f..ff57f3fb 100644
--- a/toxcore/util_test.cc
+++ b/toxcore/util_test.cc
@@ -4,28 +4,7 @@
4 4
5#include <gtest/gtest.h> 5#include <gtest/gtest.h>
6 6
7TEST(Util, UnixTimeIncreasesOverTime) { 7namespace {
8 unix_time_update();
9 uint64_t const start = unix_time();
10
11 while (start == unix_time()) {
12 unix_time_update();
13 }
14
15 uint64_t const end = unix_time();
16 EXPECT_GT(end, start);
17}
18
19TEST(Util, IsTimeout) {
20 uint64_t const start = unix_time();
21 EXPECT_FALSE(is_timeout(start, 1));
22
23 while (start == unix_time()) {
24 unix_time_update();
25 }
26
27 EXPECT_TRUE(is_timeout(start, 1));
28}
29 8
30TEST(Util, TwoRandomIdsAreNotEqual) { 9TEST(Util, TwoRandomIdsAreNotEqual) {
31 uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE]; 10 uint8_t pk1[CRYPTO_PUBLIC_KEY_SIZE];
@@ -49,3 +28,5 @@ TEST(Util, IdCopyMakesKeysEqual) {
49 28
50 EXPECT_TRUE(id_equal(pk1, pk2)); 29 EXPECT_TRUE(id_equal(pk1, pk2));
51} 30}
31
32} // namespace