Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / assets / arch-riscv64-virt.svg
Author[]Andy Green <andy@warmcat.com> 2026-09-09 08:28 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-09-09 08:28 UTC
Tree5f9d6e7aec17be8585339137ac99f6f010920d9c   Raw Patch
 
server: recognize being re-exec'd as an lws_stub child
server: recognize being re-exec'd as an lws_stub child

lws plugins that need privileged help (eg, lws-cert-dist-client) spawn it by
re-exec'ing their host process with --lws-stub=<name>.  Both the plugin and
lwsws_get_config_vhosts() detect that via lws_cmdline_option_cx(), which
needs the context to have been given argc / argv.

sai-server never passed those in, so a stub child would have come up as a
complete second sai-server: parsing the real vhosts, contending for the
listen port and the websrv SS listener, opening the databases, dropping to
the configured uid, and never reaching the plugin's stub branch at all.

Hand argc / argv to lws via lws_cmdline_option_handle_builtin(), and when
that reports we are a stub child, follow lwsws: keep our privileges
(VH_SKIP_PRIV_DROP), force global TLS init, and bring up none of our own
protocols or the SS policy, so only the plugin protocols are instantiated
on the stub-dummy vhost that lwsws_get_config_vhosts() creates for stubs.

No behaviour change when started normally.  This is the sai side of using
lws-cert-dist-client to receive cert updates without a restart; the plugin
still needs to apply the received cert to the live vhost in-process.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
diff --git a/src/server/s-conf.c b/src/server/s-conf.c index c03a236..66f0df3 100644 --- a/src/server/s-conf.c +++ b/src/server/s-conf.c @@ -31,7 +31,7 @@ struct lws_context * sai_lws_context_from_json(const char *config_dir, struct lws_context_creation_info *info, const struct lws_protocols **pprotocols, - const char *jpol) + const char *jpol, int argc, const char **argv) { int cs_len = SAI_CONFIG_STRING_SIZE - 1; struct lws_context *context; @@ -54,6 +54,32 @@ sai_lws_context_from_json(const char *config_dir, LWS_SERVER_OPTION_VALIDATE_UTF8; info->pss_policies_json = jpol; + /* + * Let lws see our commandline: lws_cmdline_option_cx() needs it, and + * it is how lws_stub children (lws plugins that spawn a privileged + * helper by re-exec'ing us with --lws-stub=<name>) are recognized, + * both by the plugins themselves and by lwsws_get_config_vhosts() + */ + lws_cmdline_option_handle_builtin(argc, argv, info); + + if (info->lws_stub) { + /* + * We are a stub child, not a sai-server. We exist only to + * host the plugin protocol that spawned us, on the stub-dummy + * vhost lwsws_get_config_vhosts() creates instead of parsing + * our real vhosts. So none of our own protocols or the SS + * websrv listener should come up, and we must keep our + * privileges rather than dropping to the configured uid / gid, + * since the stub's whole purpose is to do the privileged work. + */ + lwsl_notice("%s: lws stub child '%s'\n", __func__, + info->lws_stub); + info->options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | + LWS_SERVER_OPTION_VH_SKIP_PRIV_DROP; + info->pss_policies_json = NULL; + pprotocols = NULL; + } + lwsl_notice("Using config dir: \"%s\"\n", config_dir); /* diff --git a/src/server/s-private.h b/src/server/s-private.h index 765d440..afe20be 100644 --- a/src/server/s-private.h +++ b/src/server/s-private.h @@ -277,7 +277,7 @@ extern struct lws_context * sai_lws_context_from_json(const char *config_dir, struct lws_context_creation_info *info, const struct lws_protocols **pprotocols, - const char *jpol); + const char *jpol, int argc, const char **argv); extern const struct lws_protocols protocol_ws, protocol_ws_power; int diff --git a/src/server/s-sai.c b/src/server/s-sai.c index 2668880..84e328d 100644 --- a/src/server/s-sai.c +++ b/src/server/s-sai.c @@ -87,7 +87,7 @@ int main(int argc, const char **argv) conf = p; context = sai_lws_context_from_json(conf, &info, pprotocols, - default_ss_policy); + default_ss_policy, argc, argv); if (!context) { lwsl_err("lws init failed\n"); return 1;
Page fetched 0s ago, creation time: 2ms (vhost etag hits: 0%, cache hits: 0%)