⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxyconnectsocket.cpp

📁 DarkATLSmtp(SMTP COM 组件原创代码),注册后可在Delphi中发邮件。
💻 CPP
字号:
// ProxyConnectSocket.cpp: implementation of the CProxyConnectSocket class.
//作者:高越 邮箱:darkprince@v.cn
//QQ:1738387 (本人只接受技术探讨以及软件项目合作事宜,其他误扰)
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ProxyConnectSocket.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//CProxyConnectSocket Class Construction
CProxyConnectSocket::CProxyConnectSocket()
{
	m_pBSD= NULL;
}

//Destruction Function
CProxyConnectSocket::~CProxyConnectSocket()
{

}

//Purpose: Create Socket For Connection And Connect Far Host.
//If User Need A Proxy,That We Will Connect To Proxy First.
SOCKET CProxyConnectSocket::CreateConnectSocket(LPTAG_CONNECTINFO pConnectInfo,
												DWORD& dwErrorCode)
{
	if(pConnectInfo==NULL)
		return 0;
	SOCKET hConnect=0;
	hConnect = DPCreateSocket(AF_INET,SOCK_STREAM,0);
	if(hConnect == INVALID_SOCKET)
		return 0;
	//Alloc Some Mem For Connect Proxy
	m_pBSD = DPBSocketAttach(hConnect,READ_BUFFER_SIZE);
	if( m_pBSD == NULL )
		return 0;
	BOOL bResult=FALSE;
	switch(pConnectInfo->nProxyType)
	{
		case PROXYTYPE_NONE:
			bResult=DoConnectByNone(pConnectInfo,hConnect,dwErrorCode);
			break;
		case PROXYTYPE_HTTPGET:
			bResult=DoConnectByHttpGet(pConnectInfo,hConnect,dwErrorCode);
			break;
		//case PROXYTYPE_HTTPCONNECT:
		//	bResult=DoConnectByHttpConnect(pConnectInfo,hConnect,dwErrorCode);
		//	break;
		case PROXYTYPE_SOCKS4:
			bResult=DoConnectBySocks4(pConnectInfo,hConnect,dwErrorCode);
			break;
		case PROXYTYPE_SOCKS4A:
			bResult=DoConnectBySocks4a(pConnectInfo,hConnect,dwErrorCode);
			break;
		case PROXYTYPE_SOCKS5:
			bResult=DoConnectBySocks5(pConnectInfo,hConnect,dwErrorCode);
			break;
		case PROXYTYPE_FTPSITE:
		case PROXYTYPE_FTPOPEN:
		case PROXYTYPE_FTPTRANSPARENT: //Transparent
		case PROXYTYPE_FTPUSERAFTERLOGON: //USER after logon
		case PROXYTYPE_FTPUSERNOLOGON: //USER with no logon
		case PROXYTYPE_FTPUSERFIREID: //USER fireID@remotehost
		case PROXYTYPE_FTPUSERREMOTEID: //USER remoteID@remotehost fireID
		case PROXYTYPE_FTPUSERREMOTEIDFIREID:// USER remoteID@fireID@remotehost
			bResult=DoConnectByFtp(pConnectInfo,hConnect,dwErrorCode);
			break;
	}
	//If bResult equal FALSE That Proved To Connect Far Server Failed Or Proxy Failed.
	if(!bResult)
	{
		//Free Some Mems That We Before Connect Proxy Alloc These. 
		DPBSocketDetach(m_pBSD,TRUE);
		return 0;//Return A Socket Of Null
	}
	DPBSocketDetach(m_pBSD,FALSE);
	return hConnect;
}

BOOL CProxyConnectSocket::DoConnectByFtp(LPTAG_CONNECTINFO pConnectInfo,
	SOCKET hConnect,DWORD& dwErrorCode)
{
	dwErrorCode=ERR_CONNECT_SYSTEM;
	if(pConnectInfo==NULL||hConnect==0||hConnect==INVALID_SOCKET)
		return FALSE;
	//Use SocketModel's Connect Function By Event To Connect
	if(CDPSocketModel::DPConnectEx_Event(hConnect,pConnectInfo->strProxyIp,
		pConnectInfo->nProxyPort,pConnectInfo->dwTimeOut,TRUE)==SOCKET_ERROR)
	{
		dwErrorCode=ERR_CONNECT_PROXY;
		return FALSE;
	}
	dwErrorCode=ERR_CONNECT_SUCCESS;
	return TRUE;
}


