+ /* Choose which callback will set the session ID */
+ CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
+ if(s->generate_session_id)
+ cb = s->generate_session_id;
+ else if(s->ctx->generate_session_id)
+ cb = s->ctx->generate_session_id;
+ CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
+ /* Choose a session ID */
+ tmp = ss->session_id_length;
+ if(!cb(s, ss->session_id, &tmp))
+ {
+ /* The callback failed */
+ SSLerr(SSL_F_SSL_GET_NEW_SESSION,
+ SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
+ SSL_SESSION_free(ss);
+ return(0);
+ }
+ /* Don't allow the callback to set the session length to zero.
+ * nor set it higher than it was. */
+ if(!tmp || (tmp > ss->session_id_length))
+ {
+ /* The callback set an illegal length */
+ SSLerr(SSL_F_SSL_GET_NEW_SESSION,
+ SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
+ SSL_SESSION_free(ss);
+ return(0);
+ }
+ /* If the session length was shrunk and we're SSLv2, pad it */
+ if((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
+ memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
+ else
+ ss->session_id_length = tmp;
+ /* Finally, check for a conflict */
+ if(SSL_has_matching_session_id(s, ss->session_id,
+ ss->session_id_length))