Implement SOCKS proxy feature
This commit is contained in:
222
server/2015Remote/proxy/ProxyConnectServer.cpp
Normal file
222
server/2015Remote/proxy/ProxyConnectServer.cpp
Normal file
@@ -0,0 +1,222 @@
|
||||
#include "stdafx.h"
|
||||
#include "ProxyConnectServer.h"
|
||||
|
||||
#define MAX_SEND_BUFFER 65535 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD> 1024*64
|
||||
#define MAX_RECV_BUFFER 65535 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
|
||||
|
||||
CProxyConnectServer::CProxyConnectServer(void) :m_TcpServer(this)
|
||||
{
|
||||
Mprintf("CProxyConnectServer\r\n");
|
||||
m_bIsRun = TRUE;
|
||||
m_dwIndex = 0;
|
||||
memset(m_IDs, 0, sizeof(m_IDs));
|
||||
}
|
||||
|
||||
|
||||
CProxyConnectServer::~CProxyConnectServer(void)
|
||||
{
|
||||
if (m_TcpServer->GetState() != SS_STOPPED)
|
||||
m_TcpServer->Stop();
|
||||
while (m_TcpServer->GetState() != SS_STOPPED) {
|
||||
Sleep(300);
|
||||
}
|
||||
Mprintf("~CProxyConnectServer\r\n");
|
||||
}
|
||||
|
||||
BOOL CProxyConnectServer::Initialize(NOTIFYPROC pNotifyProc, void*user, int nMaxConnections, int nPort)
|
||||
{
|
||||
m_nMaxConnection = nMaxConnections;
|
||||
m_TcpServer->SetMaxConnectionCount(nMaxConnections);
|
||||
m_TcpServer->SetSendPolicy(SP_DIRECT);
|
||||
m_TcpServer->SetNoDelay(TRUE);
|
||||
m_pNotifyProc = pNotifyProc;
|
||||
m_pUser = user;
|
||||
m_nPort = nPort;
|
||||
m_bStop = FALSE;
|
||||
return m_TcpServer->Start(_T("0.0.0.0"), nPort);
|
||||
}
|
||||
|
||||
EnHandleResult CProxyConnectServer::OnPrepareListen(ITcpServer* pSender, SOCKET soListen)
|
||||
{
|
||||
SYS_SSO_SendBuffSize(soListen, MAX_SEND_BUFFER);
|
||||
SYS_SSO_RecvBuffSize(soListen, MAX_RECV_BUFFER);
|
||||
return HR_OK;
|
||||
}
|
||||
|
||||
EnHandleResult CProxyConnectServer::OnAccept(ITcpServer* pSender, CONNID dwConnID, UINT_PTR soClient)
|
||||
{
|
||||
if (!m_bIsRun)return HR_ERROR;
|
||||
|
||||
ClientContext* pContext = NULL;
|
||||
{
|
||||
m_Locker.lock();
|
||||
if (!m_listFreePool.IsEmpty()) {
|
||||
pContext = m_listFreePool.RemoveHead();
|
||||
}
|
||||
else {
|
||||
pContext = new(std::nothrow) ClientContext;
|
||||
}
|
||||
m_Locker.unlock();
|
||||
}
|
||||
if (pContext == NULL)
|
||||
return HR_ERROR;
|
||||
|
||||
pContext->InitMember();
|
||||
pContext->m_Socket = dwConnID;
|
||||
char szAddress[64] = {};
|
||||
int iAddressLen = sizeof(szAddress);
|
||||
USHORT usPort = 0;
|
||||
pSender->GetRemoteAddress(dwConnID, szAddress, iAddressLen, usPort);
|
||||
Mprintf("CProxyConnectServer: new connection %s:%d\n", szAddress, usPort);
|
||||
pContext->ID = dwConnID;
|
||||
m_TcpServer->SetConnectionExtra(dwConnID, pContext);
|
||||
m_pNotifyProc(m_pUser, pContext, NC_CLIENT_CONNECT);
|
||||
return HR_OK;
|
||||
}
|
||||
|
||||
EnHandleResult CProxyConnectServer::OnSend(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength)
|
||||
{
|
||||
return HR_OK;
|
||||
}
|
||||
|
||||
EnHandleResult CProxyConnectServer::OnReceive(ITcpServer* pSender, CONNID dwConnID, int iLength)
|
||||
{
|
||||
ClientContext* pContext = NULL;
|
||||
if ((!m_TcpServer->GetConnectionExtra(dwConnID, (PVOID*)&pContext)) && (pContext != nullptr) && (iLength <= 0))
|
||||
return HR_ERROR;
|
||||
|
||||
PBYTE pData = new BYTE[iLength];
|
||||
m_TcpServer->Fetch(dwConnID, pData, iLength);
|
||||
pContext->InDeCompressedBuffer.ClearBuffer();
|
||||
BYTE bToken = COMMAND_PROXY_DATA;
|
||||
pContext->InDeCompressedBuffer.Write(&bToken, sizeof(bToken));
|
||||
pContext->InDeCompressedBuffer.Write((LPBYTE)&pContext->ID, sizeof(DWORD));
|
||||
pContext->InDeCompressedBuffer.Write((PBYTE)pData, iLength);
|
||||
SAFE_DELETE_ARRAY(pData);
|
||||
m_pNotifyProc(m_pUser, pContext, NC_RECEIVE);
|
||||
return HR_OK;
|
||||
}
|
||||
|
||||
EnHandleResult CProxyConnectServer::OnClose(ITcpServer* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode)
|
||||
{
|
||||
ClientContext* pContext = NULL;
|
||||
if (m_TcpServer->GetConnectionExtra(dwConnID, (PVOID*)&pContext) && pContext != nullptr)
|
||||
m_TcpServer->SetConnectionExtra(dwConnID, NULL);
|
||||
if (!pContext)
|
||||
return HR_OK;
|
||||
|
||||
m_pNotifyProc(m_pUser, pContext, NC_CLIENT_DISCONNECT);
|
||||
pContext->InCompressedBuffer.ClearBuffer();
|
||||
pContext->InDeCompressedBuffer.ClearBuffer();
|
||||
pContext->OutCompressedBuffer.ClearBuffer();
|
||||
m_Locker.lock();
|
||||
m_listFreePool.AddTail(pContext);
|
||||
m_Locker.unlock();
|
||||
return HR_OK;
|
||||
}
|
||||
|
||||
EnHandleResult CProxyConnectServer::OnShutdown(ITcpServer* pSender)
|
||||
{
|
||||
return HR_OK;
|
||||
}
|
||||
|
||||
|
||||
BOOL CProxyConnectServer::Send(ClientContext* pContext, LPBYTE lpData, UINT nSize)
|
||||
{
|
||||
if (pContext == NULL)
|
||||
return FALSE;
|
||||
|
||||
BOOL rt = FALSE;;
|
||||
if (nSize > 0 && m_bIsRun) {
|
||||
pContext->OutCompressedBuffer.Write(lpData, nSize);
|
||||
rt = SendWithSplit(pContext->m_Socket, pContext->OutCompressedBuffer.GetBuffer(0),
|
||||
pContext->OutCompressedBuffer.GetBufferLength(), MAX_SEND_BUFFER);
|
||||
pContext->OutCompressedBuffer.ClearBuffer();
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
BOOL CProxyConnectServer::SendWithSplit(CONNID dwConnID, LPBYTE lpData, UINT nSize, UINT nSplitSize)
|
||||
{
|
||||
int nSend = 0;
|
||||
UINT nSendRetry = 0;
|
||||
BOOL rt = TRUE;
|
||||
if (nSize >= nSplitSize) {
|
||||
UINT i = 0;
|
||||
nSendRetry = nSize / nSplitSize;
|
||||
for (i = 0; i < nSendRetry; i++) {
|
||||
rt = m_TcpServer->Send(dwConnID, lpData, nSplitSize);
|
||||
if (!rt)
|
||||
return rt;
|
||||
lpData += nSplitSize;
|
||||
nSend += nSplitSize;
|
||||
}
|
||||
if (nSize - nSend < nSplitSize) {
|
||||
if (nSize - nSend > 0) {
|
||||
rt = m_TcpServer->Send(dwConnID, lpData, nSize - nSend);
|
||||
if (!rt)
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
rt = m_TcpServer->Send(dwConnID, lpData, nSize);
|
||||
if (!rt)
|
||||
return rt;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
void CProxyConnectServer::Shutdown()
|
||||
{
|
||||
DWORD dwCount = 65535;
|
||||
CONNID *pIDs = new CONNID[dwCount]();
|
||||
BOOL status = m_TcpServer->GetAllConnectionIDs(pIDs, dwCount);
|
||||
if (status && (dwCount > 0)) {
|
||||
for (DWORD i = 0; i < dwCount; i++) {
|
||||
Disconnect(pIDs[i]);
|
||||
}
|
||||
}
|
||||
m_TcpServer->Stop();
|
||||
m_bIsRun = FALSE;
|
||||
while (m_TcpServer->GetState() != SS_STOPPED)
|
||||
Sleep(10);
|
||||
|
||||
m_Locker.lock();
|
||||
while (!m_listFreePool.IsEmpty())
|
||||
delete m_listFreePool.RemoveTail();
|
||||
m_Locker.unlock();
|
||||
|
||||
SAFE_DELETE_ARRAY(pIDs);
|
||||
}
|
||||
|
||||
void CProxyConnectServer::ClearClient()
|
||||
{
|
||||
DWORD dwCount = 65535;
|
||||
CONNID* pIDs = new CONNID[dwCount]();
|
||||
BOOL status = m_TcpServer->GetAllConnectionIDs(pIDs, dwCount);
|
||||
if (status && (dwCount > 0)) {
|
||||
for (DWORD i = 0; i < dwCount; i++) {
|
||||
m_TcpServer->Disconnect(pIDs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY(pIDs);
|
||||
}
|
||||
|
||||
BOOL CProxyConnectServer::Disconnect(CONNID dwConnID)
|
||||
{
|
||||
m_TcpServer->Disconnect(dwConnID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL CProxyConnectServer::IsConnected(CONNID dwConnID)
|
||||
{
|
||||
return m_TcpServer->IsConnected(dwConnID);
|
||||
}
|
||||
|
||||
BOOL CProxyConnectServer::IsOverMaxConnectionCount()
|
||||
{
|
||||
return (m_TcpServer->GetConnectionCount() > (DWORD)m_nMaxConnection);
|
||||
}
|
||||
Reference in New Issue
Block a user