Warmcat homepage andy@warmcat.com
libwebsockets
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"", "gen_ut":1746415715, "reponame":"sai", "desc":"Sai lightweight distributed CI", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://warmcat.com/repo/sai", "f":3, "items": [ {"schema":"libjg2-1", "cid":"c60a982570376673727ef717d907597b", "commit": {"type":"commit", "time": 1512099456, "time_ofs": 480, "oid_tree": { "oid": "5ceed404c7ad7ebb7f8fd943581e02682e8da5bd", "alias": []}, "oid":{ "oid": "f6de7465ecb094489be9cb73adb55ff48fcb4950", "alias": []}, "msg": "lws_compare_time_t: conceal time discontiguities on all platforms", "sig_commit": { "git_time": { "time": 1512099456, "offset": 480 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" }, "sig_author": { "git_time": { "time": 1511492459, "offset": 480 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" }}, "body": "lws_compare_time_t: conceal time discontiguities on all platforms\n\nThis provides platform-independent support for time discontiguities.\n\nOn embedded without battery RTC, commonly we only get time after\nNTP completes. This makes the cert checking happen when we have\na reasonable time and introduces lws_compare_time_t() to correctly\ncompare time_t s that may sit on either side of a time discontiguity." , "diff": "diff --git a/lib/context.c b/lib/context.c\nindex c6f4b51..0b50489 100644\n--- a/lib/context.c\n+++ b/lib/context.c\n@@ -1578,7 +1578,8 @@ lws_check_deferred_free(struct lws_context *context, int force)\n \n \tlws_start_foreach_llp(struct lws_deferred_free **, pdf,\n \t\t\t context-\u003edeferred_free_list) {\n-\t\tif (now \u003e (*pdf)-\u003edeadline || force) {\n+\t\tif (force ||\n+\t\t lws_compare_time_t(context, now, (*pdf)-\u003edeadline) \u003e 5) {\n \t\t\tdf \u003d *pdf;\n \t\t\t*pdf \u003d df-\u003enext;\n \t\t\t/* finalize vh destruction */\n@@ -1605,7 +1606,7 @@ lws_vhost_destroy(struct lws_vhost *vh)\n \t/* part 2 is deferred to allow all the handle closes to complete */\n \n \tdf-\u003enext \u003d vh-\u003econtext-\u003edeferred_free_list;\n-\tdf-\u003edeadline \u003d lws_now_secs() + 5;\n+\tdf-\u003edeadline \u003d lws_now_secs();\n \tdf-\u003epayload \u003d vh;\n \tvh-\u003econtext-\u003edeferred_free_list \u003d df;\n }\ndiff --git a/lib/libwebsockets.c b/lib/libwebsockets.c\nindex b8a4994..90120ee 100644\n--- a/lib/libwebsockets.c\n+++ b/lib/libwebsockets.c\n@@ -182,7 +182,8 @@ lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)\n \t}\n \n \tlwsl_debug(\u0022%s: %p: %d secs\u005cn\u0022, __func__, wsi, secs);\n-\twsi-\u003epending_timeout_limit \u003d now + secs;\n+\twsi-\u003epending_timeout_limit \u003d secs;\n+\twsi-\u003epending_timeout_set \u003d now;\n \twsi-\u003epending_timeout \u003d reason;\n \n \tlws_pt_unlock(pt);\n@@ -1295,6 +1296,18 @@ lws_now_secs(void)\n \treturn tv.tv_sec;\n }\n \n+LWS_VISIBLE LWS_EXTERN int\n+lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2)\n+{\n+\tif (t1 \u003c context-\u003etime_discontiguity)\n+\t\tt1 +\u003d context-\u003etime_fixup;\n+\n+\tif (t2 \u003c context-\u003etime_discontiguity)\n+\t\tt2 +\u003d context-\u003etime_fixup;\n+\n+\treturn (int)(t1 - t2);\n+}\n+\n \n #if LWS_POSIX\n \n@@ -2423,8 +2436,7 @@ lws_restart_ws_ping_pong_timer(struct lws *wsi)\n \tif (!lws_state_is_ws(wsi-\u003estate))\n \t\treturn;\n \n-\twsi-\u003ews-\u003etime_next_ping_check \u003d (time_t)lws_now_secs() +\n-\t\t\t\t wsi-\u003econtext-\u003ews_ping_pong_interval;\n+\twsi-\u003ews-\u003etime_next_ping_check \u003d (time_t)lws_now_secs();\n }\n \n static const char *hex \u003d \u00220123456789ABCDEF\u0022;\ndiff --git a/lib/libwebsockets.h b/lib/libwebsockets.h\nindex 3753a47..a695b66 100644\n--- a/lib/libwebsockets.h\n+++ b/lib/libwebsockets.h\n@@ -5287,6 +5287,26 @@ LWS_VISIBLE LWS_EXTERN unsigned long\n lws_now_secs(void);\n \n /**\n+ * lws_compare_time_t(): return relationship between two time_t\n+ *\n+ * \u005cparam context: struct lws_context\n+ * \u005cparam t1: time_t 1\n+ * \u005cparam t2: time_t 2\n+ *\n+ * returns \u003c0 if t2 \u003e t1; \u003e0 if t1 \u003e t2; or \u003d\u003d 0 if t1 \u003d\u003d t2.\n+ *\n+ * This is aware of clock discontiguities that may have affected either t1 or\n+ * t2 and adapts the comparison for them.\n+ *\n+ * For the discontiguity detection to work, you must avoid any arithmetic on\n+ * the times being compared. For example to have a timeout that triggers\n+ * 15s from when it was set, store the time it was set and compare like\n+ * `if (lws_compare_time_t(context, now, set_time) \u003e 15)`\n+ */\n+LWS_VISIBLE LWS_EXTERN int\n+lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2);\n+\n+/**\n * lws_get_context - Allow getting lws_context from a Websocket connection\n * instance\n *\ndiff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h\nindex ed2085a..f96688f 100644\n--- a/lib/private-libwebsockets.h\n+++ b/lib/private-libwebsockets.h\n@@ -1130,6 +1130,8 @@ struct lws_context {\n \ttime_t last_ws_ping_pong_check_s;\n \ttime_t last_cert_check_s;\n \ttime_t time_up;\n+\ttime_t time_discontiguity;\n+\ttime_t time_fixup;\n \tconst struct lws_plat_file_ops *fops;\n \tstruct lws_plat_file_ops fops_platform;\n #if defined(LWS_WITH_HTTP2)\n@@ -1974,7 +1976,7 @@ struct lws {\n \tuint64_t accept_start_us;\n #endif\n #endif\n-\ttime_t pending_timeout_limit;\n+\ttime_t pending_timeout_set;\n \n \t/* ints */\n \tint position_in_fds_table;\n@@ -2049,6 +2051,8 @@ struct lws {\n #ifndef LWS_NO_CLIENT\n \tunsigned short c_port;\n #endif\n+\tunsigned short pending_timeout_limit;\n+\n \tuint8_t state; /* enum lws_connection_states */\n \tuint8_t mode; /* enum connection_mode */\n \n@@ -2167,7 +2171,7 @@ lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len);\n \n \n LWS_EXTERN int LWS_WARN_UNUSED_RESULT\n-lws_service_timeout_check(struct lws *wsi, unsigned int sec);\n+lws_service_timeout_check(struct lws *wsi, time_t sec);\n \n LWS_EXTERN void\n lws_remove_from_timeout_list(struct lws *wsi);\ndiff --git a/lib/service.c b/lib/service.c\nindex 666c9af..7a0196c 100644\n--- a/lib/service.c\n+++ b/lib/service.c\n@@ -565,7 +565,7 @@ bail_die:\n }\n \n int\n-lws_service_timeout_check(struct lws *wsi, unsigned int sec)\n+lws_service_timeout_check(struct lws *wsi, time_t sec)\n {\n \tstruct lws_context_per_thread *pt \u003d \u0026wsi-\u003econtext-\u003ept[(int)wsi-\u003etsi];\n \tint n \u003d 0;\n@@ -586,7 +586,8 @@ lws_service_timeout_check(struct lws *wsi, unsigned int sec)\n \t * if we went beyond the allowed time, kill the\n \t * connection\n \t */\n-\tif ((time_t)sec \u003e wsi-\u003epending_timeout_limit) {\n+\tif (lws_compare_time_t(wsi-\u003econtext, sec, wsi-\u003epending_timeout_set) \u003e\n+\t wsi-\u003epending_timeout_limit) {\n \n \t\tif (wsi-\u003edesc.sockfd !\u003d LWS_SOCK_INVALID \u0026\u0026\n \t\t wsi-\u003eposition_in_fds_table \u003e\u003d 0)\n@@ -993,8 +994,31 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,\n \tif (context-\u003etime_up \u003c 1464083026 \u0026\u0026 now \u003e 1464083026)\n \t\tcontext-\u003etime_up \u003d now;\n \n-\t/* TODO: if using libev, we should probably use timeout watchers... */\n-\tif (context-\u003elast_timeout_check_s !\u003d now) {\n+\tif (context-\u003elast_timeout_check_s \u0026\u0026\n+\t now - context-\u003elast_timeout_check_s \u003e 100) {\n+\t\t/*\n+\t\t * There has been a discontiguity. Any stored time that is\n+\t\t * less than context-\u003etime_discontiguity should have context-\u003e\n+\t\t * time_fixup added to it.\n+\t\t *\n+\t\t * Some platforms with no RTC will experience this as a normal\n+\t\t * event when ntp sets their clock, but we can have started\n+\t\t * long before that with a 0-based unix time.\n+\t\t */\n+\n+\t\tcontext-\u003etime_discontiguity \u003d now;\n+\t\tcontext-\u003etime_fixup \u003d now - context-\u003elast_timeout_check_s;\n+\n+\t\tlwsl_notice(\u0022time discontiguity: at old time %llus, \u0022\n+\t\t\t \u0022new time %llus: +%llus\u005cn\u0022,\n+\t\t\t (unsigned long long)context-\u003elast_timeout_check_s,\n+\t\t\t (unsigned long long)context-\u003etime_discontiguity,\n+\t\t\t (unsigned long long)context-\u003etime_fixup);\n+\n+\t\tcontext-\u003elast_timeout_check_s \u003d now - 1;\n+\t}\n+\n+\tif (lws_compare_time_t(context, context-\u003elast_timeout_check_s, now)) {\n \t\tcontext-\u003elast_timeout_check_s \u003d now;\n \n #if defined(LWS_WITH_STATS)\ndiff --git a/lib/tls/tls.c b/lib/tls/tls.c\nindex 2572434..09ce781 100644\n--- a/lib/tls/tls.c\n+++ b/lib/tls/tls.c\n@@ -235,7 +235,7 @@ lws_tls_check_cert_lifetime(struct lws_vhost *v)\n \n \t\tn \u003d lws_tls_vhost_cert_info(v, LWS_TLS_CERT_INFO_VALIDITY_TO, \u0026ir, 0);\n \t\tif (n)\n-\t\t\treturn -1;\n+\t\t\treturn 1;\n \n \t\tlife \u003d (ir.time - now) / (24 * 3600);\n \t\tlwsl_notice(\u0022 vhost %s: cert expiry: %dd\u005cn\u0022, v-\u003ename, (int)life);\n@@ -254,7 +254,8 @@ lws_tls_check_all_cert_lifetimes(struct lws_context *context)\n \tstruct lws_vhost *v \u003d context-\u003evhost_list;\n \n \twhile (v) {\n-\t\tlws_tls_check_cert_lifetime(v);\n+\t\tif (lws_tls_check_cert_lifetime(v) \u003c 0)\n+\t\t\treturn -1;\n \t\tv \u003d v-\u003evhost_next;\n \t}\n \n","s":{"c":1746415715,"u": 13211}} ],"g": 14692,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}