#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 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 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 HMulplexTransportListenThread : public HMultiplexListenThread { 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 *> HMultiplexListenThreadList; #else class HMultiplexListenThreadList : public std::list *> { public: HMultiplexListenThreadList() {} ~HMultiplexListenThreadList() {} }; #endif #endif // MULTIPLEX_TRANSPORT__H_