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

📄 asyncproxysocketlayer.cpp

📁 另外一款开放源码的高质量p2p源码软件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
						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 + -