diff --git a/lib/secure-streams/secure-streams.c b/lib/secure-streams/secure-streams.c index 53c36a88d..7cfb993a1 100644 --- a/lib/secure-streams/secure-streams.c +++ b/lib/secure-streams/secure-streams.c @@ -1132,7 +1132,7 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, (lws_smd_class_t)ssi->manual_initial_tx_credit, lws_smd_ss_cb); if (!h->u.smd.smd_peer) - goto late_bail; + goto fail_creation; lwsl_cx_info(context, "registered SS SMD"); } #endif @@ -1159,7 +1159,7 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, if (!vho) { lwsl_err("%s: no vhost %s\n", __func__, &h->policy->endpoint[1]); - goto late_bail; + goto fail_creation; } goto extant; @@ -1183,7 +1183,7 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, if (!ss_pcols[h->policy->protocol]) { lwsl_err("%s: unsupp protocol", __func__); - goto late_bail; + goto fail_creation; } *ppp++ = ss_pcols[h->policy->protocol]->protocol; @@ -1217,7 +1217,7 @@ lws_ss_create(struct lws_context *context, int tsi, const lws_ss_info_t *ssi, vho = lws_create_vhost(context, &i); if (!vho) { lwsl_cx_err(context, "failed to create vh"); - goto late_bail; + goto fail_creation; } extant: @@ -1231,7 +1231,7 @@ extant: r = lws_ss_event_helper(h, LWSSSCS_CREATING); lwsl_cx_info(context, "CREATING returned status %d", (int)r); if (r == LWSSSSRET_DESTROY_ME) - goto late_bail; + goto fail_creation; lwsl_cx_notice(context, "created server %s", h->policy->streamtype); @@ -1254,31 +1254,14 @@ extant: if (!lws_ss_policy_ref_trust_store(context, h->policy, 1 /* do the ref */)) { lwsl_err("%s: unable to get vhost / trust store\n", __func__); - goto late_bail; + goto fail_creation; } #endif r = lws_ss_event_helper(h, LWSSSCS_CREATING); lwsl_ss_info(h, "CREATING returned status %d", (int)r); - if (r == LWSSSSRET_DESTROY_ME) { - -#if defined(LWS_WITH_SERVER) || defined(LWS_WITH_SYS_SMD) -late_bail: -#endif - - if (ppss) - *ppss = NULL; - - lws_pt_lock(pt, __func__); - lws_dll2_remove(&h->list); - lws_pt_unlock(pt); - - lws_fi_destroy(&h->fic); - __lws_lc_untag(context, &h->lc); - lws_free(h); - - return 1; - } + if (r == LWSSSSRET_DESTROY_ME) + goto fail_creation; #if defined(LWS_WITH_SYS_SMD) if (!(ssi->flags & LWSSSINFLAGS_PROXIED) && @@ -1307,17 +1290,23 @@ late_bail: break; case LWSSSSRET_TX_DONT_SEND: case LWSSSSRET_DISCONNECT_ME: - if (lws_ss_backoff(h) == LWSSSSRET_DESTROY_ME) { - lws_ss_destroy(&h); - return 1; - } + if (lws_ss_backoff(h) == LWSSSSRET_DESTROY_ME) + goto fail_creation; break; case LWSSSSRET_DESTROY_ME: - lws_ss_destroy(&h); - return 1; + goto fail_creation; } return 0; + +fail_creation: + + if (ppss) + *ppss = NULL; + + lws_ss_destroy(&h); + + return 1; } void * @@ -1404,10 +1393,19 @@ lws_ss_destroy(lws_ss_handle_t **ppss) v = lws_get_vhost_by_name(h->context, h->policy->streamtype); #endif - if (h->ss_dangling_connected) - (void)lws_ss_event_helper(h, LWSSSCS_DISCONNECTED); + /* + * Since we also come here to unpick create, it's possible we failed + * the creation before issuing any states, even CREATING. We should + * only issue cleanup states on destroy if we previously got as far as + * issuing CREATING. + */ - (void)lws_ss_event_helper(h, LWSSSCS_DESTROYING); + if (h->prev_ss_state) { + if (h->ss_dangling_connected) + (void)lws_ss_event_helper(h, LWSSSCS_DISCONNECTED); + + (void)lws_ss_event_helper(h, LWSSSCS_DESTROYING); + } lws_pt_unlock(pt); @@ -1418,6 +1416,7 @@ lws_ss_destroy(lws_ss_handle_t **ppss) lwsl_info("%s: pmd %p\n", __func__, pmd); if (pmd->value_on_lws_heap) lws_free_set_NULL(pmd->value__may_own_heap); + pmd = pmd->next; } @@ -1425,14 +1424,18 @@ lws_ss_destroy(lws_ss_handle_t **ppss) { lws_ss_metadata_t *imd; + pmd = h->instant_metadata; + while (pmd) { imd = pmd; pmd = pmd->next; + lwsl_info("%s: instant md %p\n", __func__, imd); lws_free(imd); } h->instant_metadata = NULL; + if (h->imd_ac) lwsac_free(&h->imd_ac); } @@ -1485,7 +1488,7 @@ lws_ss_destroy(lws_ss_handle_t **ppss) __lws_lc_untag(h->context, &h->lc); - lws_explicit_bzero((void *)h, sizeof(*h)); + lws_explicit_bzero((void *)h, sizeof(*h) + h->info.user_alloc); lws_free_set_NULL(h); }