void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data)
{
    unsigned long hash;
    OPENSSL_LH_NODE *nn, **rn;
    void *ret;
    lh->error = 0;
    rn = getrn(lh, data, &hash);
    if (*rn == NULL) {
        lh->num_no_delete++;
        return NULL;
    } else {
        nn = *rn;
        *rn = nn->next;
        ret = nn->data;
        OPENSSL_free(nn);
        lh->num_delete++;
    }
    lh->num_items--;
    if ((lh->num_nodes > MIN_NODES) &&
        (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)))
        contract(lh);
    return ret;
}
['int tls_parse_ctos_psk(SSL *s, PACKET *pkt, unsigned int context, X509 *x,\n                       size_t chainidx)\n{\n    PACKET identities, binders, binder;\n    size_t binderoffset, hashsize;\n    SSL_SESSION *sess = NULL;\n    unsigned int id, i, ext = 0;\n    const EVP_MD *md = NULL;\n    if ((s->ext.psk_kex_mode\n            & (TLSEXT_KEX_MODE_FLAG_KE | TLSEXT_KEX_MODE_FLAG_KE_DHE)) == 0)\n        return 1;\n    if (!PACKET_get_length_prefixed_2(pkt, &identities)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR,\n                 SSL_F_TLS_PARSE_CTOS_PSK, SSL_R_BAD_EXTENSION);\n        return 0;\n    }\n    s->ext.ticket_expected = 0;\n    for (id = 0; PACKET_remaining(&identities) != 0; id++) {\n        PACKET identity;\n        unsigned long ticket_agel;\n        size_t idlen;\n        if (!PACKET_get_length_prefixed_2(&identities, &identity)\n                || !PACKET_get_net_4(&identities, &ticket_agel)) {\n            SSLfatal(s, SSL_AD_DECODE_ERROR,\n                     SSL_F_TLS_PARSE_CTOS_PSK, SSL_R_BAD_EXTENSION);\n            return 0;\n        }\n        idlen = PACKET_remaining(&identity);\n        if (s->psk_find_session_cb != NULL\n                && !s->psk_find_session_cb(s, PACKET_data(&identity), idlen,\n                                           &sess)) {\n            SSLfatal(s, SSL_AD_INTERNAL_ERROR,\n                     SSL_F_TLS_PARSE_CTOS_PSK, SSL_R_BAD_EXTENSION);\n            return 0;\n        }\n#ifndef OPENSSL_NO_PSK\n        if(sess == NULL\n                && s->psk_server_callback != NULL\n                && idlen <= PSK_MAX_IDENTITY_LEN) {\n            char *pskid = NULL;\n            unsigned char pskdata[PSK_MAX_PSK_LEN];\n            unsigned int pskdatalen;\n            if (!PACKET_strndup(&identity, &pskid)) {\n                SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,\n                         ERR_R_INTERNAL_ERROR);\n                return 0;\n            }\n            pskdatalen = s->psk_server_callback(s, pskid, pskdata,\n                                                sizeof(pskdata));\n            OPENSSL_free(pskid);\n            if (pskdatalen > PSK_MAX_PSK_LEN) {\n                SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,\n                         ERR_R_INTERNAL_ERROR);\n                return 0;\n            } else if (pskdatalen > 0) {\n                const SSL_CIPHER *cipher;\n                const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 };\n                cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id);\n                if (cipher == NULL) {\n                    OPENSSL_cleanse(pskdata, pskdatalen);\n                    SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,\n                             ERR_R_INTERNAL_ERROR);\n                    return 0;\n                }\n                sess = SSL_SESSION_new();\n                if (sess == NULL\n                        || !SSL_SESSION_set1_master_key(sess, pskdata,\n                                                        pskdatalen)\n                        || !SSL_SESSION_set_cipher(sess, cipher)\n                        || !SSL_SESSION_set_protocol_version(sess,\n                                                             TLS1_3_VERSION)) {\n                    OPENSSL_cleanse(pskdata, pskdatalen);\n                    SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,\n                             ERR_R_INTERNAL_ERROR);\n                    goto err;\n                }\n                OPENSSL_cleanse(pskdata, pskdatalen);\n            }\n        }\n#endif\n        if (sess != NULL) {\n            SSL_SESSION *sesstmp = ssl_session_dup(sess, 0);\n            if (sesstmp == NULL) {\n                SSLfatal(s, SSL_AD_INTERNAL_ERROR,\n                         SSL_F_TLS_PARSE_CTOS_PSK, ERR_R_INTERNAL_ERROR);\n                return 0;\n            }\n            SSL_SESSION_free(sess);\n            sess = sesstmp;\n            memcpy(sess->sid_ctx, s->sid_ctx, s->sid_ctx_length);\n            sess->sid_ctx_length = s->sid_ctx_length;\n            ext = 1;\n            if (id == 0)\n                s->ext.early_data_ok = 1;\n        } else {\n            uint32_t ticket_age = 0, now, agesec, agems;\n            int ret;\n            if ((s->options & SSL_OP_NO_TICKET) != 0\n                    || s->max_early_data > 0)\n                ret = tls_get_stateful_ticket(s, &identity, &sess);\n            else\n                ret = tls_decrypt_ticket(s, PACKET_data(&identity),\n                                         PACKET_remaining(&identity), NULL, 0,\n                                         &sess);\n            if (ret == SSL_TICKET_EMPTY) {\n                SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,\n                         SSL_R_BAD_EXTENSION);\n                return 0;\n            }\n            if (ret == SSL_TICKET_FATAL_ERR_MALLOC\n                    || ret == SSL_TICKET_FATAL_ERR_OTHER) {\n                SSLfatal(s, SSL_AD_INTERNAL_ERROR,\n                         SSL_F_TLS_PARSE_CTOS_PSK, ERR_R_INTERNAL_ERROR);\n                return 0;\n            }\n            if (ret == SSL_TICKET_NONE || ret == SSL_TICKET_NO_DECRYPT)\n                continue;\n            if (s->max_early_data > 0\n                    && !SSL_CTX_remove_session(s->session_ctx, sess)) {\n                SSL_SESSION_free(sess);\n                sess = NULL;\n                continue;\n            }\n            ticket_age = (uint32_t)ticket_agel;\n            now = (uint32_t)time(NULL);\n            agesec = now - (uint32_t)sess->time;\n            agems = agesec * (uint32_t)1000;\n            ticket_age -= sess->ext.tick_age_add;\n            if (id == 0\n                    && sess->timeout >= (long)agesec\n                    && agems / (uint32_t)1000 == agesec\n                    && ticket_age <= agems + 1000\n                    && ticket_age + TICKET_AGE_ALLOWANCE >= agems + 1000) {\n                s->ext.early_data_ok = 1;\n            }\n        }\n        md = ssl_md(sess->cipher->algorithm2);\n        if (md != ssl_md(s->s3->tmp.new_cipher->algorithm2)) {\n            SSL_SESSION_free(sess);\n            sess = NULL;\n            s->ext.early_data_ok = 0;\n            continue;\n        }\n        break;\n    }\n    if (sess == NULL)\n        return 1;\n    binderoffset = PACKET_data(pkt) - (const unsigned char *)s->init_buf->data;\n    hashsize = EVP_MD_size(md);\n    if (!PACKET_get_length_prefixed_2(pkt, &binders)) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,\n                 SSL_R_BAD_EXTENSION);\n        goto err;\n    }\n    for (i = 0; i <= id; i++) {\n        if (!PACKET_get_length_prefixed_1(&binders, &binder)) {\n            SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,\n                     SSL_R_BAD_EXTENSION);\n            goto err;\n        }\n    }\n    if (PACKET_remaining(&binder) != hashsize) {\n        SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_F_TLS_PARSE_CTOS_PSK,\n                 SSL_R_BAD_EXTENSION);\n        goto err;\n    }\n    if (tls_psk_do_binder(s, md, (const unsigned char *)s->init_buf->data,\n                          binderoffset, PACKET_data(&binder), NULL, sess, 0,\n                          ext) != 1) {\n        goto err;\n    }\n    sess->ext.tick_identity = id;\n    SSL_SESSION_free(s->session);\n    s->session = sess;\n    return 1;\nerr:\n    SSL_SESSION_free(sess);\n    return 0;\n}', 'int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)\n{\n    return remove_session_lock(ctx, c, 1);\n}', 'static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)\n{\n    SSL_SESSION *r;\n    int ret = 0;\n    if ((c != NULL) && (c->session_id_length != 0)) {\n        if (lck)\n            CRYPTO_THREAD_write_lock(ctx->lock);\n        if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) != NULL) {\n            ret = 1;\n            r = lh_SSL_SESSION_delete(ctx->sessions, r);\n            SSL_SESSION_list_remove(ctx, r);\n        }\n        c->not_resumable = 1;\n        if (lck)\n            CRYPTO_THREAD_unlock(ctx->lock);\n        if (ctx->remove_session_cb != NULL)\n            ctx->remove_session_cb(ctx, c);\n        if (ret)\n            SSL_SESSION_free(r);\n    } else\n        ret = 0;\n    return ret;\n}', 'DEFINE_LHASH_OF(SSL_SESSION)', 'void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data)\n{\n    unsigned long hash;\n    OPENSSL_LH_NODE *nn, **rn;\n    void *ret;\n    lh->error = 0;\n    rn = getrn(lh, data, &hash);\n    if (*rn == NULL) {\n        lh->num_no_delete++;\n        return NULL;\n    } else {\n        nn = *rn;\n        *rn = nn->next;\n        ret = nn->data;\n        OPENSSL_free(nn);\n        lh->num_delete++;\n    }\n    lh->num_items--;\n    if ((lh->num_nodes > MIN_NODES) &&\n        (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)))\n        contract(lh);\n    return ret;\n}']