📄 asyncproxysocketlayer.cpp
字号:
return;
}
//Send authentication
LPCSTR lpszAsciiUser = m_ProxyData.pProxyUser;
LPCSTR lpszAsciiPass = m_ProxyData.pProxyPass;
ASSERT(strlen(lpszAsciiUser)<=255);
ASSERT(strlen(lpszAsciiPass)<=255);
unsigned char *buffer = new unsigned char[3 + (lpszAsciiUser?strlen(lpszAsciiUser):0) + (lpszAsciiPass?strlen(lpszAsciiPass):0) + 1];
sprintf((char *)buffer, " %s %s", lpszAsciiUser?lpszAsciiUser:"", lpszAsciiPass?lpszAsciiPass:"");
buffer[0]=5;
buffer[1]=static_cast<unsigned char>(strlen(lpszAsciiUser));
buffer[2+strlen(lpszAsciiUser)]=static_cast<unsigned char>(strlen(lpszAsciiPass));
int len=3+strlen(lpszAsciiUser)+strlen(lpszAsciiPass);
int res=SendNext(buffer,len);
delete [] buffer;
if (res==SOCKET_ERROR || res<len)
{
if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
else
TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
Reset();
return;
}
}
ClearBuffer();
m_nProxyOpState++;
return;
}
}
//No auth needed
//Send connection request
USES_CONVERSION;
LPCSTR lpszAsciiHost = m_pProxyPeerHost ? T2A(m_pProxyPeerHost) : "";
char *command=new char[10+strlen(lpszAsciiHost)+1];
memset(command,0,10+strlen(lpszAsciiHost)+1);
command[0]=5;
command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
command[2]=0;
command[3]=m_nProxyPeerIp?1:3;
int len=4;
if (m_nProxyPeerIp)
{
memcpy(&command[len],&m_nProxyPeerIp,4);
len+=4;
}
else
{
command[len]=strlen(lpszAsciiHost);
strcpy(&command[len+1],lpszAsciiHost);
len+=strlen(lpszAsciiHost)+1;
}
memcpy(&command[len],&m_nProxyPeerPort,2);
len+=2;
int res=SendNext(command,len);
delete [] command;
if (res==SOCKET_ERROR || res<len)
{
if ( ( WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
else
TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
Reset();
return;
}
}
m_nProxyOpState+=2;
ClearBuffer();
return;
}
else if (m_nProxyOpState==2)
{//Response to the auth request
if (!m_pRecvBuffer)
m_pRecvBuffer=new char[2];
int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 2-m_nRecvBufferPos);
if (numread==SOCKET_ERROR)
{
if (WSAGetLastError()!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
else
TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
Reset();
}
return;
}
m_nRecvBufferPos+=numread;
if (m_nRecvBufferPos==2)
{
if (m_pRecvBuffer[1]!=0)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
else
TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
Reset();
ClearBuffer();
return;
}
USES_CONVERSION;
LPCSTR lpszAsciiHost = m_pProxyPeerHost ? T2A(m_pProxyPeerHost) : "";
char *command=new char[10+strlen(lpszAsciiHost)+1];
memset(command,0,10+strlen(lpszAsciiHost)+1);
command[0]=5;
command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
command[2]=0;
command[3]=m_nProxyPeerIp?1:3;
int len=4;
if (m_nProxyPeerIp)
{
memcpy(&command[len],&m_nProxyPeerIp,4);
len+=4;
}
else
{
command[len]=strlen(lpszAsciiHost);
strcpy(&command[len+1],lpszAsciiHost);
len+=strlen(lpszAsciiHost)+1;
}
memcpy(&command[len],&m_nProxyPeerPort,2);
len+=2;
int res=SendNext(command,len);
delete [] command;
if (res==SOCKET_ERROR || res<len)
{
if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
else
TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
Reset();
return;
}
}
m_nProxyOpState++;
ClearBuffer();
return;
}
}
else if (m_nProxyOpState==3)
{//Response to the connection request
if (!m_pRecvBuffer)
{
m_pRecvBuffer=new char[10];
m_nRecvBufferLen=5;
}
int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,m_nRecvBufferLen-m_nRecvBufferPos);
if (numread==SOCKET_ERROR)
{
if (WSAGetLastError()!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
else
TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
Reset();
}
return;
}
m_nRecvBufferPos+=numread;
if (m_nRecvBufferPos==m_nRecvBufferLen)
{
//Check for errors
if (m_pRecvBuffer[1]!=0 || m_pRecvBuffer[0]!=5)
{
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;
}
if (m_nRecvBufferLen==5)
{ //Check which kind of address the response contains
if (m_pRecvBuffer[3]==1)
m_nRecvBufferLen=10;
else
{
char *tmp=new char[m_nRecvBufferLen+=m_pRecvBuffer[4]+2];
memcpy(tmp,m_pRecvBuffer,5);
delete [] m_pRecvBuffer;
m_pRecvBuffer=tmp;
m_nRecvBufferLen+=m_pRecvBuffer[4]+2;
}
return;
}
if (m_nProxyOpID==PROXYOP_CONNECT)
{
//OK, we are connected with the remote server
Reset();
ClearBuffer();
TriggerEvent(FD_CONNECT, 0, TRUE);
TriggerEvent(FD_READ, 0, TRUE);
TriggerEvent(FD_WRITE, 0, TRUE);
}
else
{
//Listen socket created
m_nProxyOpState++;
unsigned long ip;
int port;
ASSERT(m_pRecvBuffer[3]==1);
memcpy(&ip,&m_pRecvBuffer[4],4);
memcpy(&port,&m_pRecvBuffer[8],2);
t_ListenSocketCreatedStruct data;
data.ip=ip;
data.nPort=port;
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
}
ClearBuffer();
}
}
else if (m_nProxyOpState==4)
{
if (!m_pRecvBuffer)
m_pRecvBuffer=new char[10];
int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,10-m_nRecvBufferPos);
if (numread==SOCKET_ERROR)
{
if (WSAGetLastError()!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
else
TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
Reset();
}
return;
}
m_nRecvBufferPos+=numread;
if (m_nRecvBufferPos==10)
{
if (m_pRecvBuffer[1]!=0)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
if (m_nProxyOpID==PROXYOP_CONNECT)
TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
else
{
VERIFY(m_nProxyOpID==PROXYOP_LISTEN);
TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
}
Reset();
ClearBuffer();
return;
}
//Connection to remote server established
ClearBuffer();
Reset();
TriggerEvent(FD_ACCEPT, 0, TRUE);
TriggerEvent(FD_READ, 0, TRUE);
TriggerEvent(FD_WRITE, 0, TRUE);
}
}
}
if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
{
ASSERT (m_nProxyOpID==PROXYOP_CONNECT);
char buffer[9]={0};
for(;;)
{
int numread = ReceiveNext(buffer, m_pStrBuffer?1:8);
if (numread==SOCKET_ERROR)
{
int nError=WSAGetLastError();
if (nError!=WSAEWOULDBLOCK)
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
Reset();
ClearBuffer();
TriggerEvent(FD_CONNECT, nError, TRUE );
}
return;
}
//Response begins with HTTP/
if (!m_pStrBuffer)
{
m_pStrBuffer = new char[strlen(buffer) + 1];
strcpy(m_pStrBuffer, buffer);
}
else
{
char *tmp = m_pStrBuffer;
m_pStrBuffer = new char[strlen(tmp) + strlen(buffer) + 1];
strcpy(m_pStrBuffer, tmp);
strcpy(m_pStrBuffer + strlen(tmp), buffer);
delete [] tmp;
}
memset(buffer, 0, 9);
const char start[] = "HTTP/";
if (memcmp(start, m_pStrBuffer, (strlen(start)>strlen(m_pStrBuffer)) ? strlen(m_pStrBuffer) : strlen(start)))
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, (int)_T("No valid HTTP reponse"));
Reset();
ClearBuffer();
TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE );
return;
}
char *pos = strstr(m_pStrBuffer, "\r\n");
if (pos)
{
char *pos2 = strstr(m_pStrBuffer, " ");
if (!pos2 || *(pos2+1)!='2' || pos2>pos)
{
char *tmp = new char[pos-m_pStrBuffer + 1];
tmp[pos-m_pStrBuffer] = 0;
strncpy(tmp, m_pStrBuffer, pos-m_pStrBuffer);
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, (int)tmp);
delete [] tmp;
Reset();
ClearBuffer();
TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE );
return;
}
}
if (strlen(m_pStrBuffer)>3 && !memcmp(m_pStrBuffer+strlen(m_pStrBuffer)-4, "\r\n\r\n", 4)) //End of the HTTP header
{
Reset();
ClearBuffer();
TriggerEvent(FD_CONNECT, 0, TRUE);
TriggerEvent(FD_READ, 0, TRUE);
TriggerEvent(FD_WRITE, 0, TRUE);
return;
}
}
}
}
BOOL CAsyncProxySocketLayer::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
{
if (!m_ProxyData.nProxyType)
//Connect normally because there is no proxy
return ConnectNext(lpszHostAddress, nHostPort);
USES_CONVERSION;
//Translate the host address
ASSERT(lpszHostAddress != NULL);
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
LPCSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
sockAddr.sin_family = AF_INET;
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
//Can't resolve hostname
if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A ||
m_ProxyData.nProxyType==PROXYTYPE_SOCKS5 ||
m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
{ //Can send domain names to proxy
//Conect 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=htons((u_short)nHostPort);
m_nProxyPeerIp=0;
delete [] m_pProxyPeerHost;
m_pProxyPeerHost = NULL; // 'new' may throw an exception
m_pProxyPeerHost = new TCHAR[_tcslen(lpszHostAddress)+1];
_tcscpy(m_pProxyPeerHost, lpszHostAddress);
m_nProxyOpID=PROXYOP_CONNECT;
return TRUE;
}
else
{
DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_CANTRESOLVEHOST, 0);
WSASetLastError(WSAEINVAL);
return FALSE;
}
}
}
sockAddr.sin_port = htons((u_short)nHostPort);
BOOL res=CAsyncProxySocketLayer::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
if (res || WSAGetLastError()==WSAEWOULDBLOCK)
{
delete [] m_pProxyPeerHost;
m_pProxyPeerHost = NULL; // 'new' may throw an exception
m_pProxyPeerHost = new TCHAR[_tcslen(lpszHostAddress)+1];
_tcscpy(m_pProxyPeerHost, lpszHostAddress);
}
return res;
}
BOOL CAsyncProxySocketLayer::Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen )
{
if (!m_ProxyData.nProxyType)
//Connect normally because there is no proxy
return ConnectNext(lpSockAddr, nSockAddrLen );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -