diff --git a/include/libwebsockets.h b/include/libwebsockets.h index d900a44e0..6052d24a0 100644 --- a/include/libwebsockets.h +++ b/include/libwebsockets.h @@ -50,10 +50,10 @@ struct lws_dsh; * CARE: everything using cmake defines needs to be below here */ -#define LWS_US_PER_SEC 1000000 -#define LWS_MS_PER_SEC 1000 -#define LWS_US_PER_MS 1000 -#define LWS_NS_PER_US 1000 +#define LWS_US_PER_SEC ((lws_usec_t)1000000) +#define LWS_MS_PER_SEC ((lws_usec_t)1000) +#define LWS_US_PER_MS ((lws_usec_t)1000) +#define LWS_NS_PER_US ((lws_usec_t)1000) #define LWS_KI (1024) #define LWS_MI (LWS_KI * 1024) diff --git a/include/libwebsockets/lws-timeout-timer.h b/include/libwebsockets/lws-timeout-timer.h index f6b15dc43..9a0f2959f 100644 --- a/include/libwebsockets/lws-timeout-timer.h +++ b/include/libwebsockets/lws-timeout-timer.h @@ -114,7 +114,7 @@ void lws_set_timeout_us(struct lws *wsi, enum pending_timeout reason, lws_usec_t us); #define LWS_SET_TIMER_USEC_CANCEL ((lws_usec_t)-1ll) -#define LWS_USEC_PER_SEC (1000000ll) +#define LWS_USEC_PER_SEC ((lws_usec_t)1000000) /** * lws_set_timer_usecs() - schedules a callback on the wsi in the future diff --git a/lib/core-net/sorted-usec-list.c b/lib/core-net/sorted-usec-list.c index e54a4061f..72bd8a243 100644 --- a/lib/core-net/sorted-usec-list.c +++ b/lib/core-net/sorted-usec-list.c @@ -47,6 +47,7 @@ int __lws_sul_insert(lws_dll2_owner_t *own, lws_sorted_usec_list_t *sul, lws_usec_t us) { + lws_usec_t now = lws_now_usecs(); lws_dll2_remove(&sul->list); if (us == LWS_SET_TIMER_USEC_CANCEL) { @@ -56,7 +57,7 @@ __lws_sul_insert(lws_dll2_owner_t *own, lws_sorted_usec_list_t *sul, return 0; } - sul->us = lws_now_usecs() + us; + sul->us = now + us; assert(sul->cb); /* @@ -66,7 +67,28 @@ __lws_sul_insert(lws_dll2_owner_t *own, lws_sorted_usec_list_t *sul, lws_dll2_add_sorted(&sul->list, own, sul_compare); - // lws_dll2_describe(own, "post-tail-insert"); +#if 0 // defined(_DEBUG) + { + lws_usec_t worst = 0; + int n = 1; + + lwsl_info("%s: own %p: count %d\n", __func__, own, own->count); + + lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp, + lws_dll2_get_head(own)) { + lws_sorted_usec_list_t *sul = (lws_sorted_usec_list_t *)p; + lwsl_info("%s: %d: %llu (+%lld)\n", __func__, n++, + (unsigned long long)sul->us, + (long long)(sul->us - now)); + if (sul->us < worst) { + lwsl_err("%s: wrongly sorted sul entry!\n", + __func__); + assert(0); + } + worst = sul->us; + } lws_end_foreach_dll_safe(p, tp); + } +#endif return 0; } @@ -109,5 +131,10 @@ __lws_sul_check(lws_dll2_owner_t *own, lws_usec_t usnow) */ } + /* + * Nothing left to take care of in the list (cannot return 0 otherwise + * because we will service anything equal to usnow rather than return) + */ + return 0; } diff --git a/lib/core-net/wsi-timeout.c b/lib/core-net/wsi-timeout.c index 594800be5..2d74df347 100644 --- a/lib/core-net/wsi-timeout.c +++ b/lib/core-net/wsi-timeout.c @@ -178,7 +178,7 @@ lws_set_timeout_us(struct lws *wsi, enum pending_timeout reason, lws_usec_t us) lws_pt_lock(pt, __func__); __lws_sul_insert(&pt->pt_sul_owner, &wsi->sul_timeout, us); - lwsl_debug("%s: %p: %llu us, reason %d\n", __func__, wsi, + lwsl_notice("%s: %p: %llu us, reason %d\n", __func__, wsi, (unsigned long long)us, reason); wsi->pending_timeout = reason; diff --git a/lib/plat/unix/unix-misc.c b/lib/plat/unix/unix-misc.c index 8667746c8..07ca41982 100644 --- a/lib/plat/unix/unix-misc.c +++ b/lib/plat/unix/unix-misc.c @@ -34,12 +34,14 @@ lws_now_usecs(void) if (clock_gettime(CLOCK_MONOTONIC, &ts)) return 0; - return (ts.tv_sec * LWS_US_PER_SEC) + (ts.tv_nsec / LWS_NS_PER_US); + return (((lws_usec_t)ts.tv_sec) * LWS_US_PER_SEC) + + ((lws_usec_t)ts.tv_nsec / LWS_NS_PER_US); #else struct timeval now; gettimeofday(&now, NULL); - return (now.tv_sec * 1000000ll) + now.tv_usec; + return (((lws_usec_t)now.tv_sec) * LWS_US_PER_SEC) + + (lws_usec_t)now.tv_usec; #endif } diff --git a/lib/plat/unix/unix-service.c b/lib/plat/unix/unix-service.c index 21c586ee6..61ea1e087 100644 --- a/lib/plat/unix/unix-service.c +++ b/lib/plat/unix/unix-service.c @@ -60,6 +60,8 @@ _lws_plat_service_forced_tsi(struct lws_context *context, int tsi) return 0; } +#define LWS_POLL_WAIT_LIMIT 2000000000 + int _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) { @@ -86,7 +88,7 @@ _lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) timeout_ms = 0; else /* force a default timeout of 23 days */ - timeout_ms = 2000000000; + timeout_ms = LWS_POLL_WAIT_LIMIT; timeout_us = ((lws_usec_t)timeout_ms) * LWS_US_PER_MS; if (context->event_loop_ops->run_pt) @@ -123,9 +125,15 @@ again: lws_pt_unlock(pt); } + /* ensure we don't wrap at 2^31 with poll()'s signed int ms */ + + timeout_us /= LWS_US_PER_MS; /* ms now */ + if (timeout_us > LWS_POLL_WAIT_LIMIT) + timeout_us = LWS_POLL_WAIT_LIMIT; + vpt->inside_poll = 1; lws_memory_barrier(); - n = poll(pt->fds, pt->fds_count, timeout_us / LWS_US_PER_MS); + n = poll(pt->fds, pt->fds_count, timeout_us /* ms now */ ); vpt->inside_poll = 0; lws_memory_barrier(); diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/CMakeLists.txt b/minimal-examples/ws-server/minimal-ws-server-timer/CMakeLists.txt new file mode 100644 index 000000000..acf34686d --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 2.8) +include(CheckCSourceCompiles) + +set(SAMP lws-minimal-ws-server-timer) +set(SRCS minimal-ws-server.c) + +# If we are being built as part of lws, confirm current build config supports +# reqconfig, else skip building ourselves. +# +# If we are being built externally, confirm installed lws was configured to +# support reqconfig, else error out with a helpful message about the problem. +# +MACRO(require_lws_config reqconfig _val result) + + if (DEFINED ${reqconfig}) + if (${reqconfig}) + set (rq 1) + else() + set (rq 0) + endif() + else() + set(rq 0) + endif() + + if (${_val} EQUAL ${rq}) + set(SAME 1) + else() + set(SAME 0) + endif() + + if (LWS_WITH_MINIMAL_EXAMPLES AND NOT ${SAME}) + if (${_val}) + message("${SAMP}: skipping as lws being built without ${reqconfig}") + else() + message("${SAMP}: skipping as lws built with ${reqconfig}") + endif() + set(${result} 0) + else() + if (LWS_WITH_MINIMAL_EXAMPLES) + set(MET ${SAME}) + else() + CHECK_C_SOURCE_COMPILES("#include \nint main(void) {\n#if defined(${reqconfig})\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_${reqconfig}) + if (NOT DEFINED HAS_${reqconfig} OR NOT HAS_${reqconfig}) + set(HAS_${reqconfig} 0) + else() + set(HAS_${reqconfig} 1) + endif() + if ((HAS_${reqconfig} AND ${_val}) OR (NOT HAS_${reqconfig} AND NOT ${_val})) + set(MET 1) + else() + set(MET 0) + endif() + endif() + if (NOT MET) + if (${_val}) + message(FATAL_ERROR "This project requires lws must have been configured with ${reqconfig}") + else() + message(FATAL_ERROR "Lws configuration of ${reqconfig} is incompatible with this project") + endif() + endif() + + endif() +ENDMACRO() + +set(requirements 1) +require_lws_config(LWS_ROLE_WS 1 requirements) +require_lws_config(LWS_WITH_SERVER 1 requirements) + +if (requirements) + add_executable(${SAMP} ${SRCS}) + + if (websockets_shared) + target_link_libraries(${SAMP} websockets_shared) + add_dependencies(${SAMP} websockets_shared) + else() + target_link_libraries(${SAMP} websockets) + endif() +endif() diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/README.md b/minimal-examples/ws-server/minimal-ws-server-timer/README.md new file mode 100644 index 000000000..2f90df590 --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/README.md @@ -0,0 +1,34 @@ +# lws minimal ws server timer + +This is designed to confirm long term stability of ws timers on a +particular platform. + +## build + +``` + $ cmake . && make +``` + +## Commandline Options + +Option|Meaning +---|--- +-d|Set logging verbosity +-s|Serve using TLS selfsigned cert (ie, connect to it with https://...) +-h|Strict Host: header checking against vhost name (localhost) and port +-v|Connection validity use 3s / 10s instead of default 5m / 5m10s + +## usage + +``` + $ ./lws-minimal-ws-server-timer +[2018/03/04 09:30:02:7986] USER: LWS minimal ws server | visit http://localhost:7681 +[2018/03/04 09:30:02:7986] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 on +``` + +Visit http://localhost:7681 and the browser will connect back to the test +server, you'll see ESTABLISHED logged. That triggers a TIMER event at 20s +intervals which sets the wsi timeout to 60s. It should just stay like +that forever doing the TIMER events at 20s intervals and not sending any +traffic either way. + diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/localhost-100y.cert b/minimal-examples/ws-server/minimal-ws-server-timer/localhost-100y.cert new file mode 100644 index 000000000..6f372db40 --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/localhost-100y.cert @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +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 +e2Hl/7M0c/lbZ4FvXgARlex2rkgS0Ka06HE= +-----END CERTIFICATE----- diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/localhost-100y.key b/minimal-examples/ws-server/minimal-ws-server-timer/localhost-100y.key new file mode 100644 index 000000000..148f8598e --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/localhost-100y.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +fBrpEY1IATtPq1taBZZogRqI3rOkkPk= +-----END PRIVATE KEY----- diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/minimal-ws-server.c b/minimal-examples/ws-server/minimal-ws-server-timer/minimal-ws-server.c new file mode 100644 index 000000000..4288767e3 --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/minimal-ws-server.c @@ -0,0 +1,143 @@ +/* + * lws-minimal-ws-server-timer + * + * Written in 2010-2019 by Andy Green + * + * This file is made available under the Creative Commons CC0 1.0 + * Universal Public Domain Dedication. + * + * This demonstrates the most minimal http server you can make with lws, + * with an added websocket chat server. + * + * To keep it simple, it serves stuff in the subdirectory "./mount-origin" of + * the directory it was started in. + * You can change that by changing mount.origin. + */ + +#include +#include +#include + +static int +callback_protocol(struct lws *wsi, enum lws_callback_reasons reason, + void *user, void *in, size_t len) +{ + switch (reason) { + + case LWS_CALLBACK_ESTABLISHED: + lwsl_user("LWS_CALLBACK_ESTABLISHED\n"); + lws_set_timer_usecs(wsi, 20 * LWS_USEC_PER_SEC); + lws_set_timeout(wsi, 1, 60); + break; + + case LWS_CALLBACK_TIMER: + lwsl_user("LWS_CALLBACK_TIMER\n"); + lws_set_timer_usecs(wsi, 20 * LWS_USEC_PER_SEC); + lws_set_timeout(wsi, 1, 60); + break; + + case LWS_CALLBACK_CLOSED: + lwsl_user("LWS_CALLBACK_CLOSED\n"); + break; + + default: + break; + } + + return 0; +} + +static struct lws_protocols protocols[] = { + { "http", lws_callback_http_dummy, 0, 0 }, + { "timer", callback_protocol, 0, 0 }, + { NULL, NULL, 0, 0 } /* terminator */ +}; + +static const lws_retry_bo_t retry = { + .secs_since_valid_ping = 3, + .secs_since_valid_hangup = 10, +}; + +static int interrupted; + +static const struct lws_http_mount mount = { + /* .mount_next */ NULL, /* linked-list "next" */ + /* .mountpoint */ "/", /* mountpoint URL */ + /* .origin */ "./mount-origin", /* serve from dir */ + /* .def */ "index.html", /* default filename */ + /* .protocol */ NULL, + /* .cgienv */ NULL, + /* .extra_mimetypes */ NULL, + /* .interpret */ NULL, + /* .cgi_timeout */ 0, + /* .cache_max_age */ 0, + /* .auth_mask */ 0, + /* .cache_reusable */ 0, + /* .cache_revalidate */ 0, + /* .cache_intermediaries */ 0, + /* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */ + /* .mountpoint_len */ 1, /* char count */ + /* .basic_auth_login_file */ NULL, +}; + +void sigint_handler(int sig) +{ + interrupted = 1; +} + +int main(int argc, const char **argv) +{ + struct lws_context_creation_info info; + struct lws_context *context; + const char *p; + int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE + /* for LLL_ verbosity above NOTICE to be built into lws, + * lws must have been configured and built with + * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */ + /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */ + /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */ + /* | LLL_DEBUG */; + + signal(SIGINT, sigint_handler); + + if ((p = lws_cmdline_option(argc, argv, "-d"))) + logs = atoi(p); + + lws_set_log_level(logs, NULL); + lwsl_user("LWS minimal ws server | visit http://localhost:7681 (-s = use TLS / https)\n"); + + memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ + info.port = 7681; + info.mounts = &mount; + info.protocols = protocols; + info.vhost_name = "localhost"; + info.ws_ping_pong_interval = 10; + info.options = + LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE; + + if (lws_cmdline_option(argc, argv, "-s")) { + lwsl_user("Server using TLS\n"); + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + info.ssl_cert_filepath = "localhost-100y.cert"; + info.ssl_private_key_filepath = "localhost-100y.key"; + } + + if (lws_cmdline_option(argc, argv, "-h")) + info.options |= LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK; + + if (lws_cmdline_option(argc, argv, "-v")) + info.retry_and_idle_policy = &retry; + + context = lws_create_context(&info); + if (!context) { + lwsl_err("lws init failed\n"); + return 1; + } + + while (n >= 0 && !interrupted) + n = lws_service(context, 0); + + lws_context_destroy(context); + + return 0; +} diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/example.js b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/example.js new file mode 100644 index 000000000..3a638d0ab --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/example.js @@ -0,0 +1,69 @@ + +function get_appropriate_ws_url(extra_url) +{ + var pcol; + var u = document.URL; + + /* + * We open the websocket encrypted if this page came on an + * https:// url itself, otherwise unencrypted + */ + + if (u.substring(0, 5) === "https") { + pcol = "wss://"; + u = u.substr(8); + } else { + pcol = "ws://"; + if (u.substring(0, 4) === "http") + u = u.substr(7); + } + + u = u.split("/"); + + /* + "/xxx" bit is for IE10 workaround */ + + return pcol + u[0] + "/" + extra_url; +} + +function new_ws(urlpath, protocol) +{ + if (typeof MozWebSocket != "undefined") + return new MozWebSocket(urlpath, protocol); + + return new WebSocket(urlpath, protocol); +} + +document.addEventListener("DOMContentLoaded", function() { + + var ws = new_ws(get_appropriate_ws_url(""), "timer"); + try { + ws.onopen = function() { + document.getElementById("m").disabled = 0; + document.getElementById("b").disabled = 0; + }; + + ws.onmessage =function got_packet(msg) { + document.getElementById("r").value = + document.getElementById("r").value + msg.data + "\n"; + document.getElementById("r").scrollTop = + document.getElementById("r").scrollHeight; + }; + + ws.onclose = function(){ + document.getElementById("m").disabled = 1; + document.getElementById("b").disabled = 1; + }; + } catch(exception) { + alert("

Error " + exception); + } + + function sendmsg() + { + ws.send(document.getElementById("m").value); + document.getElementById("m").value = ""; + } + + document.getElementById("b").addEventListener("click", sendmsg); + +}, false); + diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/favicon.ico b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/favicon.ico new file mode 100644 index 000000000..c0cc2e3df Binary files /dev/null and b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/favicon.ico differ diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/index.html b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/index.html new file mode 100644 index 000000000..5b597867f --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/index.html @@ -0,0 +1,16 @@ + + + + + + + +
+ + LWS wsi timer minimal ws server timer example.
+ This opens a ws connection back to the server and just sits there + setting the timer to fire every 20s, which resets the wsi timeout + for 60s each timer. It should just stay like that forever. + + + diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/libwebsockets.org-logo.svg b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/libwebsockets.org-logo.svg new file mode 100644 index 000000000..7baea649f --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/libwebsockets.org-logo.svg @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/strict-csp.svg b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/strict-csp.svg new file mode 100644 index 000000000..cd128f1d2 --- /dev/null +++ b/minimal-examples/ws-server/minimal-ws-server-timer/mount-origin/strict-csp.svg @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +