From ae6767b1d25cb33136ea259ef3634f35592d8fcd Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Tue, 21 Dec 2021 21:50:18 +0000 Subject: [PATCH] Use int64_t for timers and mg_millis() --- docs/README.md | 29 +++++++++++++------------- mongoose.c | 54 ++++++++++++++++++++++++------------------------ mongoose.h | 32 +++++++++++++++------------- src/arch_win32.h | 10 +++++---- src/dns.c | 6 +++--- src/event.h | 4 ++-- src/sntp.c | 26 ++++++++++++----------- src/sntp.h | 2 +- src/sock.c | 2 +- src/timer.c | 13 ++++++------ src/timer.h | 12 ++++++----- src/util.c | 7 +++---- src/util.h | 4 ++-- test/fuzz.c | 5 ++--- test/unit_test.c | 35 +++++++++++++++---------------- 15 files changed, 123 insertions(+), 118 deletions(-) diff --git a/docs/README.md b/docs/README.md index 78b1a422..752e4b3f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -133,7 +133,7 @@ to an event handler: ```c enum { MG_EV_ERROR, // Error char *error_message - MG_EV_POLL, // mg_mgr_poll iteration unsigned long *millis + MG_EV_POLL, // mg_mgr_poll iteration int64_t *milliseconds MG_EV_RESOLVE, // Host name is resolved NULL MG_EV_CONNECT, // Connection established NULL MG_EV_ACCEPT, // Connection accepted NULL @@ -148,7 +148,7 @@ enum { MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message * MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message * MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code - MG_EV_SNTP_TIME, // SNTP time received struct timeval * + MG_EV_SNTP_TIME, // SNTP time received int64_t *milliseconds MG_EV_USER, // Starting ID for user events }; ``` @@ -1903,16 +1903,15 @@ mg_tls_init(c, &opts); ```c struct mg_timer { - int period_ms; // Timer period in milliseconds - int flags; // Possible flags values below - void (*fn)(void *); // Function to call - void *arg; // Function argument - unsigned long expire; // Expiration timestamp in milliseconds - struct mg_timer *next; // Linkage in g_timers list -}; - + int64_t period_ms; // Timer period in milliseconds + int64_t expire; // Expiration timestamp in milliseconds + unsigned flags; // Possible flags values below #define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set + void (*fn)(void *); // Function to call + void *arg; // Function argument + struct mg_timer *next; // Linkage in g_timers list +}; ``` Timer structure. Describes a software timer. Timer granularity is the same @@ -1921,7 +1920,7 @@ as the `mg_mgr_poll()` timeout argument in the main event loop. ### mg\_timer\_init() ```c -void mg_timer_init(struct mg_timer *t, unsigned long ms, unsigned flags, +void mg_timer_init(struct mg_timer *t, int64_t period_ms, unsigned flags, void (*fn)(void *), void *fn_data); ``` @@ -1969,7 +1968,7 @@ mg_timer_free(&timer); ### mg\_timer\_poll() ```c -void mg_timer_poll(unsigned long uptime_ms); +void mg_timer_poll(int64_t uptime_ms); ``` Traverse list of timers and call them if current timestamp `uptime_ms` is @@ -1986,7 +1985,7 @@ Return value: None Usage example: ```c -unsigned long now = mg_millis(); +int64_t now = mg_millis(); mg_timer_poll(now); ``` @@ -1995,7 +1994,7 @@ mg_timer_poll(now); ### mg\_millis() ```c -unsigned long mg_millis(void); +int64_t mg_millis(void); ``` Return current uptime in milliseconds. @@ -2007,7 +2006,7 @@ Return value: Current uptime Usage example: ```c -unsigned long uptime = mg_millis(); +int64_t uptime = mg_millis(); ``` ## String diff --git a/mongoose.c b/mongoose.c index 5848d14d..ceacb63b 100644 --- a/mongoose.c +++ b/mongoose.c @@ -117,7 +117,7 @@ int mg_base64_decode(const char *src, int n, char *dst) { struct dns_data { struct dns_data *next; struct mg_connection *c; - unsigned long expire; + int64_t expire; uint16_t txnid; }; @@ -242,7 +242,7 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { struct dns_data *d, *tmp; if (ev == MG_EV_POLL) { - unsigned long now = *(unsigned long *) ev_data; + int64_t now = *(int64_t *) ev_data; for (d = s_reqs; d != NULL; d = tmp) { tmp = d->next; // LOG(LL_DEBUG, ("%lu %lu dns poll", d->expire, now)); @@ -356,7 +356,7 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms, d->txnid = s_reqs ? (uint16_t) (s_reqs->txnid + 1) : 1; d->next = s_reqs; s_reqs = d; - d->expire = mg_millis() + (unsigned long) ms; + d->expire = mg_millis() + (int64_t) ms; d->c = c; c->is_resolving = 1; LOG(LL_VERBOSE_DEBUG, @@ -2785,13 +2785,14 @@ void mg_hmac_sha1(const unsigned char *key, size_t keylen, -#define SNTP_INTERVAL_SEC (3600) +#define SNTP_INTERVAL_SEC 3600 #define SNTP_TIME_OFFSET 2208988800UL static unsigned long s_sntmp_next; -int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv) { - int mode = len > 0 ? buf[0] & 7 : 0, res = -1; +int64_t mg_sntp_parse(const unsigned char *buf, size_t len) { + int64_t res = -1; + int mode = len > 0 ? buf[0] & 7 : 0; if (len < 48) { LOG(LL_ERROR, ("%s", "corrupt packet")); } else if ((buf[0] & 0x38) >> 3 != 4) { @@ -2802,21 +2803,22 @@ int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv) { LOG(LL_ERROR, ("%s", "server sent a kiss of death")); } else { uint32_t *data = (uint32_t *) &buf[40]; - tv->tv_sec = (time_t) (mg_ntohl(data[0]) - SNTP_TIME_OFFSET); - tv->tv_usec = (suseconds_t) mg_ntohl(data[1]); - s_sntmp_next = (unsigned long) (tv->tv_sec + SNTP_INTERVAL_SEC); - res = 0; + unsigned long seconds = mg_ntohl(data[0]) - SNTP_TIME_OFFSET; + unsigned long useconds = mg_ntohl(data[1]); + // LOG(LL_DEBUG, ("%lu %lu %lu", time(0), seconds, useconds)); + res = ((int64_t) seconds) * 1000 + (int64_t) ((useconds / 1000) % 1000); + s_sntmp_next = seconds + SNTP_INTERVAL_SEC; } return res; } static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) { if (ev == MG_EV_READ) { - struct timeval tv = {0, 0}; - if (mg_sntp_parse(c->recv.buf, c->recv.len, &tv) == 0) { - mg_call(c, MG_EV_SNTP_TIME, &tv); - LOG(LL_DEBUG, ("%u.%u, next at %lu", (unsigned) tv.tv_sec, - (unsigned) tv.tv_usec, s_sntmp_next)); + int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len); + if (milliseconds > 0) { + mg_call(c, MG_EV_SNTP_TIME, &milliseconds); + LOG(LL_DEBUG, ("%u.%u, next at %lu", (unsigned) (milliseconds / 1000), + (unsigned) (milliseconds % 1000), s_sntmp_next)); } c->recv.len = 0; // Clear receive buffer } else if (ev == MG_EV_CONNECT) { @@ -3424,7 +3426,7 @@ static void connect_conn(struct mg_connection *c) { void mg_mgr_poll(struct mg_mgr *mgr, int ms) { struct mg_connection *c, *tmp; - unsigned long now; + int64_t now; mg_iotest(mgr, ms); now = mg_millis(); @@ -3657,7 +3659,7 @@ struct mg_str mg_strstrip(struct mg_str s) { struct mg_timer *g_timers; -void mg_timer_init(struct mg_timer *t, unsigned long ms, unsigned flags, +void mg_timer_init(struct mg_timer *t, int64_t ms, unsigned flags, void (*fn)(void *), void *arg) { struct mg_timer tmp = {ms, 0UL, flags, fn, arg, g_timers}; *t = tmp; @@ -3671,11 +3673,11 @@ void mg_timer_free(struct mg_timer *t) { if (*head) *head = t->next; } -void mg_timer_poll(unsigned long now_ms) { +void mg_timer_poll(int64_t now_ms) { // If time goes back (wrapped around), reset timers struct mg_timer *t, *tmp; - static unsigned long oldnow; // Timestamp in a previous invocation - if (oldnow > now_ms) { // If it is wrapped, reset timers + static int64_t oldnow; // Timestamp in a previous invocation + if (oldnow > now_ms) { // If it is wrapped, reset timers for (t = g_timers; t != NULL; t = t->next) t->expire = 0; } oldnow = now_ms; @@ -3687,9 +3689,8 @@ void mg_timer_poll(unsigned long now_ms) { t->fn(t->arg); // Try to tick timers with the given period as accurate as possible, // even if this polling function is called with some random period. - t->expire = now_ms - t->expire > (unsigned long) t->period_ms - ? now_ms + t->period_ms - : t->expire + t->period_ms; + t->expire = now_ms - t->expire > t->period_ms ? now_ms + t->period_ms + : t->expire + t->period_ms; if (!(t->flags & MG_TIMER_REPEAT)) mg_timer_free(t); } } @@ -4457,7 +4458,7 @@ int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip) { return allowed == '+'; } -unsigned long mg_millis(void) { +int64_t mg_millis(void) { #if MG_ARCH == MG_ARCH_WIN32 return GetTickCount(); #elif MG_ARCH == MG_ARCH_ESP32 @@ -4474,7 +4475,7 @@ unsigned long mg_millis(void) { mach_timebase_info(&timebase); double ticks_to_nanos = (double) timebase.numer / timebase.denom; uint64_t uptime_nanos = (uint64_t) (ticks_to_nanos * ticks); - return (unsigned long) (uptime_nanos / 1000000); + return (int64_t) (uptime_nanos / 1000000); #else struct timespec ts; #ifdef _POSIX_MONOTONIC_CLOCK @@ -4486,8 +4487,7 @@ unsigned long mg_millis(void) { #else clock_gettime(CLOCK_REALTIME, &ts); #endif - return (unsigned long) ((uint64_t) ts.tv_sec * 1000 + - (uint64_t) ts.tv_nsec / 1000000); + return ((int64_t) ts.tv_sec * 1000 + (int64_t) ts.tv_nsec / 1000000); #endif } diff --git a/mongoose.h b/mongoose.h index bc551116..447f51d6 100644 --- a/mongoose.h +++ b/mongoose.h @@ -427,13 +427,15 @@ typedef int socklen_t; // https://lgtm.com/rules/2154840805/ -gmtime, localtime, ctime and asctime static __inline struct tm *gmtime_r(time_t *t, struct tm *tm) { - (void) tm; - return gmtime(t); + struct tm *x = gmtime(t); + *tm = *x; + return tm; } static __inline struct tm *localtime_r(time_t *t, struct tm *tm) { - (void) tm; - return localtime(t); + struct tm *x = localtime(t); + *tm = *x; + return tm; } #endif @@ -581,9 +583,11 @@ void mg_log_set_callback(void (*fn)(const void *, size_t, void *), void *param); #endif + + struct mg_timer { - unsigned long period_ms; // Timer period in milliseconds - unsigned long expire; // Expiration timestamp in milliseconds + int64_t period_ms; // Timer period in milliseconds + int64_t expire; // Expiration timestamp in milliseconds unsigned flags; // Possible flags values below #define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set @@ -594,10 +598,10 @@ struct mg_timer { extern struct mg_timer *g_timers; // Global list of timers -void mg_timer_init(struct mg_timer *, unsigned long ms, unsigned, - void (*fn)(void *), void *); +void mg_timer_init(struct mg_timer *, int64_t, unsigned, void (*)(void *), + void *); void mg_timer_free(struct mg_timer *); -void mg_timer_poll(unsigned long current_time_ms); +void mg_timer_poll(int64_t current_time_ms); @@ -619,9 +623,9 @@ void mg_unhex(const char *buf, size_t len, unsigned char *to); unsigned long mg_unhexn(const char *s, size_t len); int mg_asprintf(char **buf, size_t size, const char *fmt, ...); int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap); -int64_t mg_to64(struct mg_str str); int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip); -unsigned long mg_millis(void); +int64_t mg_to64(struct mg_str str); +int64_t mg_millis(void); #define mg_htons(x) mg_ntohs(x) #define mg_htonl(x) mg_ntohl(x) @@ -763,7 +767,7 @@ void mg_error(struct mg_connection *c, const char *fmt, ...); enum { MG_EV_ERROR, // Error char *error_message MG_EV_OPEN, // Connection created NULL - MG_EV_POLL, // mg_mgr_poll iteration unsigned long *millis + MG_EV_POLL, // mg_mgr_poll iteration int64_t *milliseconds MG_EV_RESOLVE, // Host name is resolved NULL MG_EV_CONNECT, // Connection established NULL MG_EV_ACCEPT, // Connection accepted NULL @@ -778,7 +782,7 @@ enum { MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message * MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message * MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code - MG_EV_SNTP_TIME, // SNTP time received struct timeval * + MG_EV_SNTP_TIME, // SNTP time received int64_t *milliseconds MG_EV_USER, // Starting ID for user events }; @@ -1020,7 +1024,7 @@ size_t mg_ws_wrap(struct mg_connection *, size_t len, int op); struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url, mg_event_handler_t fn, void *fn_data); void mg_sntp_send(struct mg_connection *c, unsigned long utc); -int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv); +int64_t mg_sntp_parse(const unsigned char *buf, size_t len); diff --git a/src/arch_win32.h b/src/arch_win32.h index c56da00d..84a9d1f2 100644 --- a/src/arch_win32.h +++ b/src/arch_win32.h @@ -89,13 +89,15 @@ typedef int socklen_t; // https://lgtm.com/rules/2154840805/ -gmtime, localtime, ctime and asctime static __inline struct tm *gmtime_r(time_t *t, struct tm *tm) { - (void) tm; - return gmtime(t); + struct tm *x = gmtime(t); + *tm = *x; + return tm; } static __inline struct tm *localtime_r(time_t *t, struct tm *tm) { - (void) tm; - return localtime(t); + struct tm *x = localtime(t); + *tm = *x; + return tm; } #endif diff --git a/src/dns.c b/src/dns.c index 0f9a8563..36a5cdcd 100644 --- a/src/dns.c +++ b/src/dns.c @@ -7,7 +7,7 @@ struct dns_data { struct dns_data *next; struct mg_connection *c; - unsigned long expire; + int64_t expire; uint16_t txnid; }; @@ -132,7 +132,7 @@ static void dns_cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { struct dns_data *d, *tmp; if (ev == MG_EV_POLL) { - unsigned long now = *(unsigned long *) ev_data; + int64_t now = *(int64_t *) ev_data; for (d = s_reqs; d != NULL; d = tmp) { tmp = d->next; // LOG(LL_DEBUG, ("%lu %lu dns poll", d->expire, now)); @@ -246,7 +246,7 @@ static void mg_sendnsreq(struct mg_connection *c, struct mg_str *name, int ms, d->txnid = s_reqs ? (uint16_t) (s_reqs->txnid + 1) : 1; d->next = s_reqs; s_reqs = d; - d->expire = mg_millis() + (unsigned long) ms; + d->expire = mg_millis() + (int64_t) ms; d->c = c; c->is_resolving = 1; LOG(LL_VERBOSE_DEBUG, diff --git a/src/event.h b/src/event.h index ddb136ee..8578ab0b 100644 --- a/src/event.h +++ b/src/event.h @@ -9,7 +9,7 @@ void mg_error(struct mg_connection *c, const char *fmt, ...); enum { MG_EV_ERROR, // Error char *error_message MG_EV_OPEN, // Connection created NULL - MG_EV_POLL, // mg_mgr_poll iteration unsigned long *millis + MG_EV_POLL, // mg_mgr_poll iteration int64_t *milliseconds MG_EV_RESOLVE, // Host name is resolved NULL MG_EV_CONNECT, // Connection established NULL MG_EV_ACCEPT, // Connection accepted NULL @@ -24,6 +24,6 @@ enum { MG_EV_MQTT_CMD, // MQTT low-level command struct mg_mqtt_message * MG_EV_MQTT_MSG, // MQTT PUBLISH received struct mg_mqtt_message * MG_EV_MQTT_OPEN, // MQTT CONNACK received int *connack_status_code - MG_EV_SNTP_TIME, // SNTP time received struct timeval * + MG_EV_SNTP_TIME, // SNTP time received int64_t *milliseconds MG_EV_USER, // Starting ID for user events }; diff --git a/src/sntp.c b/src/sntp.c index 7f15ebdf..d4197ef2 100644 --- a/src/sntp.c +++ b/src/sntp.c @@ -4,13 +4,14 @@ #include "log.h" #include "util.h" -#define SNTP_INTERVAL_SEC (3600) +#define SNTP_INTERVAL_SEC 3600 #define SNTP_TIME_OFFSET 2208988800UL static unsigned long s_sntmp_next; -int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv) { - int mode = len > 0 ? buf[0] & 7 : 0, res = -1; +int64_t mg_sntp_parse(const unsigned char *buf, size_t len) { + int64_t res = -1; + int mode = len > 0 ? buf[0] & 7 : 0; if (len < 48) { LOG(LL_ERROR, ("%s", "corrupt packet")); } else if ((buf[0] & 0x38) >> 3 != 4) { @@ -21,21 +22,22 @@ int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv) { LOG(LL_ERROR, ("%s", "server sent a kiss of death")); } else { uint32_t *data = (uint32_t *) &buf[40]; - tv->tv_sec = (time_t) (mg_ntohl(data[0]) - SNTP_TIME_OFFSET); - tv->tv_usec = (suseconds_t) mg_ntohl(data[1]); - s_sntmp_next = (unsigned long) (tv->tv_sec + SNTP_INTERVAL_SEC); - res = 0; + unsigned long seconds = mg_ntohl(data[0]) - SNTP_TIME_OFFSET; + unsigned long useconds = mg_ntohl(data[1]); + // LOG(LL_DEBUG, ("%lu %lu %lu", time(0), seconds, useconds)); + res = ((int64_t) seconds) * 1000 + (int64_t) ((useconds / 1000) % 1000); + s_sntmp_next = seconds + SNTP_INTERVAL_SEC; } return res; } static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) { if (ev == MG_EV_READ) { - struct timeval tv = {0, 0}; - if (mg_sntp_parse(c->recv.buf, c->recv.len, &tv) == 0) { - mg_call(c, MG_EV_SNTP_TIME, &tv); - LOG(LL_DEBUG, ("%u.%u, next at %lu", (unsigned) tv.tv_sec, - (unsigned) tv.tv_usec, s_sntmp_next)); + int64_t milliseconds = mg_sntp_parse(c->recv.buf, c->recv.len); + if (milliseconds > 0) { + mg_call(c, MG_EV_SNTP_TIME, &milliseconds); + LOG(LL_DEBUG, ("%u.%u, next at %lu", (unsigned) (milliseconds / 1000), + (unsigned) (milliseconds % 1000), s_sntmp_next)); } c->recv.len = 0; // Clear receive buffer } else if (ev == MG_EV_CONNECT) { diff --git a/src/sntp.h b/src/sntp.h index cc947ff1..c9beb50c 100644 --- a/src/sntp.h +++ b/src/sntp.h @@ -5,4 +5,4 @@ struct mg_connection *mg_sntp_connect(struct mg_mgr *mgr, const char *url, mg_event_handler_t fn, void *fn_data); void mg_sntp_send(struct mg_connection *c, unsigned long utc); -int mg_sntp_parse(const unsigned char *buf, size_t len, struct timeval *tv); +int64_t mg_sntp_parse(const unsigned char *buf, size_t len); diff --git a/src/sock.c b/src/sock.c index 9d3e8bb8..0ef02b90 100644 --- a/src/sock.c +++ b/src/sock.c @@ -572,7 +572,7 @@ static void connect_conn(struct mg_connection *c) { void mg_mgr_poll(struct mg_mgr *mgr, int ms) { struct mg_connection *c, *tmp; - unsigned long now; + int64_t now; mg_iotest(mgr, ms); now = mg_millis(); diff --git a/src/timer.c b/src/timer.c index 2e9a61ce..8c1effb4 100644 --- a/src/timer.c +++ b/src/timer.c @@ -6,7 +6,7 @@ struct mg_timer *g_timers; -void mg_timer_init(struct mg_timer *t, unsigned long ms, unsigned flags, +void mg_timer_init(struct mg_timer *t, int64_t ms, unsigned flags, void (*fn)(void *), void *arg) { struct mg_timer tmp = {ms, 0UL, flags, fn, arg, g_timers}; *t = tmp; @@ -20,11 +20,11 @@ void mg_timer_free(struct mg_timer *t) { if (*head) *head = t->next; } -void mg_timer_poll(unsigned long now_ms) { +void mg_timer_poll(int64_t now_ms) { // If time goes back (wrapped around), reset timers struct mg_timer *t, *tmp; - static unsigned long oldnow; // Timestamp in a previous invocation - if (oldnow > now_ms) { // If it is wrapped, reset timers + static int64_t oldnow; // Timestamp in a previous invocation + if (oldnow > now_ms) { // If it is wrapped, reset timers for (t = g_timers; t != NULL; t = t->next) t->expire = 0; } oldnow = now_ms; @@ -36,9 +36,8 @@ void mg_timer_poll(unsigned long now_ms) { t->fn(t->arg); // Try to tick timers with the given period as accurate as possible, // even if this polling function is called with some random period. - t->expire = now_ms - t->expire > (unsigned long) t->period_ms - ? now_ms + t->period_ms - : t->expire + t->period_ms; + t->expire = now_ms - t->expire > t->period_ms ? now_ms + t->period_ms + : t->expire + t->period_ms; if (!(t->flags & MG_TIMER_REPEAT)) mg_timer_free(t); } } diff --git a/src/timer.h b/src/timer.h index 2371e1ce..62e4a5b6 100644 --- a/src/timer.h +++ b/src/timer.h @@ -1,8 +1,10 @@ #pragma once +#include "arch.h" + struct mg_timer { - unsigned long period_ms; // Timer period in milliseconds - unsigned long expire; // Expiration timestamp in milliseconds + int64_t period_ms; // Timer period in milliseconds + int64_t expire; // Expiration timestamp in milliseconds unsigned flags; // Possible flags values below #define MG_TIMER_REPEAT 1 // Call function periodically, otherwise run once #define MG_TIMER_RUN_NOW 2 // Call immediately when timer is set @@ -13,7 +15,7 @@ struct mg_timer { extern struct mg_timer *g_timers; // Global list of timers -void mg_timer_init(struct mg_timer *, unsigned long ms, unsigned, - void (*fn)(void *), void *); +void mg_timer_init(struct mg_timer *, int64_t, unsigned, void (*)(void *), + void *); void mg_timer_free(struct mg_timer *); -void mg_timer_poll(unsigned long current_time_ms); +void mg_timer_poll(int64_t current_time_ms); diff --git a/src/util.c b/src/util.c index 80b433c2..bcc0dbf3 100644 --- a/src/util.c +++ b/src/util.c @@ -299,7 +299,7 @@ int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip) { return allowed == '+'; } -unsigned long mg_millis(void) { +int64_t mg_millis(void) { #if MG_ARCH == MG_ARCH_WIN32 return GetTickCount(); #elif MG_ARCH == MG_ARCH_ESP32 @@ -316,7 +316,7 @@ unsigned long mg_millis(void) { mach_timebase_info(&timebase); double ticks_to_nanos = (double) timebase.numer / timebase.denom; uint64_t uptime_nanos = (uint64_t) (ticks_to_nanos * ticks); - return (unsigned long) (uptime_nanos / 1000000); + return (int64_t) (uptime_nanos / 1000000); #else struct timespec ts; #ifdef _POSIX_MONOTONIC_CLOCK @@ -328,7 +328,6 @@ unsigned long mg_millis(void) { #else clock_gettime(CLOCK_REALTIME, &ts); #endif - return (unsigned long) ((uint64_t) ts.tv_sec * 1000 + - (uint64_t) ts.tv_nsec / 1000000); + return ((int64_t) ts.tv_sec * 1000 + (int64_t) ts.tv_nsec / 1000000); #endif } diff --git a/src/util.h b/src/util.h index 501abb36..7e99c6b7 100644 --- a/src/util.h +++ b/src/util.h @@ -19,9 +19,9 @@ void mg_unhex(const char *buf, size_t len, unsigned char *to); unsigned long mg_unhexn(const char *s, size_t len); int mg_asprintf(char **buf, size_t size, const char *fmt, ...); int mg_vasprintf(char **buf, size_t size, const char *fmt, va_list ap); -int64_t mg_to64(struct mg_str str); int mg_check_ip_acl(struct mg_str acl, uint32_t remote_ip); -unsigned long mg_millis(void); +int64_t mg_to64(struct mg_str str); +int64_t mg_millis(void); #define mg_htons(x) mg_ntohs(x) #define mg_htonl(x) mg_ntohl(x) diff --git a/test/fuzz.c b/test/fuzz.c index 75ea5108..3a30178e 100644 --- a/test/fuzz.c +++ b/test/fuzz.c @@ -27,9 +27,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { mg_mqtt_parse(data, size, &mm); mg_mqtt_parse(NULL, 0, &mm); - struct timeval tv; - mg_sntp_parse(data, size, &tv); - mg_sntp_parse(NULL, 0, &tv); + mg_sntp_parse(data, size); + mg_sntp_parse(NULL, 0); char buf[size * 4 / 3 + 5]; // At least 4 chars and nul termination mg_base64_decode((char *) data, (int) size, buf); diff --git a/test/unit_test.c b/test/unit_test.c index 83add9d0..54da75f8 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -243,24 +243,24 @@ static void test_iobuf(void) { static void sntp_cb(struct mg_connection *c, int ev, void *evd, void *fnd) { if (ev == MG_EV_SNTP_TIME) { - *(struct timeval *) fnd = *(struct timeval *) evd; + *(int64_t *) fnd = *(int64_t *) evd; } (void) c; } static void test_sntp(void) { - struct timeval tv = {0, 0}; + int64_t ms = 0; struct mg_mgr mgr; struct mg_connection *c = NULL; int i; mg_mgr_init(&mgr); - c = mg_sntp_connect(&mgr, NULL, sntp_cb, &tv); + c = mg_sntp_connect(&mgr, NULL, sntp_cb, &ms); ASSERT(c != NULL); ASSERT(c->is_udp == 1); mg_sntp_send(c, (unsigned long) time(NULL)); - for (i = 0; i < 300 && tv.tv_sec == 0; i++) mg_mgr_poll(&mgr, 10); - ASSERT(tv.tv_sec > 0); + for (i = 0; i < 300 && ms == 0; i++) mg_mgr_poll(&mgr, 10); + ASSERT(ms > 0); mg_mgr_free(&mgr); { @@ -274,22 +274,21 @@ static void test_sntp(void) { "\xc9\xd6\xa2\xdb\xde\xea\x30\x91\x86\xb7\x10\xdb\xde" "\xed\x98\x00\x00\x00\xde\xdb\xde\xed\x99\x0a\xe2\xc7" "\x96\xdb\xde\xed\x99\x0a\xe4\x6b\xda"; - struct timeval tv2 = {0, 0}; - struct tm *tm; + struct tm tm; time_t t; - ASSERT(mg_sntp_parse(sntp_good, sizeof(sntp_good), &tv2) == 0); - t = tv2.tv_sec; - tm = gmtime(&t); - ASSERT(tm->tm_year == 116); - ASSERT(tm->tm_mon == 10); - ASSERT(tm->tm_mday == 22); - ASSERT(tm->tm_hour == 16); - ASSERT(tm->tm_min == 15); - ASSERT(tm->tm_sec == 21); - ASSERT(mg_sntp_parse(bad_good, sizeof(bad_good), &tv2) == -1); + ASSERT((ms = mg_sntp_parse(sntp_good, sizeof(sntp_good))) > 0); + t = (time_t) (ms / 1000); + gmtime_r(&t, &tm); + ASSERT(tm.tm_year == 116); + ASSERT(tm.tm_mon == 10); + ASSERT(tm.tm_mday == 22); + ASSERT(tm.tm_hour == 16); + ASSERT(tm.tm_min == 15); + ASSERT(tm.tm_sec == 21); + ASSERT(mg_sntp_parse(bad_good, sizeof(bad_good)) < 0); } - ASSERT(mg_sntp_parse(NULL, 0, &tv) == -1); + ASSERT(mg_sntp_parse(NULL, 0) == -1); } static void mqtt_cb(struct mg_connection *c, int ev, void *evd, void *fnd) {