1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

ss: handle DESTROY_ME from inside ss creation

Normally when doing a Client Connection Error handling,
we can action any ss relationship straight away since
we are in a wsi callback without any ss-aware parents
in the call stack.

But in the specific case we're doing the initial onward
wsi connection part on behalf of a ss, in fact the call
stack does have earlier  parents holding references on
the related ss.

For example

  secstream_h1 (ss-h1.c:470)                          CCE
  lws_inform_client_conn_fail (close.c:319)           fails early
  lws_client_connect_2_dnsreq (connect2.c:349)
  lws_http_client_connect_via_info2 (connect.c:71)
  lws_header_table_attach (parsers.c:291)
  rops_client_bind_h1 (ops-h1.c:1001)
  lws_client_connect_via_info (connect.c:429)         start onward connect
  _lws_ss_client_connect (secure-streams.c:859)
  _lws_ss_request_tx (secure-streams.c:1577)
  lws_ss_request_tx (secure-streams.c:1515)           request tx
  ss_cpd_state (captive-portal-detect.c:50)
  lws_ss_event_helper (secure-streams.c:408)
  lws_ss_create (secure-streams.c:1256)                SS Create

Under these conditions, we can't action the DESTROY_ME that
is coming when the CCE exhausts the retries.

This patch adds a flag that is set during the SS's onward wsi
connection attempt and causes it to stash rather than action
the result code.

The result code is brought out from the stash when we return to
_lws_ss_client_connect level, and passed up in the SS flow until
it is actioned, cleanly aborting the ss create.
This commit is contained in:
Andy Green 2021-08-11 13:31:41 +01:00
parent e644bb4a6e
commit 406b79e440
3 changed files with 24 additions and 2 deletions

View file

@ -165,6 +165,8 @@ typedef struct lws_ss_handle {
lws_ss_constate_t connstate;/**< public connection state */
lws_ss_seq_state_t seqstate; /**< private connection state */
lws_ss_state_return_t pending_ret; /**< holds desired disposition
* for ss during CCE */
#if defined(LWS_WITH_SERVER)
int txn_resp;
@ -189,6 +191,9 @@ typedef struct lws_ss_handle {
uint8_t destroying:1;
uint8_t ss_dangling_connected:1;
uint8_t proxy_onward:1; /* opaque is conn */
uint8_t inside_connect:1; /* set if we are currently
* creating the onward
* connect */
} lws_ss_handle_t;
/* connection helper that doesn't need to hang around after connection starts */

View file

@ -461,13 +461,24 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user,
h->lc.gutag, in ? (const char *)in : "none");
/* already disconnected, no action for DISCONNECT_ME */
r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE);
if (r)
if (r) {
if (h->inside_connect) {
h->pending_ret = r;
break;
}
return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
}
h->wsi = NULL;
r = lws_ss_backoff(h);
if (r != LWSSSSRET_OK)
if (r != LWSSSSRET_OK) {
if (h->inside_connect) {
h->pending_ret = r;
break;
}
return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h);
}
break;
case LWS_CALLBACK_CLIENT_HTTP_REDIRECT:

View file

@ -855,7 +855,10 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw)
return r;
}
h->inside_connect = 1;
h->pending_ret = LWSSSSRET_OK;
wsi = lws_client_connect_via_info(&i);
h->inside_connect = 0;
lws_free(path);
if (!wsi) {
/*
@ -863,6 +866,9 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry, void *conn_if_sspc_onw)
* having to go around the event loop
*/
if (h->pending_ret)
return h->pending_ret;
if (h->prev_ss_state != LWSSSCS_UNREACHABLE &&
h->prev_ss_state != LWSSSCS_ALL_RETRIES_FAILED) {
/*