Files
smartservice_native/hdssd/huslib/MultiplexTransport.h
T
2026-05-20 03:08:08 +09:00

512 lines
12 KiB
C++

#ifndef MULTIPLEX_TRANSPORT__H_
#define MULTIPLEX_TRANSPORT__H_
#ifdef _WIN32
#pragma once
#endif
class HMultiplexTransportTcpSocket;
class HMultiplexTransport : public HTransport
{
public:
HMultiplexTransport() {}
~HMultiplexTransport() {}
inline void SetMpSocket(HMultiplexTcpSocket * pSocket) { m_pMulplexTransportSocket = pSocket; }
inline HMultiplexTcpSocket * GetMpSocket() { return m_pMulplexTransportSocket; }
inline bool GetTransportInfo(const char * pName, void * pValue);
inline void Terminate();
inline int Send(const char * pData, int nSize);
protected:
HMultiplexTcpSocket * m_pMulplexTransportSocket;
friend class HMultiplexTransportTcpSocket;
friend class HMultiplexTransportSslSocket;
};
///////////////////////////////////////
class HMultiplexTransportTcpSocket : public HMultiplexTcpSocket
{
public:
HMultiplexTransportTcpSocket()
{
m_bAutoDelete = false;
m_nReconnectTime = 0;
m_pReceiveBuffer = (char *)malloc(g_nSocketReceiveBlockSize + 1);
m_pTransport = NULL;
}
HMultiplexTransportTcpSocket(SOCKET sock, struct sockaddr_in * psaiRemote, HMpsDispatcher * pDispatcher)
: HMultiplexTcpSocket(sock, psaiRemote, pDispatcher)
{
m_bAutoDelete = false;
m_nReconnectTime = 0;
m_pReceiveBuffer = (char *)malloc(g_nSocketReceiveBlockSize + 1);
m_pTransport = NULL;
}
~HMultiplexTransportTcpSocket()
{
if (m_pTransport)
delete m_pTransport;
free(m_pReceiveBuffer);
}
inline void AttachTransport(HMultiplexTransport * pTransport) { m_pTransport = pTransport; }
inline HMultiplexTransport * GetTransport() { return m_pTransport; }
inline void SetAutoDelete(bool bAutoDelete) { m_bAutoDelete = bAutoDelete; }
inline void SetAutoReconnect(DWORD nTime) { m_nReconnectTime = nTime; }
protected:
inline void OnClose()
{
if (m_bAutoDelete)
SetState(MPS_DELETE); // auto delete
else if (m_nReconnectTime > 0)
SetTimer(2181006, m_nReconnectTime);
m_pTransport->OnReceivedStatus(HTransport::T_END_TRANSPORT);
}
inline void OnConnect(bool bIsSuccess)
{
if (bIsSuccess == false)
{
m_pTransport->OnReceivedStatus(HTransport::T_FAILED_BEGIN);
return;
}
m_pTransport->OnReceivedStatus(HTransport::T_BEGIN_TRANSPORT);
}
inline void OnReceive()
{
if (m_pTransport == NULL)
return;
if (m_pTransport->OnPrepareReceive() == false)
return;
int nReceivedSize = Receive(m_pReceiveBuffer, g_nSocketReceiveBlockSize);
if (nReceivedSize <= 0)
return;
if (m_pTransport->OnReceived(m_pReceiveBuffer, nReceivedSize) < 0)
FinishTcp();
}
inline int OnSendRetry()
{
return m_pTransport->OnSendRetry();
}
inline void OnAccepted()
{
m_pTransport->OnReceivedStatus(HTransport::T_BEGIN_TRANSPORT);
}
ON_TIMER(HMultiplexTransportTcpSocket, OnTimer) // add void OnTimer(DWORD nTimerID) {}
protected:
char * m_pReceiveBuffer;
bool m_bAutoDelete;
DWORD m_nReconnectTime;
HMultiplexTransport * m_pTransport;
};
inline void HMultiplexTransportTcpSocket::OnTimer(unsigned int nTimerId)
{
KillTimer(2181006);
Create();
Connect(0);
}
///////////////////////////////////////
class HMultiplexTransportSslSocket : public HMultiplexSslSocket
{
public:
HMultiplexTransportSslSocket()
{
m_bAutoDelete = false;
m_nReconnectTime = 0;
m_pTransport = NULL;
}
HMultiplexTransportSslSocket(SOCKET sock, struct sockaddr_in * psaiRemote, HMpsDispatcher * pDispatcher)
: HMultiplexSslSocket(sock, psaiRemote, pDispatcher)
{
m_bAutoDelete = false;
m_nReconnectTime = 0;
m_pTransport = NULL;
}
~HMultiplexTransportSslSocket()
{
if (m_pTransport)
delete m_pTransport;
}
inline void AttachTransport(HMultiplexTransport * pTransport) { m_pTransport = pTransport; }
inline HMultiplexTransport * GetTransport() { return m_pTransport; }
inline void SetAutoDelete(bool bAutoDelete) { m_bAutoDelete = bAutoDelete; }
inline void SetAutoReconnect(DWORD nTime) { m_nReconnectTime = nTime; }
inline void OnAccepted()
{
HMultiplexSslSocket::OnAccepted();
m_pTransport->OnReceivedStatus(HTransport::T_BEGIN_TRANSPORT);
}
protected:
inline void OnClose()
{
if (m_bAutoDelete)
SetState(MPS_DELETE); // auto delete
else if (m_nReconnectTime > 0)
SetTimer(2181006, m_nReconnectTime);
m_pTransport->OnReceivedStatus(HTransport::T_END_TRANSPORT);
}
inline void OnReceive()
{
if (m_pTransport == NULL)
return;
if (m_pTransport->OnPrepareReceive() == false)
return;
Receive();
while (m_pStreamBufferForDecrypt->StoredSize() > 0)
{
//HLOGF(HLOG_WARNING, "SSL_TRACE, recv size = %d\n", m_pStreamBufferForDecrypt->StoredSize());
//HLOGD(HLOG_WARNING, m_pStreamBufferForDecrypt->Head(), 40, true);
if (m_pStreamBufferForDecrypt->StoredSize() > (size_t)g_nSocketReceiveBlockSize)
{
if (m_pTransport->OnReceived(m_pStreamBufferForDecrypt->Head(), g_nSocketReceiveBlockSize) < 0)
{
FinishTcp();
return;
}
m_pStreamBufferForDecrypt->Pop(g_nSocketReceiveBlockSize);
}
else
{
if (m_pTransport->OnReceived(m_pStreamBufferForDecrypt->Head(), m_pStreamBufferForDecrypt->StoredSize()) < 0)
{
FinishTcp();
return;
}
m_pStreamBufferForDecrypt->Reset();
}
}
}
inline int OnSendRetry()
{
if (m_bEncryptRetry)
return m_pTransport->OnSendRetry();
return SendBufferedData();
}
inline void OnConnectChild(bool bIsSuccess)
{
if (bIsSuccess == false)
{
SetState(MPS_CLOSING);
m_pTransport->OnReceivedStatus(HTransport::T_FAILED_BEGIN);
return;
}
m_pTransport->OnReceivedStatus(HTransport::T_BEGIN_TRANSPORT);
}
ON_TIMER(HMultiplexTransportSslSocket, OnTimer) // add void OnTimer(DWORD nTimerID) {}
protected:
bool m_bAutoDelete;
DWORD m_nReconnectTime;
HMultiplexTransport * m_pTransport;
};
inline void HMultiplexTransportSslSocket::OnTimer(unsigned int nTimerId)
{
KillTimer(2181006);
Create();
Connect(0);
}
/////////////////////////////////////////////////
inline bool HMultiplexTransport::GetTransportInfo(const char * pName, void * pValue)
{
if (strcmp(pName, "peer_ip") == 0)
{
int nResult = m_pMulplexTransportSocket->GetPeerAddress((char *)pValue, NULL);
if (nResult)
{
HLOGF(HLOG_WARNING, "[WARN], MplxTrnsp, Failed to GetPeerAddress 1, error = %d\n", nResult);
return false;
}
return true;
}
else if (strcmp(pName, "peer_port") == 0)
{
int nResult = m_pMulplexTransportSocket->GetPeerAddress(NULL, (u_short *)pValue);
if (nResult)
{
HLOGF(HLOG_WARNING, "[WARN], MplxTrnsp, Failed to GetPeerAddress 2, error = %d\n", nResult);
return false;
}
return true;
}
else if (strcmp(pName, "peer_address") == 0)
{
char szIp[32];
u_short nPort = 0;
int nResult = m_pMulplexTransportSocket->GetPeerAddress(szIp, &nPort);
if (nResult)
{
HLOGF(HLOG_WARNING, "[WARN], MplxTrnsp, Failed to GetPeerAddress 3, error = %d\n", nResult);
return false;
}
sprintf((char *)pValue, "%s:%d", szIp, nPort);
return true;
}
else if (strcmp(pName, "is_ssl_socket") == 0)
{
*((bool *)pValue) = m_pMulplexTransportSocket->IsSslSocket();
return true;
}
return false;
}
inline void HMultiplexTransport::Terminate()
{
m_pMulplexTransportSocket->FinishTcp();
}
inline int HMultiplexTransport::Send(const char * pData, int nSize)
{
return m_pMulplexTransportSocket->Send(pData, nSize);
}
/////////////////////////////////////////////////
template<class _THandler, class _TSocket>
class HMulplexTransportListenSocket : public HMultiplexListenSocket
{
public:
HMulplexTransportListenSocket() {}
~HMulplexTransportListenSocket() {}
protected:
HMultiplexTcpSocket * OnAccept(SOCKET sock, struct sockaddr_in * psaiRemote)
{
HMultiplexTransport * pMultiplexTransport = new HMultiplexTransport;
pMultiplexTransport->AttachHandler(new _THandler);
_TSocket * pSocket = new _TSocket(sock, psaiRemote, GetDispatcher());
pMultiplexTransport->SetMpSocket(pSocket);
pSocket->AttachTransport(pMultiplexTransport);
pSocket->SetAutoDelete(true);
return pSocket;
}
};
/////////////////////////////////////////////////
class HMulplexSocketConnector
{
public:
HMulplexSocketConnector() { m_pVecOutboundIp = NULL; m_nOutboundIpIndex = -1; }
virtual ~HMulplexSocketConnector() {}
inline void SetOutboundIpList(HStrVector * pVector) { m_pVecOutboundIp = pVector; }
inline void SetOutboundIpIndex(int nIndex) { m_nOutboundIpIndex = nIndex; }
virtual bool Connect(const char * pszAddress, u_short nPort, unsigned nTimeout, HMpsDispatcher * pDispatcher) { return false; }
protected:
HStrVector * m_pVecOutboundIp;
int m_nOutboundIpIndex;
};
template<class _THandler, class _TSocket>
class HMulplexTransportConnector : public HMulplexSocketConnector
{
public:
HMulplexTransportConnector() { m_pHandler = NULL; }
~HMulplexTransportConnector() {}
inline _THandler * GetHandler() { return m_pHandler; }
inline bool Connect(const char * pszAddress, u_short nPort, unsigned nTimeout, HMpsDispatcher * pDispatcher, unsigned long nAutoReconnectTime = 0)
{
HMultiplexTransport * pMultiplexTransport = new HMultiplexTransport;
m_pHandler = new _THandler;
pMultiplexTransport->AttachHandler(m_pHandler);
_TSocket * pSocket = new _TSocket;
if (pSocket->Create() == false)
{
delete pSocket;
delete pMultiplexTransport;
return false;
}
pMultiplexTransport->SetMpSocket(pSocket);
pSocket->AttachTransport(pMultiplexTransport);
if (nAutoReconnectTime > 0)
pSocket->SetAutoReconnect(nAutoReconnectTime);
else
pSocket->SetAutoDelete(true);
HLOGF(HLOG_INFO3, "INFO, MpConnector, Connect, inst = 0x%x, %s:%d\n", this, pszAddress, nPort);
if (IsIpString(pszAddress))
pSocket->SetRemoteAddress(pszAddress, nPort);
else
pSocket->SetRemoteAddressHostByName(pszAddress, nPort);
if (m_pVecOutboundIp && m_pVecOutboundIp->size() > 0)
{
// outbound load balance
static int nIpCount = m_pVecOutboundIp->size();
static int nIpIndex = 0;
static u_short nPort = 20000;
if (nIpCount <= 0)
return false;
if (++nIpIndex >= nIpCount)
nIpIndex = 0;
for (int i = 20000; i < 60000; i++)
{
if (++nPort >= 60000)
nPort = 20000;
if (m_nOutboundIpIndex != -1)
{
if (pSocket->Bind((*m_pVecOutboundIp)[m_nOutboundIpIndex], nPort))
break;
}
else
{
if (pSocket->Bind((*m_pVecOutboundIp)[nIpIndex], nPort))
break;
}
Sleep(50);
}
}
if (pSocket->Connect(nTimeout) == false)
{
delete pSocket;
return false;
}
pDispatcher->Attach(pSocket);
return true;
}
private:
_THandler * m_pHandler;
};
/////////////////////////////////////////////////
template<class _THandler, class _TSocket>
class HMulplexTransportListenThread : public HMultiplexListenThread<HMultiplexTcpSocket>
{
public:
HMulplexTransportListenThread() {}
~HMulplexTransportListenThread() {}
protected:
HMultiplexTcpSocket * OnAccept(SOCKET sock, struct sockaddr_in * psaiRemote)
{
HMultiplexTransport * pMultiplexTransport = new HMultiplexTransport;
pMultiplexTransport->AttachHandler(new _THandler);
#if 1
HMpsDispatcher * pDispatcher = m_pListDispatcher->GetLazyDispatcher();
_TSocket * pSocket = new _TSocket(sock, psaiRemote, pDispatcher);
pMultiplexTransport->SetMpSocket(pSocket);
pSocket->AttachTransport(pMultiplexTransport);
pSocket->SetAutoDelete(true);
pDispatcher->AttachWithLock(pSocket);
return pSocket;
#else
HMpsDispatcherList::iterator iter;
int i = 0;
for (iter = m_pListDispatcher->begin(); iter != m_pListDispatcher->end(); iter++)
{
if ((*iter)->IsProcessing() == false)
i++;
}
//HLOGF(HLOG_WARNING, "[TRACE], MplxTrnspLstnThr_0x%x, lazy dispatcher count = %d\n", this, i);
for (;;)
{
for (iter = m_pListDispatcher->begin(); iter != m_pListDispatcher->end(); iter++)
{
if ((*iter)->IsProcessing() == false)
{
_TSocket * pSocket = new _TSocket(sock, psaiRemote, *iter);
pMultiplexTransport->SetMpSocket(pSocket);
pSocket->AttachTransport(pMultiplexTransport);
pSocket->SetAutoDelete(true);
(*iter)->AttachWithLock(pSocket);
return pSocket;
}
}
Sleep(10);
}
#endif
}
};
#if 1
typedef std::list<HMultiplexListenThread<HMultiplexTcpSocket> *> HMultiplexListenThreadList;
#else
class HMultiplexListenThreadList : public std::list<HMultiplexListenThread<HMultiplexTcpSocket> *>
{
public:
HMultiplexListenThreadList() {}
~HMultiplexListenThreadList() {}
};
#endif
#endif // MULTIPLEX_TRANSPORT__H_