OmniNet 0.7.4: CRITICAL — Fix TLSContext::createSocket() double-free
This is a hotfix release. v0.7.2 and v0.7.3 had a regression
that caused 'free(): double free' abort on every HTTPS request
when using the new TLSContext::createClient()->createSocket()
factory pattern.
Root cause: Both ~TLSSocket() (via cleanupContext()) AND
~TLSContext() called SSL_CTX_free() on the same SSL_CTX pointer.
When the socket was created via createSocket(), the socket's
m_ctx aliased the context's m_ctx (no copy, just a pointer).
When both destructors ran, SSL_CTX_free was called twice.
Fix: Track ownership via the m_context shared_ptr member.
In cleanupContext(), only call SSL_CTX_free(m_ctx) when m_context
is null (the socket owns its own context). When m_context is
non-null, the shared TLSContext owns the SSL_CTX and is the
sole owner responsible for freeing it. The socket just drops
its alias (sets m_ctx = nullptr).
Commit: c994cf2
Affects: any user of TLSContext::createClient()->createSocket()
or TLSContext::createServer()->createSocket()
Does NOT affect: TLSSocket constructed directly (default ctor,
fd ctor, or std::unique_ptr<Socket> ctor) — those
still own their SSL_CTX and free it in ~TLSSocket.
Upgrade: MANDATORY if you use TLSContext::createSocket() in 0.7.2/0.7.3.
Otherwise optional (0.7.2/0.7.3 is fine for the TLSSocket
default-constructor path).
Build verified clean. All existing tests pass (no regressions).