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

📄 asyncproxysocketlayer.cpp

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