//Purpose: If We Are Need't Proxy That Direct Connect Far Server.
BOOL CProxyConnectSocket::DoConnectByNone(LPTAG_CONNECTINFO pConnectInfo,
										  SOCKET hConnect,DWORD& dwErrorCode)
{
	dwErrorCode=ERR_CONNECT_SYSTEM;
	if(pConnectInfo==NULL||hConnect==0||hConnect==INVALID_SOCKET)
		return FALSE;
	//Use SocketModel's Connect Function By Event To Connect
	if(CDPSocketModel::DPConnectEx_Event(hConnect,pConnectInfo->strServerIp,
		pConnectInfo->nServerPort,pConnectInfo->dwTimeOut,TRUE)==SOCKET_ERROR)
	{
		dwErrorCode=ERR_CONNECT_HOST;
		return FALSE;
	}
	dwErrorCode=ERR_CONNECT_SUCCESS;
	return TRUE;
}

BOOL CProxyConnectSocket::DoConnectByHttpGet(LPTAG_CONNECTINFO pConnectInfo,
											 SOCKET hConnect,DWORD& dwErrorCode)
{
	dwErrorCode=ERR_CONNECT_SYSTEM;
	if(pConnectInfo==NULL||hConnect==0||hConnect==INVALID_SOCKET)
		return FALSE;
	//Use SocketModel's Connect Function By Event To Connect
	if(CDPSocketModel::DPConnectEx_Event(hConnect,pConnectInfo->strProxyIp,
		pConnectInfo->nProxyPort,pConnectInfo->dwTimeOut,TRUE)==SOCKET_ERROR)
	{
		dwErrorCode=ERR_CONNECT_PROXY;
		return FALSE;
	}
	dwErrorCode=ERR_CONNECT_SUCCESS;
	return TRUE;
}

BOOL CProxyConnectSocket::DoConnectByHttpConnect(LPTAG_CONNECTINFO pConnectInfo,
												 SOCKET hConnect,DWORD& dwErrorCode)
{
	dwErrorCode=ERR_CONNECT_NOTSUSTAIN;
	return FALSE;
}

//Connect To Far Host That Use Socks4 Protocol Connect Proxy First.
BOOL CProxyConnectSocket::DoConnectBySocks4(LPTAG_CONNECTINFO pConnectInfo,
											SOCKET hConnect,DWORD& dwErrorCode)
{
	dwErrorCode=ERR_CONNECT_SYSTEM;
	if(pConnectInfo==NULL||hConnect==0||hConnect==INVALID_SOCKET)
		return FALSE;
	dwErrorCode=ERR_CONNECT_PROXY;
	TAG_SOCKSREPPACKET	pack;
	//It Must Gained ServerIP By Socks4 Protocol.
	DWORD dwServerIp=DPGetIP(pConnectInfo->strServerIp,TRUE);
	//If DNS Failed
	if( dwServerIp == INADDR_NONE )
		return FALSE;
	//We Connect To Proxy
	if( CDPSocketModel::DPConnectEx_Event(hConnect,pConnectInfo->strProxyIp,
		pConnectInfo->nProxyPort,pConnectInfo->dwTimeOut,TRUE) == SOCKET_ERROR )
		return FALSE;
	//Send Socks Request To Proxy
	if( SOP_SendSocks4Req(hConnect,CMD_CONNECT,pConnectInfo->nServerPort,
		dwServerIp,pConnectInfo->strUserName,pConnectInfo->dwTimeOut) == SOCKET_ERROR )
		return FALSE;
	//Init Buffer For Proxy Reply
	ZeroMemory(&pack,sizeof(TAG_SOCKSREPPACKET));
	dwErrorCode=ERR_CONNECT_HOST;
	//Recv Data By Socks4
	if( SOP_RecvPacket(m_pBSD,&pack,PACKET_SOCKS4REP,pConnectInfo->dwTimeOut)
		== SOCKET_ERROR )
		return FALSE;
	//Judge Recv Packet Are Right.
	if( !SOP_IsSocksOK(&pack,PACKET_SOCKS4REP) )
		return FALSE;
	dwErrorCode=ERR_CONNECT_SUCCESS;
	return TRUE;
}

