1
0

Merge pull request #2831 from cuberite/BlockingSslClientSocketFix

Changed m_IsConnected to an atomic bool, added logging.
This commit is contained in:
Mattes D 2015-12-30 13:36:17 +01:00
commit 1210eb1316
3 changed files with 24 additions and 11 deletions

View File

@ -70,7 +70,9 @@ class cBlockingSslClientSocketLinkCallbacks:
{ {
m_Socket.OnDisconnected(); m_Socket.OnDisconnected();
} }
public: public:
cBlockingSslClientSocketLinkCallbacks(cBlockingSslClientSocket & a_Socket): cBlockingSslClientSocketLinkCallbacks(cBlockingSslClientSocket & a_Socket):
m_Socket(a_Socket) m_Socket(a_Socket)
{ {
@ -143,7 +145,6 @@ bool cBlockingSslClientSocket::Connect(const AString & a_ServerName, UInt16 a_Po
return false; return false;
} }
m_IsConnected = true;
return true; return true;
} }
@ -182,7 +183,11 @@ bool cBlockingSslClientSocket::SetTrustedRootCertsFromString(const AString & a_C
bool cBlockingSslClientSocket::Send(const void * a_Data, size_t a_NumBytes) bool cBlockingSslClientSocket::Send(const void * a_Data, size_t a_NumBytes)
{ {
ASSERT(m_IsConnected); if (!m_IsConnected)
{
m_LastErrorText = "Socket is closed";
return false;
}
// Keep sending the data until all of it is sent: // Keep sending the data until all of it is sent:
const char * Data = reinterpret_cast<const char *>(a_Data); const char * Data = reinterpret_cast<const char *>(a_Data);
@ -216,8 +221,7 @@ bool cBlockingSslClientSocket::Send(const void * a_Data, size_t a_NumBytes)
int cBlockingSslClientSocket::Receive(void * a_Data, size_t a_MaxBytes) int cBlockingSslClientSocket::Receive(void * a_Data, size_t a_MaxBytes)
{ {
ASSERT(m_IsConnected); // Even if m_IsConnected is false (socket disconnected), the SSL context may have more data in the queue
int res = m_Ssl.ReadPlain(a_Data, a_MaxBytes); int res = m_Ssl.ReadPlain(a_Data, a_MaxBytes);
if (res < 0) if (res < 0)
{ {
@ -239,9 +243,16 @@ void cBlockingSslClientSocket::Disconnect(void)
} }
m_Ssl.NotifyClose(); m_Ssl.NotifyClose();
m_Socket->Close();
m_Socket.reset();
m_IsConnected = false; m_IsConnected = false;
// Grab a copy of the socket so that we know it doesn't change under our hands:
auto socket = m_Socket;
if (socket != nullptr)
{
socket->Close();
}
m_Socket.reset();
} }
@ -293,6 +304,7 @@ int cBlockingSslClientSocket::SendEncrypted(const unsigned char * a_Buffer, size
void cBlockingSslClientSocket::OnConnected(void) void cBlockingSslClientSocket::OnConnected(void)
{ {
m_IsConnected = true; m_IsConnected = true;
@ -305,7 +317,7 @@ void cBlockingSslClientSocket::OnConnected(void)
void cBlockingSslClientSocket::OnConnectError(const AString & a_ErrorMsg) void cBlockingSslClientSocket::OnConnectError(const AString & a_ErrorMsg)
{ {
LOG("Cannot connect to %s: %s", m_ServerName.c_str(), a_ErrorMsg.c_str()); LOG("Cannot connect to %s: \"%s\"", m_ServerName.c_str(), a_ErrorMsg.c_str());
m_Event.Set(); m_Event.Set();
} }
@ -337,8 +349,8 @@ void cBlockingSslClientSocket::SetLink(cTCPLinkPtr a_Link)
void cBlockingSslClientSocket::OnDisconnected(void) void cBlockingSslClientSocket::OnDisconnected(void)
{ {
m_Socket.reset();
m_IsConnected = false; m_IsConnected = false;
m_Socket.reset();
m_Event.Set(); m_Event.Set();
} }

View File

@ -9,6 +9,7 @@
#pragma once #pragma once
#include <atomic>
#include "OSSupport/Network.h" #include "OSSupport/Network.h"
#include "CallbackSslContext.h" #include "CallbackSslContext.h"
@ -81,7 +82,7 @@ protected:
AString m_LastErrorText; AString m_LastErrorText;
/** Set to true if the connection established successfully. */ /** Set to true if the connection established successfully. */
bool m_IsConnected; std::atomic<bool> m_IsConnected;
/** Protects m_IncomingData against multithreaded access. */ /** Protects m_IncomingData against multithreaded access. */
cCriticalSection m_CSIncomingData; cCriticalSection m_CSIncomingData;

View File

@ -748,7 +748,7 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
Json::Reader reader; Json::Reader reader;
if (!reader.parse(Response, root, false) || !root.isArray()) if (!reader.parse(Response, root, false) || !root.isArray())
{ {
LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON: \"%s\"", __FUNCTION__, reader.getFormattedErrorMessages().c_str());
LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
continue; continue;
} }
@ -861,7 +861,7 @@ void cMojangAPI::QueryUUIDToProfile(const AString & a_UUID)
Json::Value root; Json::Value root;
if (!reader.parse(Response, root, false) || !root.isObject()) if (!reader.parse(Response, root, false) || !root.isObject())
{ {
LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON!", __FUNCTION__); LOGWARNING("%s failed: Cannot parse received data (NameToUUID) to JSON: \"%s\"", __FUNCTION__, reader.getFormattedErrorMessages().c_str());
LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str()); LOGD("Response body:\n%s", CreateHexDump(HexDump, Response.data(), Response.size(), 16).c_str());
return; return;
} }