📄 proxyconnectsocket.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 + -