diff --git a/minimal-examples/secure-streams/minimal-secure-streams-client-tx/CMakeLists.txt b/minimal-examples/secure-streams/minimal-secure-streams-client-tx/CMakeLists.txt index 286300f0b..272c8d9ca 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-client-tx/CMakeLists.txt +++ b/minimal-examples/secure-streams/minimal-secure-streams-client-tx/CMakeLists.txt @@ -17,6 +17,55 @@ require_lws_config(LWS_WITH_SECURE_STREAMS_PROXY_API 1 requirements) if (requirements) add_executable(${SAMP} ${SRCS}) + add_compile_options(-DLWS_SS_USE_SSPC) + + find_program(VALGRIND "valgrind") + + if (LWS_CTEST_INTERNET_AVAILABLE AND NOT WIN32) + + # + # Define test dep to bring up and take down the test + # proxy + # + + if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + # uds abstract namespace for linux + set(CTEST_SOCKET_PATH "@ctest-sspctx-$ENV{SAI_PROJECT}-$ENV{SAI_OVN}") + else() + # filesystem socket for others + set(CTEST_SOCKET_PATH "/tmp/ctest-sspctx-$ENV{SAI_PROJECT}-$ENV{SAI_OVN}") + endif() + add_test(NAME st_ssproxyctx COMMAND + ${CMAKE_SOURCE_DIR}/scripts/ctest-background.sh + ssproxyctx $ + -i ${CTEST_SOCKET_PATH} ) + set_tests_properties(st_ssproxyctx PROPERTIES WORKING_DIRECTORY . FIXTURES_SETUP ssproxyctx TIMEOUT 800) + + add_test(NAME ki_ssproxyctx COMMAND + ${CMAKE_SOURCE_DIR}/scripts/ctest-background-kill.sh + ssproxyctx $ + -i ${CTEST_SOCKET_PATH}) + set_tests_properties(ki_ssproxyctx PROPERTIES FIXTURES_CLEANUP ssproxyctx) + + # + # the client part that will connect to the proxy + # + + if (VALGRIND) + message("testing via valgrind") + add_test(NAME sspc-minimaltx COMMAND + ${VALGRIND} --tool=memcheck --leak-check=yes --num-callers=20 + $ -i +${CTEST_SOCKET_PATH}) + else() + add_test(NAME sspc-minimaltx COMMAND lws-minimal-secure-streams-client-tx -i +${CTEST_SOCKET_PATH}) + endif() + set_tests_properties(sspc-minimaltx PROPERTIES + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/minimal-examples/secure-streams/minimal-secure-streams-client-tx + FIXTURES_REQUIRED "ssproxyctx" + TIMEOUT 40) + + endif() + if (websockets_shared) target_link_libraries(${SAMP} websockets_shared ${LIBWEBSOCKETS_DEP_LIBS}) diff --git a/minimal-examples/secure-streams/minimal-secure-streams-client-tx/README.md b/minimal-examples/secure-streams/minimal-secure-streams-client-tx/README.md index 80a1c6928..19b74c65f 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-client-tx/README.md +++ b/minimal-examples/secure-streams/minimal-secure-streams-client-tx/README.md @@ -1,14 +1,9 @@ -# lws minimal secure streams +# lws minimal secure streams client tx -The application goes to https://warmcat.com and reads index.html there. +The application connects to the secure stream proxy, and opens a streamtype +"spam"... this is a websocket connection to libwebsockets.org. -It does it using Secure Streams... the main code in minimal-secure-streams.c -just sets up the context and opens a secure stream of type "mintest". - -The handler for state changes and payloads for "mintest" is in ss-myss.c - -The information about how a "mintest" stream should connect and the -protocol it uses is kept separated in policy-database.c +It then issues 100 x ws messages at 20Hz and exits. ## build @@ -25,40 +20,21 @@ Commandline option|Meaning -p| Run as proxy server for clients to connect to over unix domain socket ``` -[2019/08/12 07:16:11:0045] USR: LWS minimal secure streams [-d] [-f] -[2019/08/12 07:16:12:6102] USR: myss_state: LWSSSCS_CREATING, ord 0x0 -[2019/08/12 07:16:12:6107] USR: myss_state: LWSSSCS_POLL, ord 0x0 -[2019/08/12 07:16:12:6117] N: lws_ss_client_connect: connecting h1get warmcat.com / -[2019/08/12 07:16:12:6118] USR: myss_state: LWSSSCS_CONNECTING, ord 0x0 -[2019/08/12 07:16:13:4171] USR: myss_state: LWSSSCS_CONNECTED, ord 0x0 -[2019/08/12 07:16:13:4222] USR: myss_rx: len 1024, flags: 1 -[2019/08/12 07:16:13:4243] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4244] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4244] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4245] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4246] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4247] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4252] USR: myss_rx: len 1015, flags: 0 -[2019/08/12 07:16:13:4264] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4265] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4266] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4267] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4268] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4268] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4269] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4270] USR: myss_rx: len 1015, flags: 0 -[2019/08/12 07:16:13:4278] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4279] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4280] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4281] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4282] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4283] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4283] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4284] USR: myss_rx: len 1015, flags: 0 -[2019/08/12 07:16:13:4287] USR: myss_rx: len 1024, flags: 0 -[2019/08/12 07:16:13:4288] USR: myss_rx: len 947, flags: 0 -[2019/08/12 07:16:13:4293] USR: myss_rx: len 0, flags: 2 -[2019/08/12 07:16:13:4399] USR: myss_state: LWSSSCS_DISCONNECTED, ord 0x0 -[2019/08/12 07:16:13:4761] USR: myss_state: LWSSSCS_DESTROYING, ord 0x0 -[2019/08/12 07:16:13:4781] USR: Completed: OK +[2021/02/19 11:25:20:1396] U: LWS secure streams client TX [-d] +[2021/02/19 11:25:20:1756] N: LWS: 4.1.99-v4.1.0-280-ga329c51485, loglevel 1031 +[2021/02/19 11:25:20:1761] N: NET CLI SRV H1 H2 WS SS-JSON-POL SSPROX IPV6-on +[2021/02/19 11:25:20:2055] N: ++ [1100944|wsi|0|pipe] (1) +[2021/02/19 11:25:20:2133] N: ++ [1100944|vh|0|netlink] (1) +[2021/02/19 11:25:20:3647] N: ++ [1100944|vh|1|default] (2) +[2021/02/19 11:25:20:8590] N: ++ [1100944|SSPcli|0|spam] (1) +[2021/02/19 11:25:20:8810] N: ++ [1100944|wsiSSPcli|0|RAW/raw-skt/+@proxy.ss.lws/([1100944|SSPcli|0|spam])] (1) +[2021/02/19 11:25:20:9103] N: lws_sspc_sul_retry_cb: [1100944|wsiSSPcli|0|RAW/raw-skt/+@proxy.ss.lws/([1100944|SSPcli|0|spam|default])] +[2021/02/19 11:25:20:9795] U: myss_state: LWSSSCS_CREATING, ord 0x0 +[2021/02/19 11:25:20:9869] U: myss_state: LWSSSCS_CONNECTING, ord 0x0 +[2021/02/19 11:25:21:0791] U: myss_state: LWSSSCS_CONNECTED, ord 0x0 +[2021/02/19 11:25:21:1444] U: myss_tx: sending pkt 1 +[2021/02/19 11:25:21:1945] U: myss_tx: sending pkt 2 +[2021/02/19 11:25:21:2459] U: myss_tx: sending pkt 3 +[2021/02/19 11:25:21:2971] U: myss_tx: sending pkt 4 +... ``` diff --git a/minimal-examples/secure-streams/minimal-secure-streams-client-tx/minimal-secure-streams-client-tx.c b/minimal-examples/secure-streams/minimal-secure-streams-client-tx/minimal-secure-streams-client-tx.c index 33920250b..583b8d637 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-client-tx/minimal-secure-streams-client-tx.c +++ b/minimal-examples/secure-streams/minimal-secure-streams-client-tx/minimal-secure-streams-client-tx.c @@ -1,17 +1,21 @@ /* * lws-minimal-secure-streams-tx * - * Written in 2010-2020 by Andy Green + * Written in 2010-2021 by Andy Green * * This file is made available under the Creative Commons CC0 1.0 * Universal Public Domain Dedication. * * - * This demonstrates tx from secure streams. + * This demonstrates proxied mass tx from secure streams, this example is a + * client that has no policy of its own, but gets stuff done via the ss proxy. * - * It opens a stream and fires small 80-byte payloads on it at 50Hz (20ms) + * It opens a websocket stream and fires 100 x small 80-byte payloads on it + * at 20Hz (50ms) */ +#define LWS_SS_USE_SSPC + #include #include #include @@ -22,7 +26,7 @@ static int interrupted, bad = 1; typedef struct myss { - struct lws_sspc_handle *ss; + struct lws_ss_handle *ss; void *opaque_data; /* ... application specific state ... */ lws_sorted_usec_list_t sul; @@ -36,12 +40,8 @@ typedef struct myss { static lws_ss_state_return_t myss_rx(void *userobj, const uint8_t *buf, size_t len, int flags) { -// myss_t *m = (myss_t *)userobj; - - //lwsl_user("%s: len %d, flags: %d\n", __func__, (int)len, flags); - //lwsl_hexdump_info(buf, len); - - return 0; + /* this example isn't interested in rx */ + return LWSSSSRET_OK; } static void @@ -49,17 +49,20 @@ txcb(struct lws_sorted_usec_list *sul) { myss_t *m = lws_container_of(sul, myss_t, sul); - if (m->count == 1000) { + /* + * We want to do 100 of these ws messages, and then exit, so we can run + * this as a pass / fail test. + */ + + if (m->count == 100) { interrupted = 1; - return; + bad = 0; + } else { + m->due = 1; + lws_ss_request_tx(m->ss); } - m->due = 1; - lws_sspc_request_tx(m->ss); - - lws_sul_schedule(lws_sspc_get_context(m->ss), 0, &m->sul, txcb, RATE_US); - - + lws_sul_schedule(lws_ss_get_context(m->ss), 0, &m->sul, txcb, RATE_US); } static lws_ss_state_return_t @@ -69,30 +72,23 @@ myss_tx(void *userobj, lws_ss_tx_ordinal_t ord, uint8_t *buf, size_t *len, myss_t *m = (myss_t *)userobj; if (!m->due) - return 0; + return LWSSSSRET_TX_DONT_SEND; m->due = 0; - if (lws_get_random(lws_sspc_get_context(m->ss), buf, PKT_SIZE) != PKT_SIZE) - return 1; + if (lws_get_random(lws_ss_get_context(m->ss), buf, PKT_SIZE) != PKT_SIZE) + return LWSSSSRET_TX_DONT_SEND; *len = PKT_SIZE; - *flags = 0; - if (!m->count) - *flags |= LWSSS_FLAG_SOM; - if (m->count == 999) { - *flags |= LWSSS_FLAG_EOM; - lwsl_user("%s: sent final packet\n", __func__); - bad = 0; - } + *flags = LWSSS_FLAG_SOM | LWSSS_FLAG_EOM; m->count++; - lws_sul_schedule(lws_sspc_get_context(m->ss), 0, &m->sul, txcb, RATE_US); + lws_sul_schedule(lws_ss_get_context(m->ss), 0, &m->sul, txcb, RATE_US); - // lwsl_user("%s: sending pkt %d\n", __func__, m->count); + lwsl_user("%s: sending pkt %d\n", __func__, m->count); - return 0; + return LWSSSSRET_OK; } static lws_ss_state_return_t @@ -100,14 +96,15 @@ myss_state(void *userobj, void *sh, lws_ss_constate_t state, lws_ss_tx_ordinal_t ack) { myss_t *m = (myss_t *)userobj; - struct lws_context *context = lws_sspc_get_context(m->ss); + struct lws_context *context = lws_ss_get_context(m->ss); lwsl_user("%s: %s, ord 0x%x\n", __func__, lws_ss_state_name((int)state), (unsigned int)ack); switch (state) { case LWSSSCS_CREATING: - break; + return lws_ss_client_connect(m->ss); + case LWSSSCS_CONNECTED: lws_sul_schedule(context, 0, &m->sul, txcb, RATE_US); break; @@ -131,12 +128,21 @@ sigint_handler(int sig) interrupted = 1; } +static const lws_ss_info_t ssi = { + .handle_offset = offsetof(myss_t, ss), + .opaque_user_data_offset = offsetof(myss_t, opaque_data), + .rx = myss_rx, + .tx = myss_tx, + .state = myss_state, + .user_alloc = sizeof(myss_t), + .streamtype = "spam" +}; + int main(int argc, const char **argv) { int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE; struct lws_context_creation_info info; struct lws_context *context; - lws_ss_info_t ssi; const char *p; signal(SIGINT, sigint_handler); @@ -149,37 +155,36 @@ int main(int argc, const char **argv) memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ - info.options = //LWS_SERVER_OPTION_EXPLICIT_VHOSTS | - LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; info.fd_limit_per_thread = 1 + 6 + 1; info.port = CONTEXT_PORT_NO_LISTEN; info.protocols = lws_sspc_protocols; -#if defined(LWS_WITH_DETAILED_LATENCY) - info.detailed_latency_cb = lws_det_lat_plot_cb; - info.detailed_latency_filepath = "/tmp/lws-latency-ssclient"; -#endif + { + const char *p; + + /* connect to ssproxy via UDS by default, else via + * tcp connection to this port */ + if ((p = lws_cmdline_option(argc, argv, "-p"))) + info.ss_proxy_port = (uint16_t)atoi(p); + + /* UDS "proxy.ss.lws" in abstract namespace, else this socket + * path; when -p given this can specify the network interface + * to bind to */ + if ((p = lws_cmdline_option(argc, argv, "-i"))) + info.ss_proxy_bind = p; + + /* if -p given, -a specifies the proxy address to connect to */ + if ((p = lws_cmdline_option(argc, argv, "-a"))) + info.ss_proxy_address = p; + } context = lws_create_context(&info); if (!context) { lwsl_err("lws init failed\n"); - return 1; + goto bail1; } - /* - * We're requesting a secure stream via proxy... where and how this - * connects are details managed by the proxy policy - */ - - memset(&ssi, 0, sizeof ssi); - ssi.handle_offset = offsetof(myss_t, ss); - ssi.opaque_user_data_offset = offsetof(myss_t, opaque_data); - ssi.rx = myss_rx; - ssi.tx = myss_tx; - ssi.state = myss_state; - ssi.user_alloc = sizeof(myss_t); - ssi.streamtype = "spam"; - - if (lws_sspc_create(context, 0, &ssi, NULL, NULL, NULL, NULL)) { + if (lws_ss_create(context, 0, &ssi, NULL, NULL, NULL, NULL)) { lwsl_err("%s: create secure stream failed\n", __func__); goto bail; } @@ -191,6 +196,8 @@ int main(int argc, const char **argv) bail: lws_context_destroy(context); + +bail1: lwsl_user("Completed: %s\n", bad ? "failed" : "OK"); return bad;