Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 6 additions & 22 deletions iocore/net/SSLSessionCache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -326,22 +326,8 @@ SSLOriginSessionCache::insert_session(const std::string &lookup_key, SSL_SESSION
Debug("ssl.origin_session_cache", "insert session: %s = %p", lookup_key.c_str(), sess);
}

size_t len = i2d_SSL_SESSION(sess, nullptr);

Ptr<IOBufferData> buf;
Ptr<IOBufferData> buf_exdata;
size_t len_exdata = sizeof(ssl_session_cache_exdata);
buf = new_IOBufferData(buffer_size_to_index(len, MAX_BUFFER_SIZE_INDEX), MEMALIGNED);
ink_release_assert(static_cast<size_t>(buf->block_size()) >= len);
unsigned char *loc = reinterpret_cast<unsigned char *>(buf->data());
i2d_SSL_SESSION(sess, &loc);
buf_exdata = new_IOBufferData(buffer_size_to_index(len, MAX_BUFFER_SIZE_INDEX), MEMALIGNED);
ink_release_assert(static_cast<size_t>(buf_exdata->block_size()) >= len_exdata);
ssl_session_cache_exdata *exdata = reinterpret_cast<ssl_session_cache_exdata *>(buf_exdata->data());
// This could be moved to a function in charge of populating exdata
exdata->curve = (ssl == nullptr) ? 0 : SSLGetCurveNID(ssl);

ats_scoped_obj<SSLOriginSession> ssl_orig_session(new SSLOriginSession(lookup_key, buf, len, buf_exdata));
ssl_curve_id curve = (ssl == nullptr) ? 0 : SSLGetCurveNID(ssl);
ats_scoped_obj<SSLOriginSession> ssl_orig_session(new SSLOriginSession(lookup_key, sess, curve));
auto new_node = ssl_orig_session.release();

std::unique_lock lock(mutex);
Expand All @@ -360,7 +346,7 @@ SSLOriginSessionCache::insert_session(const std::string &lookup_key, SSL_SESSION
}

bool
SSLOriginSessionCache::get_session(const std::string &lookup_key, SSL_SESSION **sess, ssl_session_cache_exdata **data)
SSLOriginSessionCache::get_session(const std::string &lookup_key, SSL_SESSION **sess, ssl_curve_id *curve)
{
if (is_debug_tag_set("ssl.origin_session_cache")) {
Debug("ssl.origin_session_cache", "get session: %s", lookup_key.c_str());
Expand All @@ -372,11 +358,9 @@ SSLOriginSessionCache::get_session(const std::string &lookup_key, SSL_SESSION **
return false;
}

const unsigned char *loc = reinterpret_cast<const unsigned char *>(entry->second->asn1_data->data());
*sess = d2i_SSL_SESSION(nullptr, &loc, entry->second->len_asn1_data);
if (data != nullptr) {
ssl_session_cache_exdata *exdata = reinterpret_cast<ssl_session_cache_exdata *>(entry->second->extra_data->data());
*data = exdata;
*sess = entry->second->session;
if (curve != nullptr) {
*curve = entry->second->curve_id;
}
return true;
}
Expand Down
14 changes: 7 additions & 7 deletions iocore/net/SSLSessionCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,16 +187,16 @@ class SSLOriginSession
{
public:
std::string key;
Ptr<IOBufferData> asn1_data; /* this is the ASN1 representation of the SSL_CTX */
size_t len_asn1_data;
Ptr<IOBufferData> extra_data;
SSL_SESSION *session;
ssl_curve_id curve_id;

SSLOriginSession(const std::string &lookup_key, const Ptr<IOBufferData> &ssl_asn1_data, size_t len_asn1,
Ptr<IOBufferData> &exdata)
: key(lookup_key), asn1_data(ssl_asn1_data), len_asn1_data(len_asn1), extra_data(exdata)
SSLOriginSession(const std::string &lookup_key, SSL_SESSION *sess, ssl_curve_id curve)
: key(lookup_key), session(sess), curve_id(curve)
{
}

~SSLOriginSession() { SSL_SESSION_free(session); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling SSL_SESSION_free here is the fix, and other changes are not, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, this is freeing the session when it's being replaced or removed from the cache, as we're not doing the i2d_SSL_SESSION conversion and returning the correct return value through the new session callback.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for the leak is because when we do the i2d_SSL_SESSION for the server sessions, we always return 0 so the reference count for the actual OpenSSL's session object is decreased after returning from the callback, and we do some manual cleanups in our NetVC if we convert the session object back. But we seem to not do that for the origin sessions, and just rely on OpenSSL's own ref counter to clean up things.


LINK(SSLOriginSession, link);
};

Expand All @@ -207,7 +207,7 @@ class SSLOriginSessionCache
~SSLOriginSessionCache();

void insert_session(const std::string &lookup_key, SSL_SESSION *sess, SSL *ssl);
bool get_session(const std::string &lookup_key, SSL_SESSION **sess, ssl_session_cache_exdata **data);
bool get_session(const std::string &lookup_key, SSL_SESSION **sess, ssl_curve_id *curve);

private:
void remove_oldest_session(const std::unique_lock<std::shared_mutex> &lock);
Expand Down
9 changes: 4 additions & 5 deletions iocore/net/TLSSessionResumptionSupport.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,10 @@ TLSSessionResumptionSupport::getSession(SSL *ssl, const unsigned char *id, int l
SSL_SESSION *
TLSSessionResumptionSupport::getOriginSession(SSL *ssl, const std::string &lookup_key)
{
SSL_SESSION *session = nullptr;
ssl_session_cache_exdata *exdata = nullptr;
if (origin_sess_cache->get_session(lookup_key, &session, &exdata)) {
SSL_SESSION *session = nullptr;
ssl_curve_id curve = 0;
if (origin_sess_cache->get_session(lookup_key, &session, &curve)) {
ink_assert(session);
ink_assert(exdata);

// Double check the timeout
if (is_ssl_session_timed_out(session)) {
Expand All @@ -188,7 +187,7 @@ TLSSessionResumptionSupport::getOriginSession(SSL *ssl, const std::string &looku
} else {
SSL_INCREMENT_DYN_STAT(ssl_origin_session_cache_hit);
this->_setSSLSessionCacheHit(true);
this->_setSSLCurveNID(exdata->curve);
this->_setSSLCurveNID(curve);
}
} else {
SSL_INCREMENT_DYN_STAT(ssl_origin_session_cache_miss);
Expand Down