//Connect To Far Host That Use Socks4a Proto For Connect Proxy First
BOOL CProxyConnectSocket::DoConnectBySocks4a(LPTAG_CONNECTINFO pConnectInfo,
											 SOCKET hConnect,DWORD& dwErrorCode)
{
	dwErrorCode=ERR_CONNECT_SYSTEM;
	if(pConnectInfo==NULL||hConnect==0||hConnect==INVALID_SOCKET)
		return FALSE;
	dwErrorCode=ERR_CONNECT_PROXY;
	TAG_SOCKSREPPACKET	pack;
	//Get Far Host's IP,But Socks4A Not Always Need IP,
	//If pConnectInfo->strServerIp Is True IP,That Redirect DoConnectBySocks4 To Do It.
	DWORD dwServerIp=DPGetIP(pConnectInfo->strServerIp,TRUE);
	//If pConnectInfo->strServerIp Is't A True IP. So Just Use Under Course.
	if( dwServerIp == INADDR_NONE )
	{
		if(CDPSocketModel::DPConnectEx_Event(hConnect,pConnectInfo->strProxyIp,
			pConnectInfo->nProxyPort,pConnectInfo->dwTimeOut,TRUE)==SOCKET_ERROR)
			return FALSE;
		if( SOP_SendSocks4aReq(hConnect,CMD_CONNECT,pConnectInfo->nServerPort,
			pConnectInfo->strServerIp,pConnectInfo->strUserName,
			pConnectInfo->dwTimeOut) == SOCKET_ERROR )
			return FALSE;
		ZeroMemory(&pack,sizeof(LPTAG_SOCKSREPPACKET));
		dwErrorCode=ERR_CONNECT_HOST;
		if( SOP_RecvPacket(m_pBSD,&pack,PACKET_SOCKS4AREP,
			pConnectInfo->dwTimeOut)==SOCKET_ERROR )
			return FALSE;
		if( !SOP_IsSocksOK(&pack,PACKET_SOCKS4AREP) )
			return FALSE;
		dwErrorCode=ERR_CONNECT_SUCCESS;
		return TRUE;
	}
	return(DoConnectBySocks4(pConnectInfo,hConnect,dwErrorCode));
}

