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 / src / server / s-notification.c
Author[]Andy Green <andy@warmcat.com> 2026-09-21 08:32 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-09-21 08:32 UTC
Tree3e1b33d76d4c40193586f136262d4ca145cd8bc3   Raw Patch
 
server: refuse the comms protocol on more than one vhost
server: refuse the comms protocol on more than one vhost

All the builder, power and task state that sai-web sees over the websrv
control link belongs to the vhd of the vhost the protocol initialized
on, and sais_list_builders() marks a builder online only if it is
connected on that same vhd.  So sai-server only supports one vhost
carrying com-warmcat-sai.

With the link on a path-based unix socket, a second vhost with the
protocol (eg, a unix-socket vhost for a front-end proxy that was given
the full pvo set) no longer fails at bind like it did on the abstract
name: lws unlinks the first vhd's socket and binds its own, so sai-web
ends up connected to a vhd with no builders on it.  The UI then shows
every builder offline and never sees task progress until a refresh
reads the db, while the builders are busy on the other vhd.

Make the second protocol init a loud failure naming both vhosts
instead, and say in the README that hooks go to the same vhost as the
builders.
diff --git a/README.md b/README.md index c0da922..65b2479 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,15 @@ the same on both sides: "sockpath": "/var/run/sai-websrv", ``` +Only one sai-server vhost may carry the com-warmcat-sai protocol: the +builders, the hook intake and this link all belong to that one vhost's +protocol instance. A second vhost with the protocol (eg, a unix-socket vhost +for a front-end proxy) would bind its own copy of the link on the same path +and sai-web would see a vhd with no builders on it; sai-server now refuses to +initialize the protocol on any vhost after the first. Hook notifications go +to the same vhost the builders use, eg, `http://127.0.0.1:4444/update-hook` +from a hook on the same host. + sai-server binds it during protocol init, before dropping privileges, and lws gives the socket sai-server's conf `uid`:`gid` with mode 0660 (the same way it treats any path-based listen socket). So only that user and members of that diff --git a/src/server/s-comms.c b/src/server/s-comms.c index 2b1fc36..b97dc2f 100644 --- a/src/server/s-comms.c +++ b/src/server/s-comms.c @@ -40,6 +40,16 @@ extern const lws_struct_map_t lsm_schema_sq3_map_event[]; extern const lws_ss_info_t ssi_server; +/* + * The vhost whose protocol instance serves the websrv control link. All the + * builder, power and task state sai-web sees over the link belongs to that + * one vhd, so sai-server supports exactly one vhost carrying the + * com-warmcat-sai protocol: a second one would bind its own link on the same + * path, unlinking the first, and sai-web would then be talking to a vhd that + * has no builders on it. + */ +static struct lws_vhost *sais_link_vhost; + typedef enum { SHMUT_NONE = -1, SHMUT_HOOK, @@ -190,6 +200,17 @@ s_callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, vhd->context = lws_get_context(wsi); vhd->vhost = lws_get_vhost(wsi); + if (sais_link_vhost) { + lwsl_err("%s: com-warmcat-sai is already active on" + " vhost %s; only one sai-server vhost may" + " carry it (builders, hooks and the sai-web" + " control link all belong to that vhd)." + " Remove the protocol from vhost %s\n", + __func__, lws_get_vhost_name(sais_link_vhost), + lws_get_vhost_name(vhd->vhost)); + return -1; + } + if (lws_pvo_get_str(in, "notification-key", &vhd->notification_key)) { lwsl_warn("%s: notification_key pvo required\n", __func__); @@ -394,6 +415,8 @@ s_callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, return -1; } + sais_link_vhost = vhd->vhost; + lws_sul_schedule(vhd->context, 0, &vhd->sul_central, sais_central_cb, 500 * LWS_US_PER_MS); @@ -403,6 +426,8 @@ s_callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, break; case LWS_CALLBACK_PROTOCOL_DESTROY: + if (vhd && vhd->vhost == sais_link_vhost) + sais_link_vhost = NULL; sais_server_destroy(vhd, &vhd->server); goto passthru;
Page fetched 0s ago, creation time: 3ms (vhost etag hits: 0%, cache hits: 0%)