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 / jig / j-private.h
Author[]Andy Green <andy@warmcat.com> 2026-09-21 06:19 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-09-21 07:08 UTC
Treed616be5b759e8f4403803ca7151bbd4a76420f40   Raw Patch
 
server: don't touch ws close payload at CLOSED unless the conn established
server: don't touch ws close payload at CLOSED unless the conn established

LWS_CALLBACK_CLOSED can arrive at the comms protocol for a wsi that was
never established as a builder or power conn, eg on a vhost where the
protocol init failed, or a conn dropped at the ESTABLISHED URL checks,
or one caught by a context destroy in a non-ws condition.  Asking about
the peer's close payload dereferences wsi->ws, which only exists on a
conn that completed a ws upgrade, crashing the server at shutdown with

  lws_get_close_length (ops-ws.c:1017)
  s_callback_ws
  __lws_close_free_wsi (close.c:1030)
  lws_context_destroy (context.c:2467)

Bail out of the CLOSED handling unless the pss is on a vhd conn list,
ie, it actually established on /builder or /power and so has teardown
state and a ws condition.  This also subsumes the !vhd check that
followed it: a pss on a vhd conn list necessarily has a vhd.
diff --git a/src/server/s-comms.c b/src/server/s-comms.c index 29198ba..2b1fc36 100644 --- a/src/server/s-comms.c +++ b/src/server/s-comms.c @@ -655,6 +655,18 @@ s_callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, return -1; case LWS_CALLBACK_CLOSED: + /* + * This can also arrive for wsis that were never established + * as a builder or power conn, eg on a vhost where protocol + * init failed, or one dropped at the ESTABLISHED URL checks. + * Those were never added to a vhd conn list and have no + * teardown state, and may not even be in a ws condition: + * asking about the peer's close payload dereferences wsi->ws, + * which only exists on a conn that got that far. + */ + if (!pss || lws_dll2_is_detached(&pss->same)) + break; + lwsac_free(&pss->query_ac); /* a conn closed mid-message must not leak its reassembly */ @@ -672,14 +684,6 @@ s_callback_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, /* remove pss from vhd->builders (active connection list) */ lws_dll2_remove(&pss->same); - /* - * On a vhost where protocol init failed there is no vhd and - * the conn was never established as a builder: there is - * nothing vhd-relative to tear down. - */ - if (!vhd) - break; - sais_builder_disconnected(vhd, wsi); sais_resource_wellknown_remove_pss(&pss->vhd->server, pss);
Page fetched 0s ago, creation time: 7ms (vhost etag hits: 0%, cache hits: 0%)