//Purpose: Connect To Far Host That Use Socks5 Connect Proxy First.
//Input: LPTAG_CONNECTINFO struct, Socket For Connect
//Output: TRUE/FALSE,Successful return True.
BOOL CProxyConnectSocket::DoConnectBySocks5(LPTAG_CONNECTINFO pConnectInfo,
											SOCKET hConnect,DWORD& dwErrorCode)
{
	dwErrorCode=ERR_CONNECT_SYSTEM;
	if(pConnectInfo==NULL||hConnect==0||hConnect==INVALID_SOCKET)
		return FALSE;
	dwErrorCode=ERR_CONNECT_PROXY;
	TAG_SOCKSREPPACKET	pack;
	if( CDPSocketModel::DPConnectEx_Event(hConnect,pConnectInfo->strProxyIp,
		pConnectInfo->nProxyPort,pConnectInfo->dwTimeOut,TRUE) == SOCKET_ERROR)
		return FALSE;

	CString strAuth;
	if(pConnectInfo->bNeedAuth)
	{
		//Judge User struct First Two Bytes Must Is 0x00 And 0x02
		strAuth =  _T("");
		char c	= (char)AUTH_NONE;
		strAuth += c;
		c 		= (char)AUTH_PASSWD;
		strAuth += c;
	}
	else
	{
		//Need't Judge User's Identity That The First Byte Must Be 0x00.
		char c	= (char)AUTH_NONE;
		strAuth =  _T("");
		strAuth += c;
	}
	//Get Length Of strAuth,In order to tell Proxy That We will use number of methods.
	//About that more infomation please look over RFC1928
	BYTE bAuth =(BYTE)strAuth.GetLength();
	if( SOP_SendSocks5AuthReq(hConnect,bAuth,(LPCTSTR)strAuth,pConnectInfo->dwTimeOut)
		== SOCKET_ERROR )
		return FALSE;

	//Init Packet That is Result For Socks5 Recv.
	dwErrorCode=ERR_CONNECT_PROXYAUTH;
	ZeroMemory(&pack,sizeof(TAG_SOCKSREPPACKET));
	if( SOP_RecvPacket(m_pBSD,&pack,PACKET_SOCKS5AUTHREP,pConnectInfo->dwTimeOut)
		== SOCKET_ERROR )
		return FALSE;
	//Judge The Return Packets Are Aright.
	if( !SOP_IsSocksOK(&pack,PACKET_SOCKS5AUTHREP) )
		return FALSE;
	//Analyze The Packet Of Recv.
	switch( pack.socks5AuthRep.bAuth )
	{
	case AUTH_NONE:
		break;
	case AUTH_PASSWD: //If Proxy Allow Use Validate User That..
		if(!pConnectInfo->bNeedAuth)
			return FALSE;
		//Send Auth Validate Packet.
		if( SOP_SendSocks5AuthPasswdReq(hConnect,pConnectInfo->strUserName,
			pConnectInfo->strPassWord,pConnectInfo->dwTimeOut) == SOCKET_ERROR)
			return FALSE;
		ZeroMemory(&pack,sizeof(TAG_SOCKSREPPACKET));
		if( SOP_RecvPacket(m_pBSD,&pack,PACKET_SOCKS5AUTHPASSWDREP,pConnectInfo->dwTimeOut)
			== SOCKET_ERROR )
			return FALSE;
		//Judge The Packet Of Recv True Or False
		if( !SOP_IsSocksOK(&pack,PACKET_SOCKS5AUTHPASSWDREP) )
			return FALSE;
		break;
	case AUTH_GSSAPI:
	case AUTH_CHAP:
	case AUTH_UNKNOWN:
	default:
		return FALSE;
		break;
	}
	BYTE bAtyp=0;
	CString strAddr="";
	DWORD dwServerIp=DPGetIP(pConnectInfo->strServerIp,TRUE);
	//If Server Addr Is True IP
	if( dwServerIp != INADDR_NONE )
	{
		bAtyp = ATYP_IPV4ADDR;
		strAddr = _T("");
		//conversion Order of Byte.
		dwServerIp = htonl(dwServerIp);
		strAddr += (char)( (dwServerIp>>24) &0x000000ff); 
		strAddr += (char)( (dwServerIp>>16) &0x000000ff); 
		strAddr += (char)( (dwServerIp>>8 ) &0x000000ff); 
		strAddr += (char)( dwServerIp &0x000000ff); 
	}
	else//Direct use Host Name
	{
		bAtyp = ATYP_HOSTNAME;
		char c = (char)pConnectInfo->strServerIp.GetLength();
		strAddr  = _T("");
		strAddr += c;
		strAddr += pConnectInfo->strUserName;
	}
	dwErrorCode=ERR_CONNECT_HOST;
	//Send These Data.
	if( SOP_SendSocks5Req(hConnect,CMD_CONNECT,bAtyp,(LPCTSTR)strAddr,
		pConnectInfo->nServerPort,pConnectInfo->dwTimeOut) == SOCKET_ERROR )
		return FALSE;

	ZeroMemory(&pack,sizeof(TAG_SOCKSREPPACKET));
	if( SOP_RecvPacket(m_pBSD,&pack,PACKET_SOCKS5REP,pConnectInfo->dwTimeOut)
		==SOCKET_ERROR )
		return FALSE;
	//Judge Packet of Recv.
	if( !SOP_IsSocksOK(&pack,PACKET_SOCKS5REP) )
		return FALSE;
	dwErrorCode=ERR_CONNECT_SUCCESS;	
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -