diff --git a/mongoose.c b/mongoose.c index 7314a7ad..69343bd0 100644 --- a/mongoose.c +++ b/mongoose.c @@ -3860,21 +3860,22 @@ void mg_sha1_final(unsigned char digest[20], mg_sha1_ctx *context) { int64_t mg_sntp_parse(const unsigned char *buf, size_t len) { int64_t res = -1; int mode = len > 0 ? buf[0] & 7 : 0; + int version = len > 0 ? (buf[0] >> 3) & 7 : 0; if (len < 48) { MG_ERROR(("%s", "corrupt packet")); - } else if ((buf[0] & 0x38) >> 3 != 4) { - MG_ERROR(("%s", "wrong version")); } else if (mode != 4 && mode != 5) { MG_ERROR(("%s", "not a server reply")); } else if (buf[1] == 0) { MG_ERROR(("%s", "server sent a kiss of death")); - } else { + } else if (version == 4 || version == 3) { uint32_t *data = (uint32_t *) &buf[40]; unsigned long seconds = mg_ntohl(data[0]) - SNTP_TIME_OFFSET; unsigned long useconds = mg_ntohl(data[1]); - // MG_DEBUG(("%lu %lu %lu", time(0), seconds, useconds)); res = ((int64_t) seconds) * 1000 + (int64_t) ((useconds / 1000) % 1000); + } else { + MG_ERROR(("unexpected version: %d", version)); } + if (res == -1) mg_hexdump(buf, len); return res; } diff --git a/src/sntp.c b/src/sntp.c index 3bcdf784..e0c801b5 100644 --- a/src/sntp.c +++ b/src/sntp.c @@ -10,21 +10,22 @@ int64_t mg_sntp_parse(const unsigned char *buf, size_t len) { int64_t res = -1; int mode = len > 0 ? buf[0] & 7 : 0; + int version = len > 0 ? (buf[0] >> 3) & 7 : 0; if (len < 48) { MG_ERROR(("%s", "corrupt packet")); - } else if ((buf[0] & 0x38) >> 3 != 4) { - MG_ERROR(("%s", "wrong version")); } else if (mode != 4 && mode != 5) { MG_ERROR(("%s", "not a server reply")); } else if (buf[1] == 0) { MG_ERROR(("%s", "server sent a kiss of death")); - } else { + } else if (version == 4 || version == 3) { uint32_t *data = (uint32_t *) &buf[40]; unsigned long seconds = mg_ntohl(data[0]) - SNTP_TIME_OFFSET; unsigned long useconds = mg_ntohl(data[1]); - // MG_DEBUG(("%lu %lu %lu", time(0), seconds, useconds)); res = ((int64_t) seconds) * 1000 + (int64_t) ((useconds / 1000) % 1000); + } else { + MG_ERROR(("unexpected version: %d", version)); } + if (res == -1) mg_hexdump(buf, len); return res; } diff --git a/test/unit_test.c b/test/unit_test.c index 6412a06c..08375b83 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -285,30 +285,33 @@ 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) { *(int64_t *) fnd = *(int64_t *) evd; - } else if (ev == MG_EV_POLL) { - // For some reason, GA on macos fails often, apparently SNTP request - // gets lost. We re-send it each poll - if (c->is_resolving == 0) mg_sntp_request(c); + MG_DEBUG(("got time: %lld", *(int64_t *) evd)); } (void) c; } -static void test_sntp(void) { +static void test_sntp_server(const char *url) { 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, &ms); + c = mg_sntp_connect(&mgr, url, sntp_cb, &ms); ASSERT(c != NULL); ASSERT(c->is_udp == 1); for (i = 0; i < 60 && ms == 0; i++) mg_mgr_poll(&mgr, 50); - MG_DEBUG(("ms: %lld", ms)); + MG_DEBUG(("server: %s, ms: %lld", url ? url : "(default)", ms)); ASSERT(ms > 0); mg_mgr_free(&mgr); +} + +static void test_sntp(void) { + test_sntp_server("udp://time.windows.com:123"); + test_sntp_server(NULL); { + int64_t ms; const unsigned char sntp_good[] = "\x24\x02\x00\xeb\x00\x00\x00\x1e\x00\x00\x07\xb6\x3e" "\xc9\xd6\xa2\xdb\xde\xea\x30\x91\x86\xb7\x10\xdb\xde"