mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-30 00:00:16 +01:00
ss: state violations need to report lifecycle tags
The state tracking and violation detection is very powerful at enforcing only legal transitions, but if it's busy, we don't get to see which stream had to problem. Add a pointer to the handle lc tag, do that rather than just pass the handle so we can deal with ss and sspc handles cleanly.
This commit is contained in:
parent
d92a099374
commit
14c5b7ebaf
5 changed files with 42 additions and 37 deletions
|
@ -473,7 +473,8 @@ lws_sspc_event_helper(lws_sspc_handle_t *h, lws_ss_constate_t cs,
|
|||
lws_ss_tx_ordinal_t flags);
|
||||
|
||||
int
|
||||
lws_ss_check_next_state(uint8_t *prevstate, lws_ss_constate_t cs);
|
||||
lws_ss_check_next_state(lws_lifecycle_t *lc, uint8_t *prevstate,
|
||||
lws_ss_constate_t cs);
|
||||
|
||||
void
|
||||
lws_proxy_clean_conn_ss(struct lws *wsi);
|
||||
|
|
|
@ -26,7 +26,7 @@ lws_sspc_event_helper(lws_sspc_handle_t *h, lws_ss_constate_t cs,
|
|||
if (!h)
|
||||
return LWSSSSRET_OK;
|
||||
|
||||
if (lws_ss_check_next_state(&h->prev_ss_state, cs))
|
||||
if (lws_ss_check_next_state(&h->lc, &h->prev_ss_state, cs))
|
||||
return LWSSSSRET_DESTROY_ME;
|
||||
|
||||
if (!h->ssi.state)
|
||||
|
|
|
@ -484,7 +484,8 @@ callback_ss_proxy(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
break;
|
||||
|
||||
case LWS_CALLBACK_RAW_WRITEABLE:
|
||||
// lwsl_notice("LWS_CALLBACK_RAW_PROXY_SRV_WRITEABLE\n");
|
||||
lwsl_debug("%s: %s: LWS_CALLBACK_RAW_WRITEABLE, state 0x%x\n",
|
||||
__func__, lws_wsi_tag(wsi), lwsi_state(wsi));
|
||||
|
||||
/*
|
||||
* We can transmit something back to the client from the dsh
|
||||
|
|
|
@ -408,35 +408,30 @@ lws_ss_deserialize_parse(struct lws_ss_serialization_parser *par,
|
|||
case LWSSS_SER_TXPRE_ONWARD_CONNECT:
|
||||
if (client)
|
||||
goto hangup;
|
||||
|
||||
if (*state != LPCSPROX_OPERATIONAL)
|
||||
goto hangup;
|
||||
|
||||
par->ps = RPAR_TYPE;
|
||||
lwsl_notice("%s: LWSSS_SER_TXPRE_ONWARD_CONNECT\n", __func__);
|
||||
lwsl_notice("%s: ONWARD_CONNECT\n", __func__);
|
||||
|
||||
if (proxy_pss_to_ss_h(pss) &&
|
||||
!proxy_pss_to_ss_h(pss)->wsi)
|
||||
/*
|
||||
* We're going to try to do the onward
|
||||
* connect, but that could end in any
|
||||
* of the ways like DESTROY_ME etc
|
||||
*/
|
||||
switch (_lws_ss_client_connect(
|
||||
proxy_pss_to_ss_h(pss), 0, parconn)) {
|
||||
case LWSSSSRET_OK:
|
||||
/* well, connect is ongoing */
|
||||
break;
|
||||
case LWSSSSRET_TX_DONT_SEND:
|
||||
/* it has failed already... */
|
||||
break;
|
||||
case LWSSSSRET_DISCONNECT_ME:
|
||||
// if (lws_ss_backoff(h))
|
||||
// /* has been destroyed */
|
||||
// return 1;
|
||||
break;
|
||||
case LWSSSSRET_DESTROY_ME:
|
||||
goto hangup;
|
||||
}
|
||||
/*
|
||||
* Shrug it off if we are already connecting or
|
||||
* connected
|
||||
*/
|
||||
|
||||
if (!proxy_pss_to_ss_h(pss) ||
|
||||
proxy_pss_to_ss_h(pss)->wsi)
|
||||
break;
|
||||
|
||||
/*
|
||||
* We're going to try to do the onward connect
|
||||
*/
|
||||
|
||||
if (_lws_ss_client_connect(proxy_pss_to_ss_h(pss),
|
||||
0, parconn) ==
|
||||
LWSSSSRET_DESTROY_ME)
|
||||
goto hangup;
|
||||
break;
|
||||
|
||||
case LWSSS_SER_TXPRE_STREAMTYPE:
|
||||
|
@ -1240,7 +1235,8 @@ payload_ff:
|
|||
|
||||
h->creating_cb_done = 1;
|
||||
|
||||
if (lws_ss_check_next_state(&h->prev_ss_state, LWSSSCS_CREATING))
|
||||
if (lws_ss_check_next_state(&h->lc, &h->prev_ss_state,
|
||||
LWSSSCS_CREATING))
|
||||
return LWSSSSRET_DESTROY_ME;
|
||||
|
||||
h->prev_ss_state = (uint8_t)LWSSSCS_CREATING;
|
||||
|
@ -1396,7 +1392,8 @@ payload_ff:
|
|||
if (cs == LWSSSCS_DISCONNECTED)
|
||||
h->ss_dangling_connected = 0;
|
||||
|
||||
if (lws_ss_check_next_state(&h->prev_ss_state, cs))
|
||||
if (lws_ss_check_next_state(&h->lc,
|
||||
&h->prev_ss_state, cs))
|
||||
return LWSSSSRET_DESTROY_ME;
|
||||
|
||||
if (cs < LWSSSCS_USER_BASE)
|
||||
|
|
|
@ -172,7 +172,8 @@ static const uint32_t ss_state_txn_validity[] = {
|
|||
};
|
||||
|
||||
int
|
||||
lws_ss_check_next_state(uint8_t *prevstate, lws_ss_constate_t cs)
|
||||
lws_ss_check_next_state(lws_lifecycle_t *lc, uint8_t *prevstate,
|
||||
lws_ss_constate_t cs)
|
||||
{
|
||||
if (cs >= LWSSSCS_USER_BASE)
|
||||
/*
|
||||
|
@ -183,29 +184,34 @@ lws_ss_check_next_state(uint8_t *prevstate, lws_ss_constate_t cs)
|
|||
|
||||
if (cs >= LWS_ARRAY_SIZE(ss_state_txn_validity)) {
|
||||
/* we don't recognize this state as usable */
|
||||
lwsl_err("%s: bad new state %u\n", __func__, cs);
|
||||
lwsl_err("%s: %s: bad new state %u\n", __func__, lc->gutag, cs);
|
||||
assert(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (*prevstate >= LWS_ARRAY_SIZE(ss_state_txn_validity)) {
|
||||
/* existing state is broken */
|
||||
lwsl_err("%s: bad existing state %u\n", __func__,
|
||||
(unsigned int)*prevstate);
|
||||
lwsl_err("%s: %s: bad existing state %u\n", __func__,
|
||||
lc->gutag, (unsigned int)*prevstate);
|
||||
assert(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ss_state_txn_validity[*prevstate] & (1u << cs)) {
|
||||
|
||||
lwsl_notice("%s: %s: %s -> %s\n", __func__, lc->gutag,
|
||||
lws_ss_state_name((int)*prevstate),
|
||||
lws_ss_state_name((int)cs));
|
||||
|
||||
/* this is explicitly allowed, update old state to new */
|
||||
*prevstate = (uint8_t)cs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
lwsl_err("%s: transition from %s -> %s is illegal\n", __func__,
|
||||
lws_ss_state_name((int)*prevstate),
|
||||
lws_ss_state_name((int)cs));
|
||||
lwsl_err("%s: %s: transition from %s -> %s is illegal\n", __func__,
|
||||
lc->gutag, lws_ss_state_name((int)*prevstate),
|
||||
lws_ss_state_name((int)cs));
|
||||
|
||||
assert(0);
|
||||
|
||||
|
@ -232,7 +238,7 @@ lws_ss_event_helper(lws_ss_handle_t *h, lws_ss_constate_t cs)
|
|||
if (!h)
|
||||
return LWSSSSRET_OK;
|
||||
|
||||
if (lws_ss_check_next_state(&h->prev_ss_state, cs))
|
||||
if (lws_ss_check_next_state(&h->lc, &h->prev_ss_state, cs))
|
||||
return LWSSSSRET_DESTROY_ME;
|
||||
|
||||
if (cs == LWSSSCS_CONNECTED)
|
||||
|
|
Loading…
Add table
Reference in a new issue