diff --git a/include/libwebsockets/lws-secure-streams-client.h b/include/libwebsockets/lws-secure-streams-client.h index 042716ac8..7070ec2d7 100644 --- a/include/libwebsockets/lws-secure-streams-client.h +++ b/include/libwebsockets/lws-secure-streams-client.h @@ -119,7 +119,7 @@ lws_sspc_request_tx_len(struct lws_sspc_handle *h, unsigned long len); * Starts the connection process for the secure stream. Returns 0 if OK or * nonzero if we have already failed. */ -LWS_VISIBLE LWS_EXTERN int +LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t lws_sspc_client_connect(struct lws_sspc_handle *h); /** diff --git a/include/libwebsockets/lws-secure-streams.h b/include/libwebsockets/lws-secure-streams.h index 8d65691a8..93d279658 100644 --- a/include/libwebsockets/lws-secure-streams.h +++ b/include/libwebsockets/lws-secure-streams.h @@ -281,7 +281,7 @@ typedef enum { */ typedef enum lws_ss_state_return { - LWSSSSRET_TX_DONT_SEND = 1, /* (*tx) only */ + LWSSSSRET_TX_DONT_SEND = 1, /* (*tx) only, or failure */ LWSSSSRET_OK = 0, /* no error */ LWSSSSRET_DISCONNECT_ME = -1, /* caller should disconnect us */ @@ -451,10 +451,15 @@ lws_ss_request_tx_len(struct lws_ss_handle *pss, unsigned long len); * * \param h: secure streams handle * - * Starts the connection process for the secure stream. Returns 0 if OK or - * nonzero if we have already failed. + * Starts the connection process for the secure stream. + * + * Can return any of the lws_ss_state_return_t values depending on user + * state callback returns. + * + * LWSSSSRET_OK means the connection is ongoing. + * */ -LWS_VISIBLE LWS_EXTERN int +LWS_VISIBLE LWS_EXTERN lws_ss_state_return_t lws_ss_client_connect(struct lws_ss_handle *h); /** diff --git a/lib/secure-streams/private-lib-secure-streams.h b/lib/secure-streams/private-lib-secure-streams.h index 74f703750..29a1fe682 100644 --- a/lib/secure-streams/private-lib-secure-streams.h +++ b/lib/secure-streams/private-lib-secure-streams.h @@ -401,7 +401,7 @@ lws_ss_state_return_t lws_ss_backoff(lws_ss_handle_t *h); int -_lws_ss_handle_state_ret(lws_ss_state_return_t r, struct lws *wsi, +_lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(lws_ss_state_return_t r, struct lws *wsi, lws_ss_handle_t **ph); int @@ -432,7 +432,7 @@ int _lws_ss_set_metadata(lws_ss_metadata_t *omd, const char *name, const void *value, size_t len); -int +lws_ss_state_return_t _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry); struct lws_vhost * diff --git a/lib/secure-streams/protocols/ss-h1.c b/lib/secure-streams/protocols/ss-h1.c index 018efe71a..1ddfc0d1d 100644 --- a/lib/secure-streams/protocols/ss-h1.c +++ b/lib/secure-streams/protocols/ss-h1.c @@ -383,12 +383,12 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user, /* already disconnected, no action for DISCONNECT_ME */ r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE); if (r) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); h->wsi = NULL; r = lws_ss_backoff(h); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; case LWS_CALLBACK_CLIENT_HTTP_REDIRECT: @@ -422,14 +422,14 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user, !h->txn_ok && !wsi->a.context->being_destroyed) { r = lws_ss_backoff(h); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; } else h->seqstate = SSSEQ_IDLE; /* already disconnected, no action for DISCONNECT_ME */ r = lws_ss_event_helper(h, LWSSSCS_DISCONNECTED); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; @@ -454,7 +454,7 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user, r = _lws_ss_backoff(h, inter); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); return -1; /* end this stream */ } @@ -484,7 +484,7 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user, if (n) { r = lws_ss_event_helper(h, n); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); } } @@ -506,7 +506,7 @@ secstream_h1(struct lws *wsi, enum lws_callback_reasons reason, void *user, r = lws_ss_event_helper(h, LWSSSCS_CONNECTED); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); /* * Since it's an http transaction we initiated... this is @@ -655,7 +655,7 @@ malformed: !strcmp(h->policy->u.http.method, "POST"))) { r = lws_ss_event_helper(h, LWSSSCS_CONNECTED); if (r) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); } break; @@ -685,7 +685,7 @@ malformed: r = h->info.rx(ss_to_userobj(h), (const uint8_t *)in, len, f); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); return 0; /* don't passthru */ @@ -717,7 +717,7 @@ malformed: LWSSSCS_QOS_ACK_REMOTE : LWSSSCS_QOS_NACK_REMOTE); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); lws_cancel_service(lws_get_context(wsi)); /* abort poll wait */ break; @@ -794,7 +794,7 @@ malformed: if (r == LWSSSSRET_TX_DONT_SEND) return 0; if (r < 0) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); // lwsl_notice("%s: WRITEABLE: user tx says len %d fl 0x%x\n", // __func__, (int)buflen, (int)f); @@ -897,7 +897,7 @@ malformed: r = lws_ss_event_helper(h, LWSSSCS_SERVER_TXN); if (r) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); return 0; #endif diff --git a/lib/secure-streams/protocols/ss-h2.c b/lib/secure-streams/protocols/ss-h2.c index 465207ad5..721a74c60 100644 --- a/lib/secure-streams/protocols/ss-h2.c +++ b/lib/secure-streams/protocols/ss-h2.c @@ -75,7 +75,7 @@ secstream_h2(struct lws *wsi, enum lws_callback_reasons reason, void *user, h->txn_ok = 1; lws_cancel_service(lws_get_context(wsi)); /* abort poll wait */ if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; case LWS_CALLBACK_WSI_TX_CREDIT_GET: diff --git a/lib/secure-streams/protocols/ss-mqtt.c b/lib/secure-streams/protocols/ss-mqtt.c index a76a8c2e2..ba449d3a6 100644 --- a/lib/secure-streams/protocols/ss-mqtt.c +++ b/lib/secure-streams/protocols/ss-mqtt.c @@ -52,11 +52,11 @@ secstream_mqtt(struct lws *wsi, enum lws_callback_reasons reason, void *user, } if (r == LWSSSSRET_DESTROY_ME) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); r = lws_ss_backoff(h); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; @@ -75,13 +75,13 @@ secstream_mqtt(struct lws *wsi, enum lws_callback_reasons reason, void *user, } if (r) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); if (h->policy && !(h->policy->flags & LWSSSPOLF_OPPORTUNISTIC) && !h->txn_ok && !wsi->a.context->being_destroyed) { r = lws_ss_backoff(h); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); } break; @@ -96,7 +96,7 @@ secstream_mqtt(struct lws *wsi, enum lws_callback_reasons reason, void *user, lws_sul_cancel(&h->sul); r = lws_ss_event_helper(h, LWSSSCS_CONNECTED); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); if (h->policy->u.mqtt.topic) lws_callback_on_writable(wsi); break; @@ -119,7 +119,7 @@ secstream_mqtt(struct lws *wsi, enum lws_callback_reasons reason, void *user, r = h->info.rx(ss_to_userobj(h), (const uint8_t *)pmqpp->payload, len, f); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); return 0; /* don't passthru */ @@ -132,7 +132,7 @@ secstream_mqtt(struct lws *wsi, enum lws_callback_reasons reason, void *user, lws_sul_cancel(&h->sul_timeout); r = lws_ss_event_helper(h, LWSSSCS_QOS_ACK_REMOTE); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; case LWS_CALLBACK_MQTT_CLIENT_WRITEABLE: @@ -191,7 +191,7 @@ secstream_mqtt(struct lws *wsi, enum lws_callback_reasons reason, void *user, return 0; if (r < 0) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); memset(&mqpp, 0, sizeof(mqpp)); /* this is the string-substituted h->policy->u.mqtt.topic */ diff --git a/lib/secure-streams/protocols/ss-raw.c b/lib/secure-streams/protocols/ss-raw.c index 0fe95252e..043b71935 100644 --- a/lib/secure-streams/protocols/ss-raw.c +++ b/lib/secure-streams/protocols/ss-raw.c @@ -49,11 +49,11 @@ secstream_raw(struct lws *wsi, enum lws_callback_reasons reason, void *user, h, h->policy->streamtype, in ? (char *)in : "(null)"); r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE); if (r == LWSSSSRET_DESTROY_ME) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); h->wsi = NULL; r = lws_ss_backoff(h); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; case LWS_CALLBACK_RAW_CLOSE: @@ -76,13 +76,13 @@ secstream_raw(struct lws *wsi, enum lws_callback_reasons reason, void *user, !h->txn_ok && !wsi->a.context->being_destroyed) { r = lws_ss_backoff(h); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; } /* wsi is going down anyway */ r = lws_ss_event_helper(h, LWSSSCS_DISCONNECTED); if (r == LWSSSSRET_DESTROY_ME) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; case LWS_CALLBACK_RAW_CONNECTED: @@ -93,7 +93,7 @@ secstream_raw(struct lws *wsi, enum lws_callback_reasons reason, void *user, lws_sul_cancel(&h->sul); r = lws_ss_event_helper(h, LWSSSCS_CONNECTED); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); lws_validity_confirmed(wsi); break; @@ -109,7 +109,7 @@ secstream_raw(struct lws *wsi, enum lws_callback_reasons reason, void *user, r = h->info.rx(ss_to_userobj(h), (const uint8_t *)in, len, 0); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); return 0; /* don't passthru */ @@ -123,7 +123,7 @@ secstream_raw(struct lws *wsi, enum lws_callback_reasons reason, void *user, if (r == LWSSSSRET_TX_DONT_SEND) return 0; if (r < 0) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); /* * flags are ignored with raw, there are no protocol payload diff --git a/lib/secure-streams/protocols/ss-ws.c b/lib/secure-streams/protocols/ss-ws.c index f79fd4fdc..b62368afc 100644 --- a/lib/secure-streams/protocols/ss-ws.c +++ b/lib/secure-streams/protocols/ss-ws.c @@ -47,12 +47,12 @@ secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, break; r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE); if (r == LWSSSSRET_DESTROY_ME) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); h->wsi = NULL; r = lws_ss_backoff(h); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; case LWS_CALLBACK_CLOSED: /* server */ @@ -62,7 +62,7 @@ secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, lws_sul_cancel(&h->sul_timeout); r = lws_ss_event_helper(h, LWSSSCS_DISCONNECTED); if (r == LWSSSSRET_DESTROY_ME) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); if (h->wsi) lws_set_opaque_user_data(h->wsi, NULL); @@ -83,7 +83,7 @@ secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, !h->txn_ok && !wsi->a.context->being_destroyed) { r = lws_ss_backoff(h); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; } @@ -108,7 +108,7 @@ secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, lws_sul_cancel(&h->sul); r = lws_ss_event_helper(h, LWSSSCS_CONNECTED); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); break; case LWS_CALLBACK_RECEIVE: @@ -126,7 +126,7 @@ secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, r = h->info.rx(ss_to_userobj(h), (const uint8_t *)in, len, f); if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); return 0; /* don't passthru */ @@ -147,7 +147,7 @@ secstream_ws(struct lws *wsi, enum lws_callback_reasons reason, void *user, if (r == LWSSSSRET_TX_DONT_SEND) return 0; if (r != LWSSSSRET_OK) - return _lws_ss_handle_state_ret(r, wsi, &h); + return _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, wsi, &h); f1 = lws_write_ws_flags(h->policy->u.http.u.ws.binary ? LWS_WRITE_BINARY : LWS_WRITE_TEXT, diff --git a/lib/secure-streams/secure-streams-serialize.c b/lib/secure-streams/secure-streams-serialize.c index ebef76136..4440cdb45 100644 --- a/lib/secure-streams/secure-streams-serialize.c +++ b/lib/secure-streams/secure-streams-serialize.c @@ -407,12 +407,33 @@ lws_ss_deserialize_parse(struct lws_ss_serialization_parser *par, goto hangup; if (*state != LPCSPROX_OPERATIONAL) goto hangup; + par->ps = RPAR_TYPE; lwsl_notice("%s: LWSSS_SER_TXPRE_ONWARD_CONNECT\n", __func__); + if (proxy_pss_to_ss_h(pss) && !proxy_pss_to_ss_h(pss)->wsi) - _lws_ss_client_connect( - proxy_pss_to_ss_h(pss), 0); + /* + * 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)) { + 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; + } break; case LWSSS_SER_TXPRE_STREAMTYPE: diff --git a/lib/secure-streams/secure-streams.c b/lib/secure-streams/secure-streams.c index 96f70cac2..313de3366 100644 --- a/lib/secure-streams/secure-streams.c +++ b/lib/secure-streams/secure-streams.c @@ -112,7 +112,7 @@ lws_ss_event_helper(lws_ss_handle_t *h, lws_ss_constate_t cs) } int -_lws_ss_handle_state_ret(lws_ss_state_return_t r, struct lws *wsi, +_lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(lws_ss_state_return_t r, struct lws *wsi, lws_ss_handle_t **ph) { if (r == LWSSSSRET_DESTROY_ME) { @@ -315,7 +315,7 @@ lws_ss_smd_tx_cb(lws_sorted_usec_list_t *sul) #endif -int +lws_ss_state_return_t _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry) { const char *prot, *_prot, *ipath, *_ipath, *ads, *_ads; @@ -331,7 +331,7 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry) if (!h->policy) { lwsl_err("%s: ss with no policy\n", __func__); - return -1; + return LWSSSSRET_OK; } /* @@ -348,7 +348,7 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry) if (h->policy == &pol_smd) { if (h->u.smd.smd_peer) - return 0; + return LWSSSSRET_OK; // lwsl_notice("%s: received connect for _lws_smd, registering for class mask 0x%x\n", // __func__, h->info.manual_initial_tx_credit); @@ -359,14 +359,14 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry) h->info.manual_initial_tx_credit, lws_smd_ss_cb); if (!h->u.smd.smd_peer) - return -1; + return LWSSSSRET_TX_DONT_SEND; if (lws_ss_event_helper(h, LWSSSCS_CONNECTING)) - return -1; + return LWSSSSRET_TX_DONT_SEND; // lwsl_err("%s: registered SS SMD\n", __func__); if (lws_ss_event_helper(h, LWSSSCS_CONNECTED)) - return -1; - return 0; + return LWSSSSRET_TX_DONT_SEND; + return LWSSSSRET_OK; } #endif @@ -382,7 +382,7 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry) &used_in, &used_out) != LSTRX_DONE) { lwsl_err("%s: address strexp failed\n", __func__); - return -1; + return LWSSSSRET_TX_DONT_SEND; } /* @@ -459,7 +459,7 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry) if (!ssp) { lwsl_err("%s: unsupported protocol\n", __func__); - return -1; + return LWSSSSRET_TX_DONT_SEND; } i.alpn = ssp->alpn; @@ -490,25 +490,26 @@ _lws_ss_client_connect(lws_ss_handle_t *h, int is_retry) return r; if (!lws_client_connect_via_info(&i)) { + /* + * We already found that we could not connect, without even + * having to go around the event loop + */ + r = lws_ss_event_helper(h, LWSSSCS_UNREACHABLE); - if (r == LWSSSSRET_DESTROY_ME) - return !!_lws_ss_handle_state_ret(r, NULL, &h); if (r) return r; r = lws_ss_backoff(h); - if (r == LWSSSSRET_DESTROY_ME) - return !!_lws_ss_handle_state_ret(r, NULL, &h); if (r) return r; - return 1; + return LWSSSSRET_TX_DONT_SEND; } - return 0; + return LWSSSSRET_OK; } -int +lws_ss_state_return_t lws_ss_client_connect(lws_ss_handle_t *h) { return _lws_ss_client_connect(h, 0); @@ -529,6 +530,7 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, { struct lws_context_per_thread *pt = &context->pt[tsi]; const lws_ss_policy_t *pol; + lws_ss_state_return_t r; lws_ss_metadata_t *smd; lws_ss_handle_t *h; size_t size; @@ -795,7 +797,10 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, } #endif - if (lws_ss_event_helper(h, LWSSSCS_CREATING)) { + r = lws_ss_event_helper(h, LWSSSCS_CREATING); + lwsl_info("%s: CREATING returned status %d\n", __func__, (int)r); + if (r == LWSSSSRET_DESTROY_ME) { + late_bail: lws_pt_lock(pt, __func__); lws_dll2_remove(&h->list); @@ -813,10 +818,18 @@ late_bail: ) #endif )) - if (_lws_ss_client_connect(h, 0)) { + switch (_lws_ss_client_connect(h, 0)) { + case LWSSSSRET_OK: + break; + case LWSSSSRET_TX_DONT_SEND: + case LWSSSSRET_DISCONNECT_ME: if (lws_ss_backoff(h)) /* has been destroyed */ return 1; + break; + case LWSSSSRET_DESTROY_ME: + lws_ss_destroy(&h); + return 1; } return 0; @@ -1116,7 +1129,7 @@ lws_ss_to_cb(lws_sorted_usec_list_t *sul) if (h->wsi) lws_set_timeout(h->wsi, 1, LWS_TO_KILL_ASYNC); - _lws_ss_handle_state_ret(r, h->wsi, &h); + _lws_ss_handle_state_ret_CAN_DESTROY_HANDLE(r, h->wsi, &h); } void diff --git a/minimal-examples/secure-streams/minimal-secure-streams-alexa/alexa.c b/minimal-examples/secure-streams/minimal-secure-streams-alexa/alexa.c index a44da084e..41a46cf13 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-alexa/alexa.c +++ b/minimal-examples/secure-streams/minimal-secure-streams-alexa/alexa.c @@ -537,15 +537,15 @@ ss_avs_metadata_state(void *userobj, void *sh, switch (state) { case LWSSSCS_CREATING: - lws_ss_client_connect(m->ss); - break; + return lws_ss_client_connect(m->ss); + case LWSSSCS_CONNECTING: m->pos = 0; break; case LWSSSCS_CONNECTED: lwsl_info("%s: CONNECTED\n", __func__); - lws_ss_request_tx(m->ss); - break; + return lws_ss_request_tx(m->ss); + case LWSSSCS_DISCONNECTED: lws_sul_cancel(&m->sul); //if (m->mh) { diff --git a/minimal-examples/secure-streams/minimal-secure-streams-avs/avs.c b/minimal-examples/secure-streams/minimal-secure-streams-avs/avs.c index 089260b08..c5a7fe4c8 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-avs/avs.c +++ b/minimal-examples/secure-streams/minimal-secure-streams-avs/avs.c @@ -233,14 +233,14 @@ ss_avs_metadata_state(void *userobj, void *sh, switch (state) { case LWSSSCS_CREATING: lwsl_user("%s: CREATING\n", __func__); - lws_ss_client_connect(m->ss); m->pos = 0; - break; + return lws_ss_client_connect(m->ss); + case LWSSSCS_CONNECTING: break; case LWSSSCS_CONNECTED: - lws_ss_request_tx(m->ss); - break; + return lws_ss_request_tx(m->ss); + case LWSSSCS_ALL_RETRIES_FAILED: /* for this demo app, we want to exit on fail to connect */ case LWSSSCS_DISCONNECTED: diff --git a/minimal-examples/secure-streams/minimal-secure-streams-metadata/minimal-secure-streams.c b/minimal-examples/secure-streams/minimal-secure-streams-metadata/minimal-secure-streams.c index e8b30f4d1..b3eddeafd 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-metadata/minimal-secure-streams.c +++ b/minimal-examples/secure-streams/minimal-secure-streams-metadata/minimal-secure-streams.c @@ -227,8 +227,8 @@ myss_state(void *userobj, void *sh, lws_ss_constate_t state, lwsl_notice("%s: CREATING: setting servername metadata to %s\n", __func__, server_name_or_url); lws_ss_set_metadata(m->ss, "servername", server_name_or_url, strlen(server_name_or_url)); - lws_ss_client_connect(m->ss); - break; + return lws_ss_client_connect(m->ss); + case LWSSSCS_ALL_RETRIES_FAILED: /* if we're out of retries, we want to close the app and FAIL */ interrupted = 1; diff --git a/minimal-examples/secure-streams/minimal-secure-streams-staticpolicy/minimal-secure-streams.c b/minimal-examples/secure-streams/minimal-secure-streams-staticpolicy/minimal-secure-streams.c index efdbf7749..d276c2164 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-staticpolicy/minimal-secure-streams.c +++ b/minimal-examples/secure-streams/minimal-secure-streams-staticpolicy/minimal-secure-streams.c @@ -100,8 +100,8 @@ myss_state(void *userobj, void *sh, lws_ss_constate_t state, case LWSSSCS_CREATING: lws_ss_set_metadata(m->ss, "uptag", "myuptag123", 10); lws_ss_set_metadata(m->ss, "ctype", "myctype", 7); - lws_ss_client_connect(m->ss); - break; + return lws_ss_client_connect(m->ss); + case LWSSSCS_ALL_RETRIES_FAILED: /* if we're out of retries, we want to close the app and FAIL */ interrupted = 1; diff --git a/minimal-examples/secure-streams/minimal-secure-streams-testsfail/minimal-secure-streams-testsfail.c b/minimal-examples/secure-streams/minimal-secure-streams-testsfail/minimal-secure-streams-testsfail.c index 981851852..944cda9f9 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams-testsfail/minimal-secure-streams-testsfail.c +++ b/minimal-examples/secure-streams/minimal-secure-streams-testsfail/minimal-secure-streams-testsfail.c @@ -594,7 +594,7 @@ myss_state(void *userobj, void *sh, lws_ss_constate_t state, * We have definitively failed on an unexpected state received */ - lwsl_user("%s: failing on unexpected state %s\n", + lwsl_warn("%s: failing on unexpected state %s\n", __func__, lws_ss_state_name((int)state)); fail: @@ -634,8 +634,8 @@ fail: (unsigned int)curr_test->eom_pass); lws_ss_set_metadata(m->ss, "amount", buf, sl); } - lws_ss_client_connect(m->ss); - break; + return lws_ss_client_connect(m->ss); + case LWSSSCS_DESTROYING: if (!m->result_reported) { lwsl_user("%s: failing on unexpected destruction\n", @@ -663,8 +663,10 @@ tests_start_next(lws_sorted_usec_list_t *sul) /* destroy the old one */ - if (h) + if (h) { + lwsl_notice("%s: destroying previous stream\n", __func__); lws_ss_destroy(&h); + } if ((unsigned int)tests >= LWS_ARRAY_SIZE(tests_seq)) { lwsl_notice("Completed all tests\n"); @@ -690,6 +692,7 @@ tests_start_next(lws_sorted_usec_list_t *sul) if (lws_ss_create(context, 0, &ssi, ts, &h, NULL, NULL)) { lwsl_err("%s: failed to create secure stream\n", __func__); + tests_fail++; interrupted = 1; return; } @@ -745,7 +748,7 @@ main(int argc, const char **argv) lwsl_user("LWS secure streams error path tests [-d]\n"); - info.fd_limit_per_thread = 1 + 6 + 1; + info.fd_limit_per_thread = 1 + 16 + 1; info.port = CONTEXT_PORT_NO_LISTEN; #if defined(LWS_SS_USE_SSPC) info.protocols = lws_sspc_protocols; @@ -790,8 +793,7 @@ main(int argc, const char **argv) /* the event loop */ - do { - } while(lws_service(context, 0) >= 0 && !interrupted); + do { } while(lws_service(context, 0) >= 0 && !interrupted); lws_context_destroy(context); diff --git a/minimal-examples/secure-streams/minimal-secure-streams/minimal-secure-streams.c b/minimal-examples/secure-streams/minimal-secure-streams/minimal-secure-streams.c index 5ebcc9940..cbf7bf3b0 100644 --- a/minimal-examples/secure-streams/minimal-secure-streams/minimal-secure-streams.c +++ b/minimal-examples/secure-streams/minimal-secure-streams/minimal-secure-streams.c @@ -279,8 +279,8 @@ myss_state(void *userobj, void *sh, lws_ss_constate_t state, lws_ss_start_timeout(m->ss, timeout_ms); lws_ss_set_metadata(m->ss, "uptag", "myuptag123", 10); lws_ss_set_metadata(m->ss, "ctype", "myctype", 7); - lws_ss_client_connect(m->ss); - break; + return lws_ss_client_connect(m->ss); + case LWSSSCS_ALL_RETRIES_FAILED: /* if we're out of retries, we want to close the app and FAIL */ interrupted = 1;