www.pudn.com > sock5 > ProxySocket.cpp


// ProxySocket.cpp : implementation file 
// 
 
#include "stdafx.h" 
#include "SockProxy.h" 
#include "ProxySocket.h" 
#include "asyncproxysocket.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
// CProxySocket 
 
CProxySocket::CProxySocket() 
{ 
	m_mode = 0; 
} 
 
CProxySocket::~CProxySocket() 
{ 
} 
 
 
// Do not edit the following lines, which are needed by ClassWizard. 
#if 0 
BEGIN_MESSAGE_MAP(CProxySocket, CSocket) 
	//{{AFX_MSG_MAP(CProxySocket) 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
#endif	// 0 
 
///////////////////////////////////////////////////////////////////////////// 
// CProxySocket member functions 
 
BOOL CProxySocket::ProxyConnect(CString addr, unsigned short port,  
								CString proxyaddr, LONG proxyport, 
								CString User, CString Pass, int mode) 
{ 
	BOOL bRet = FALSE; 
	in_addr sa; 
	m_mode = mode; 
 
	m_strServer = proxyaddr; 
	m_strRemote = addr; 
	m_nPort = (unsigned short)proxyport; 
	m_nPortRemote = port; 
	m_strUser = User; 
	m_strPass = Pass; 
 
	bRet = Connect(proxyaddr, proxyport); 
	if(!bRet){ 
		TRACE("Cann't connect to the proxy server!\n"); 
		return FALSE; 
	} 
	char send[3]; 
 
	m_strSend.Empty(); 
	m_strSend = _T(""); 
 
	send[0] = SOCKS_VER; 
	send[1] = 0x01; 
	send[2] = METHOD_AUTH; 
 
	int num = Send(send, 3); 
	if(num != 3){ 
		TRACE("Send negotiate command error!\n"); 
		return FALSE; 
	} 
	char szReadBuf[BUFF_SIZE]; 
 
	memset(szReadBuf, 0, BUFF_SIZE); 
	num = Receive(szReadBuf, BUFF_SIZE); 
	if(num == 0){ 
		TRACE("Maybe the server is not properly open!\n"); 
		return FALSE; 
	} 
	if(szReadBuf[0] == SOCKS_VER && szReadBuf[1] == METHOD_AUTH){ 
		m_strSend += (char)1; 
		m_strSend += (char)User.GetLength(); 
		m_strSend += User; 
		m_strSend += (char)Pass.GetLength(); 
		m_strSend += Pass; 
		int len =m_strSend.GetLength(); 
		char* p = m_strSend.GetBuffer(0); 
		num = Send(p, len); 
		m_strSend.ReleaseBuffer(); 
		if(num == 0){ 
			TRACE("Send Authority negotiate command error!\n"); 
			return FALSE; 
		} 
		memset(szReadBuf, 0, BUFF_SIZE); 
		num = Receive(szReadBuf, BUFF_SIZE); 
		if(num == SOCKET_ERROR || num == 0){ 
			TRACE("error:%d\n", GetLastError()); 
			return FALSE; 
		} 
		if(szReadBuf[0] != 1 || szReadBuf[1] != 0){ 
			AfxMessageBox("Your Username or Password is invalid!"); 
			return FALSE; 
		} 
		unsigned short pt = htons(port); 
		TRACE("The server has passed your authoritory!\n"); 
		memset(szReadBuf, 0, BUFF_SIZE); 
		szReadBuf[0] = SOCKS_VER; 
		szReadBuf[1] = mode;//CMD_CONNECT; 
		szReadBuf[2] = FIELD_RSV; 
		sa = GetIpByHost(addr.GetBuffer(0)); 
		addr.ReleaseBuffer(0); 
		if(sa.s_addr != INADDR_NONE){ 
			szReadBuf[3] = ATYP_IPV4; 
			memcpy(szReadBuf + 4, &sa, 4); 
			memcpy(szReadBuf + 8, &pt, 2); 
			len = 10; 
		} 
		else{ 
			szReadBuf[3] = ATYP_DOMAINNAME; 
			len = szReadBuf[4] = addr.GetLength(); 
			memcpy(szReadBuf + 5, addr.GetBuffer(0), szReadBuf[4]); 
			addr.ReleaseBuffer(); 
			memcpy(szReadBuf + len + 5, &pt, 2); 
			len = len + 7; 
		} 
		num = Send(szReadBuf, len); 
		if(num == 0){ 
			TRACE("Send Authority negotiate command error!\n"); 
			return FALSE; 
		} 
		memset(szReadBuf, 0, BUFF_SIZE); 
		num = Receive(szReadBuf, BUFF_SIZE, 0); 
		if(num == SOCKET_ERROR || num == 0){ 
			TRACE("Connection to remote host error!\n"); 
			return FALSE; 
		} 
		if(szReadBuf[1] != REP_SUCCESS){ 
			TRACE("Connect to remote address failed,error code:%d\n", szReadBuf[1]); 
			return FALSE; 
		} 
	} 
	return TRUE; 
} 
 
struct in_addr CProxySocket::GetIpByHost(char *szHost) 
{ 
	struct in_addr in; 
	if (szHost == NULL) 
	{ 
		in.s_addr = INADDR_NONE; 
	} 
	else 
	{ 
		unsigned long addr = inet_addr(szHost); 
		if (addr == INADDR_NONE) 
		{ 
			LPHOSTENT lphost; 
			lphost = gethostbyname(szHost); 
			if (lphost != NULL) 
				in = *(LPIN_ADDR)*(lphost->h_addr_list); 
			else 
				in.s_addr = INADDR_NONE; 
		} 
		else 
			in.s_addr = addr; 
	} 
	return in; 
} 
 
BOOL CProxySocket::ProxyListen() 
{ 
	int num = 0; 
	char szReadBuf[BUFF_SIZE]; 
	memset(szReadBuf, 0, BUFF_SIZE); 
 
	if(m_mode == CMD_BIND){ 
		while(1){ 
			num = Receive(szReadBuf, BUFF_SIZE); 
			if(szReadBuf[1] != REP_SUCCESS){ 
				TRACE("Connect to remote address failed!\n"); 
				return FALSE; 
			} 
			if(szReadBuf[1] == REP_SUCCESS) 
				break; 
		} 
	} 
	else{ 
		TRACE("This function can only called by bind socket,else will cause failure!\n"); 
		return FALSE; 
	} 
	return TRUE; 
} 
 
BOOL CProxySocket::ProxyAccept(CAsyncProxySocket &rConnectedSock,  
							   SOCKADDR *lpSockAddr, int *lpSockAddrLen) 
{ 
	rConnectedSock.m_mode = m_mode; 
	rConnectedSock.m_nPort = m_nPort; 
	rConnectedSock.m_nPortRemote = m_nPortRemote; 
	rConnectedSock.m_strPass = m_strPass; 
	rConnectedSock.m_strRemote = m_strRemote; 
	rConnectedSock.m_strSend = m_strSend; 
	rConnectedSock.m_strUser = m_strUser; 
	 
	//return Accept(rConnectedSock, lpSockAddr, lpSockAddrLen); 
	rConnectedSock.m_hSocket = m_hSocket; 
	return TRUE; 
}