📄 asyncproxysocketlayer.cpp
字号:
LPSOCKADDR_IN sockAddr=(LPSOCKADDR_IN)lpSockAddr;
//Save server details
m_nProxyPeerIp=sockAddr->sin_addr.S_un.S_addr;
m_nProxyPeerPort=sockAddr->sin_port;
delete [] m_pProxyPeerHost;
m_pProxyPeerHost = NULL;
m_nProxyOpID=PROXYOP_CONNECT;
BOOL res = ConnectNext(m_ProxyData.pProxyHost, m_ProxyData.nProxyPort);
if (!res)
{
if (WSAGetLastError()!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, WSAGetLastError());
return FALSE;
}
}
return res;
}
void CAsyncProxySocketLayer::OnConnect(int nErrorCode)
{
if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
{
TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
return;
}
ASSERT(m_nProxyOpID);
if (!m_nProxyOpID)
{
//This should not happen
return;
};
if (nErrorCode)
{ //Can't connect to proxy
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, nErrorCode);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
else
TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
Reset();
ClearBuffer();
return;
}
if (m_nProxyOpID==PROXYOP_CONNECT || m_nProxyOpID==PROXYOP_LISTEN)
{
if (m_nProxyOpState)
//Somehow OnConnect has been called more than once
return;
ASSERT(m_ProxyData.nProxyType!=PROXYTYPE_NOPROXY);
ClearBuffer();
//Send the initial request
if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
{ //SOCKS4 proxy
//Send request
USES_CONVERSION;
LPCSTR lpszAscii = m_pProxyPeerHost ? T2A(m_pProxyPeerHost) : "";
char *command=new char [9+strlen(lpszAscii)+1];
memset(command,0,9+strlen(lpszAscii)+1);
int len=9;
command[0]=4;
command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2; //CONNECT or BIND request
memcpy(&command[2],&m_nProxyPeerPort,2); //Copy target address
if (!m_nProxyPeerIp)
{
ASSERT(m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A);
ASSERT(strcmp(lpszAscii, ""));
//Set the IP to 0.0.0.x (x is nonzero)
command[4]=0;
command[5]=0;
command[6]=0;
command[7]=1;
//Add host as URL
strcpy(&command[9],lpszAscii);
len+=strlen(lpszAscii)+1;
}
else
memcpy(&command[4],&m_nProxyPeerIp,4);
int res=SendNext(command,len); //Send command
delete [] command;
int nErrorCode=WSAGetLastError();
if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
else
TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
Reset();
ClearBuffer();
return;
}
else if (res<len)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
else
TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
Reset();
ClearBuffer();
return;
}
}
else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
{ //SOCKS5 proxy
//Send initialization request
unsigned char command[10];
memset(command,0,10);
command[0]=5;
//CAsyncProxySocketLayer supports to logon types: No logon and
//cleartext username/password (if set) logon
command[1]=m_ProxyData.bUseLogon?2:1; //Number of logon types
command[2]=m_ProxyData.bUseLogon?2:0; //2=user/pass, 0=no logon
int len=m_ProxyData.bUseLogon?4:3; //length of request
int res=SendNext(command,len);
int nErrorCode=WSAGetLastError();
if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
else
TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
Reset();
ClearBuffer();
return;
}
else if (res<len)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
else
TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
Reset();
ClearBuffer();
return;
}
}
else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
{
char str[4096]; //This should be large enough
char * pHost = NULL;
if (m_pProxyPeerHost && *m_pProxyPeerHost)
{
USES_CONVERSION;
pHost = new char[_tcslen(m_pProxyPeerHost)*2+1];
strcpy(pHost, T2A(m_pProxyPeerHost));
}
else
{
pHost = new char[16];
sprintf(pHost, "%d.%d.%d.%d", m_nProxyPeerIp%256, (m_nProxyPeerIp>>8) % 256, (m_nProxyPeerIp>>16) %256, m_nProxyPeerIp>>24);
}
if (!m_ProxyData.bUseLogon)
sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", pHost, ntohs(m_nProxyPeerPort),
pHost, ntohs(m_nProxyPeerPort));
else
{
sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", pHost, ntohs(m_nProxyPeerPort),
pHost, ntohs(m_nProxyPeerPort));
char userpass[4096];
sprintf(userpass, "%s:%s", m_ProxyData.pProxyUser?m_ProxyData.pProxyUser:"", m_ProxyData.pProxyPass?m_ProxyData.pProxyPass:"");
char base64str[4096];
CBase64Coding base64coding;
if (!base64coding.Encode(userpass, strlen(userpass), base64str))
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
else
TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
Reset();
ClearBuffer();
delete [] pHost;
return;
}
strcat(str, "Authorization: Basic ");
strcat(str, base64str);
strcat(str, "\r\nProxy-Authorization: Basic ");
strcat(str, base64str);
strcat(str, "\r\n\r\n");
}
delete [] pHost;
int numsent=SendNext(str, strlen(str) );
int nErrorCode=WSAGetLastError();
if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
else
TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
Reset();
ClearBuffer();
return;
}
else if ( numsent < static_cast<int>( strlen(str) ) )
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
else
TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
Reset();
ClearBuffer();
return;
}
m_nProxyOpState++;
return;
}
else
ASSERT(FALSE);
//Now we'll wait for the response, handled in OnReceive
m_nProxyOpState++;
}
}
void CAsyncProxySocketLayer::ClearBuffer()
{
delete [] m_pStrBuffer;
m_pStrBuffer = NULL;
if (m_pRecvBuffer)
{
delete [] m_pRecvBuffer;
m_pRecvBuffer=0;
}
m_nRecvBufferLen=0;
m_nRecvBufferPos=0;
}
BOOL CAsyncProxySocketLayer::Listen( int nConnectionBacklog)
{
if (GetProxyType()==PROXYTYPE_NOPROXY)
return ListenNext(nConnectionBacklog);
//Connect to proxy server
BOOL res=ConnectNext(m_ProxyData.pProxyHost, m_ProxyData.nProxyPort);
if (!res)
{
if (WSAGetLastError()!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, WSAGetLastError());
return FALSE;
}
}
m_nProxyPeerPort=0;
m_nProxyPeerIp=(unsigned int)nConnectionBacklog;
m_nProxyOpID=PROXYOP_LISTEN;
return TRUE;
}
#ifdef _AFX
BOOL CAsyncProxySocketLayer::GetPeerName(CString &rPeerAddress, UINT &rPeerPort)
{
if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
return GetPeerNameNext(rPeerAddress, rPeerPort);
if (GetLayerState()==notsock)
{
WSASetLastError(WSAENOTSOCK);
return FALSE;
}
else if (GetLayerState()!=connected)
{
WSASetLastError(WSAENOTCONN);
return FALSE;
}
else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
{
WSASetLastError(WSAENOTCONN);
return FALSE;
}
ASSERT(m_ProxyData.nProxyType);
BOOL res=GetPeerNameNext( rPeerAddress, rPeerPort );
if (res)
{
rPeerPort=ntohs(m_nProxyPeerPort);
rPeerAddress.Format(_T("%d.%d.%d.%d"), m_nProxyPeerIp%256,(m_nProxyPeerIp>>8)%256,(m_nProxyPeerIp>>16)%256, m_nProxyPeerIp>>24);
}
return res;
}
#endif
BOOL CAsyncProxySocketLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
{
if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
return GetPeerNameNext(lpSockAddr, lpSockAddrLen);
if (GetLayerState()==notsock)
{
WSASetLastError(WSAENOTSOCK);
return FALSE;
}
else if (GetLayerState()!=connected)
{
WSASetLastError(WSAENOTCONN);
return FALSE;
}
else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
{
WSASetLastError(WSAENOTCONN);
return FALSE;
}
ASSERT(m_ProxyData.nProxyType);
BOOL res=GetPeerNameNext(lpSockAddr,lpSockAddrLen);
if (res)
{
LPSOCKADDR_IN addr=(LPSOCKADDR_IN)lpSockAddr;
addr->sin_port=m_nProxyPeerPort;
addr->sin_addr.S_un.S_addr=m_nProxyPeerIp;
}
return res;
}
int CAsyncProxySocketLayer::GetProxyType() const
{
return m_ProxyData.nProxyType;
}
void CAsyncProxySocketLayer::Close()
{
delete [] m_ProxyData.pProxyHost;
delete [] m_ProxyData.pProxyUser;
delete [] m_ProxyData.pProxyPass;
delete [] m_pProxyPeerHost;
m_ProxyData.pProxyHost = NULL;
m_ProxyData.pProxyUser = NULL;
m_ProxyData.pProxyPass = NULL;
m_pProxyPeerHost = NULL;
ClearBuffer();
Reset();
CloseNext();
}
void CAsyncProxySocketLayer::Reset()
{
m_nProxyOpState=0;
m_nProxyOpID=0;
}
int CAsyncProxySocketLayer::Send(const void* lpBuf, int nBufLen, int nFlags)
{
if (m_nProxyOpID)
{
WSASetLastError(WSAEWOULDBLOCK);
return SOCKET_ERROR;
}
return SendNext(lpBuf, nBufLen, nFlags);
}
int CAsyncProxySocketLayer::Receive(void* lpBuf, int nBufLen, int nFlags)
{
if (m_nProxyOpID)
{
WSASetLastError(WSAEWOULDBLOCK);
return SOCKET_ERROR;
}
return ReceiveNext(lpBuf, nBufLen, nFlags);
}
BOOL CAsyncProxySocketLayer::PrepareListen(unsigned long ip)
{
if (GetLayerState()!=notsock && GetLayerState()!=unconnected)
return FALSE;
m_nProxyPeerIp=ip;
return TRUE;
}
BOOL CAsyncProxySocketLayer::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
{
if (!m_ProxyData.nProxyType)
return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);
GetPeerName(lpSockAddr, lpSockAddrLen);
return TRUE;
}
CString GetProxyError(UINT nError)
{
if (nError == PROXYERROR_NOERROR)
return _T("No error");
else if (nError == PROXYERROR_NOCONN)
return _T("Can't connect to proxy server");
else if (nError == PROXYERROR_REQUESTFAILED)
return _T("Request failed, can't send data");
else if (nError == PROXYERROR_AUTHREQUIRED)
return _T("Authentication required");
else if (nError == PROXYERROR_AUTHTYPEUNKNOWN)
return _T("Authtype unknown or not supported");
else if (nError == PROXYERROR_AUTHFAILED)
return _T("Authentication failed");
else if (nError == PROXYERROR_AUTHNOLOGON)
return _T("AuthNoLogon");
else if (nError == PROXYERROR_CANTRESOLVEHOST)
return _T("Can't resolve host");
else if (nError == PROXYSTATUS_LISTENSOCKETCREATED)
return _T("Listen socket created");
else{
CString strError;
strError.Format(_T("Error: %u"), nError);
return strError;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -