| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258 | 
							- /*CAsyncProxySocketLayer by Tim Kosse ([email protected])
 
-                  Version 1.6 (2003-03-26)
 
- --------------------------------------------------------
 
- Introduction:
 
- -------------
 
- This class is layer class for CAsyncSocketEx. With this class you
 
- can connect through SOCKS4/5 and HTTP 1.1 proxies. This class works
 
- as semi-transparent layer between CAsyncSocketEx and the actual socket.
 
- This class is used in FileZilla, a powerful open-source FTP client.
 
- It can be found under http://sourceforge.net/projects/filezilla
 
- For more information about SOCKS4/5 goto
 
- http://www.socks.nec.com/socksprot.html
 
- For more information about HTTP 1.1 goto http://www.rfc-editor.org
 
- and search for RFC2616
 
- How to use?
 
- -----------
 
- You don't have to change much in you already existing code to use
 
- CAsyncProxySocketLayer.
 
- To use it, create an instance of CAsyncProxySocketLayer, call SetProxy
 
- and attach it to a CAsyncSocketEx instance.
 
- You have to process OnLayerCallback in you CAsyncSocketEx instance as it will
 
- receive all layer nofications.
 
- The following notifications are sent:
 
- //Error codes
 
- PROXYERROR_NOERROR 0
 
- PROXYERROR_NOCONN 1 //Can't connect to proxy server, use GetLastError for more information
 
- PROXYERROR_REQUESTFAILED 2 //Request failed, can't send data
 
- PROXYERROR_AUTHREQUIRED 3 //Authentication required
 
- PROXYERROR_AUTHTYPEUNKNOWN 4 //Authtype unknown or not supported
 
- PROXYERROR_AUTHFAILED 5  //Authentication failed
 
- PROXYERROR_AUTHNOLOGON 6
 
- PROXYERROR_CANTRESOLVEHOST 7
 
- //Status messages
 
- PROXYSTATUS_LISTENSOCKETCREATED 8 //Called when a listen socket was created successfully. Unlike the normal listen function,
 
- 								//a socksified socket has to connect to the proxy to negotiate the details with the server
 
- 								//on which the listen socket will be created
 
- 								//The two parameters will contain the ip and port of the listen socket on the server.
 
- If you want to use CAsyncProxySocketLayer to create a listen socket, you
 
- have to use this overloaded function:
 
- BOOL PrepareListen(unsigned long serverIp);
 
- serverIP is the IP of the server you are already connected
 
- through the SOCKS proxy. You can't use listen sockets over a
 
- SOCKS proxy without a primary connection. Listen sockets are only
 
- supported by SOCKS proxies, this won't work with HTTP proxies.
 
- When the listen socket is created successfully, the PROXYSTATUS_LISTENSOCKETCREATED
 
- notification is sent. The parameters  will tell you the ip and the port of the listen socket.
 
- After it you have to handle the OnAccept message and accept the
 
- connection.
 
- Be carful when calling Accept: rConnected socket will NOT be filled! Instead use the instance which created the
 
- listen socket, it will handle the data connection.
 
- If you want to accept more than one connection, you have to create a listing socket for each of them!
 
- Description of important functions and their parameters:
 
- --------------------------------------------------------
 
- void SetProxy(int nProxyType);
 
- void SetProxy(int nProxyType, const char * pProxyHost, int nProxyPort);
 
- void SetProxy(int nProxyType, const char * pProxyHost, int nProxyPort, const char *pProxyUser, const char * pProxyPass);
 
- Call one of this functions to set the proxy type.
 
- Parametes:
 
- - nProxyType specifies the Proxy Type.
 
- - ProxyHost and nProxyPort specify the address of the proxy
 
- - ProxyUser and ProxyPass are only available for SOCKS5 proxies.
 
- supported proxy types:
 
- PROXYTYPE_NOPROXY
 
- PROXYTYPE_SOCKS4
 
- PROXYTYPE_SOCKS4A
 
- PROXYTYPE_SOCKS5
 
- PROXYTYPE_HTTP11
 
- There are also some other functions:
 
- GetProxyPeerName
 
- Like GetPeerName of CAsyncSocket, but returns the address of the
 
- server connected through the proxy.	If using proxies, GetPeerName
 
- only returns the address of the proxy.
 
- int GetProxyType();
 
- Returns the used proxy
 
- const int GetLastProxyError() const;
 
- Returns the last proxy error
 
- License
 
- -------
 
- Feel free to use this class, as long as you don't claim that you wrote it
 
- and this copyright notice stays intact in the source files.
 
- If you use this class in commercial applications, please send a short message
 
- to [email protected]
 
- Version history
 
- ---------------
 
- - 1.6 got rid of MFC
 
- - 1.5 released CAsyncSocketExLayer version
 
- - 1.4 added UNICODE support
 
- - 1.3 added basic HTTP1.1 authentication
 
-       fixed memory leak in SOCKS5 code
 
- 	  OnSocksOperationFailed will be called after Socket has been closed
 
-       fixed some minor bugs
 
- - 1.2 renamed into CAsyncProxySocketLayer
 
-       added HTTP1.1 proxy support
 
- - 1.1 fixes all known bugs, mostly with SOCKS5 authentication
 
- - 1.0 initial release
 
- */
 
- #include "stdafx.h"
 
- #include "AsyncProxySocketLayer.h"
 
- #include "atlconv.h" //Unicode<->Ascii conversion macros declared here
 
- #include "CBase64coding.hpp"
 
- #ifdef _DEBUG
 
- #undef THIS_FILE
 
- static char THIS_FILE[]=__FILE__;
 
- #define new DEBUG_NEW
 
- #endif
 
- //////////////////////////////////////////////////////////////////////
 
- // Konstruktion/Destruktion
 
- //////////////////////////////////////////////////////////////////////
 
- CAsyncProxySocketLayer::CAsyncProxySocketLayer()
 
- {
 
- 	m_nProxyOpID=0;
 
- 	m_nProxyOpState=0;
 
- 	m_pRecvBuffer=0;
 
- 	m_nRecvBufferLen=0;
 
- 	m_nRecvBufferPos=0;
 
- 	m_ProxyData.nProxyType=0;
 
- 	m_nProxyPeerIp=0;
 
- 	m_nProxyPeerPort=0;
 
- 	m_pProxyPeerHost = NULL;
 
- 	m_pStrBuffer = NULL;
 
- 	m_ProxyData.pProxyHost = NULL;
 
- 	m_ProxyData.pProxyUser = NULL;
 
- 	m_ProxyData.pProxyPass = NULL;
 
- 	m_pProxyPeerHost = NULL;
 
- }
 
- CAsyncProxySocketLayer::~CAsyncProxySocketLayer()
 
- {
 
- 	delete [] m_ProxyData.pProxyHost;
 
- 	delete [] m_ProxyData.pProxyUser;
 
- 	delete [] m_ProxyData.pProxyPass;
 
- 	delete [] m_pProxyPeerHost;
 
- 	ClearBuffer();
 
- }
 
- /////////////////////////////////////////////////////////////////////////////
 
- // Member-Funktion CAsyncProxySocketLayer
 
- void CAsyncProxySocketLayer::SetProxy(int nProxyType)
 
- {
 
- 	//Validate the parameters
 
- 	ASSERT(nProxyType==PROXYTYPE_NOPROXY);
 
- 	m_ProxyData.nProxyType=nProxyType;
 
- }
 
- void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort)
 
- {
 
- 	USES_CONVERSION;
 
- 	//Validate the parameters
 
- 	ASSERT(nProxyType==PROXYTYPE_SOCKS4  ||
 
- 		   nProxyType==PROXYTYPE_SOCKS4A ||
 
- 		   nProxyType==PROXYTYPE_SOCKS5  ||
 
- 		   nProxyType==PROXYTYPE_HTTP11);
 
- 	ASSERT(!m_nProxyOpID);
 
- 	ASSERT(pProxyHost && *pProxyHost);
 
- 	ASSERT(ProxyPort>0);
 
- 	ASSERT(ProxyPort<=65535);
 
- 	delete m_ProxyData.pProxyHost;
 
- 	delete m_ProxyData.pProxyUser;
 
- 	delete m_ProxyData.pProxyPass;
 
- 	m_ProxyData.pProxyUser = NULL;
 
- 	m_ProxyData.pProxyPass = NULL;
 
- 	m_ProxyData.nProxyType = nProxyType;
 
- 	m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
 
- 	strcpy(m_ProxyData.pProxyHost, pProxyHost);
 
- 	m_ProxyData.nProxyPort = ProxyPort;
 
- 	m_ProxyData.bUseLogon = FALSE;
 
- }
 
- void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort, const char * pProxyUser, const char * pProxyPass)
 
- {
 
- 	USES_CONVERSION;
 
- 	//Validate the parameters
 
- 	ASSERT(nProxyType==PROXYTYPE_SOCKS5 || nProxyType==PROXYTYPE_HTTP11);
 
- 	ASSERT(!m_nProxyOpID);
 
- 	ASSERT(pProxyHost && *pProxyHost);
 
- 	ASSERT(ProxyPort>0);
 
- 	ASSERT(ProxyPort<=65535);
 
- 	delete m_ProxyData.pProxyHost;
 
- 	delete m_ProxyData.pProxyUser;
 
- 	delete m_ProxyData.pProxyPass;
 
- 	m_ProxyData.pProxyUser = NULL;
 
- 	m_ProxyData.pProxyPass = NULL;
 
- 	m_ProxyData.nProxyType = nProxyType;
 
- 	m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
 
- 	strcpy(m_ProxyData.pProxyHost, pProxyHost);
 
- 	m_ProxyData.nProxyPort=ProxyPort;
 
- 	if (pProxyUser)
 
- 	{
 
- 		m_ProxyData.pProxyUser = new char[strlen(pProxyUser)+1];
 
- 		strcpy(m_ProxyData.pProxyUser, pProxyUser);
 
- 	}
 
- 	if (pProxyPass)
 
- 	{
 
- 		m_ProxyData.pProxyPass = new char[strlen(pProxyPass)+1];
 
- 		strcpy(m_ProxyData.pProxyPass, pProxyPass);
 
- 	}
 
- 	m_ProxyData.bUseLogon = TRUE;
 
- }
 
- void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
 
- {
 
- 	//Here we handle the responses from the SOCKS proxy
 
- 	if (!m_nProxyOpID)
 
- 	{
 
- 		TriggerEvent(FD_READ, nErrorCode, TRUE);
 
- 		return;
 
- 	}
 
- 	if (nErrorCode)
 
- 	{
 
- 		TriggerEvent(FD_READ, nErrorCode, TRUE);
 
- 	}
 
- 	if (!m_nProxyOpState) //We should not receive a response yet!
 
- 	{ 
 
- 		//Ignore it
 
- 		return;
 
- 	}
 
- 	if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
 
- 	{
 
- 		if (m_nProxyOpState==1) //Both for PROXYOP_CONNECT and PROXYOP_BIND
 
- 		{
 
- 			if (!m_pRecvBuffer)
 
- 				m_pRecvBuffer=new char[8];
 
- 			int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 8-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();
 
- 					ClearBuffer();
 
- 				}
 
- 				return;
 
- 			}
 
- 			m_nRecvBufferPos+=numread;
 
- 			if (m_nRecvBufferPos==8)
 
- 			{
 
- 				if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
 
- 				{
 
- 					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_nProxyOpID==PROXYOP_CONNECT)
 
- 				{
 
- 					//OK, we are connected with the remote server
 
- 					ClearBuffer();
 
- 					Reset();
 
- 					TriggerEvent(FD_CONNECT, 0, TRUE);
 
- 					TriggerEvent(FD_READ, 0, TRUE);
 
- 					TriggerEvent(FD_WRITE, 0, TRUE);
 
- 					return;
 
- 				}
 
- 				else
 
- 				{
 
- 					//Listen socket created
 
- 					m_nProxyOpState++;
 
- 					unsigned long ip;
 
- 					int port;
 
- 					memcpy(&ip,&m_pRecvBuffer[4],4);
 
- 					if (!ip)
 
- 					{ 
 
- 						//No IP return, use the IP of the proxy server
 
- 						SOCKADDR SockAddr;
 
- 						memset(&SockAddr,0,sizeof(SockAddr));
 
- 						int SockAddrLen=sizeof(SockAddr);
 
- 						if (GetPeerName(&SockAddr, &SockAddrLen ))
 
- 						{
 
- 							ip=((LPSOCKADDR_IN)&SockAddr)->sin_addr.S_un.S_addr;
 
- 						}
 
- 						else
 
- 						{
 
- 							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;
 
- 						}
 
- 					}
 
- 					memcpy(&port,&m_pRecvBuffer[2],2);
 
- 					t_ListenSocketCreatedStruct data;
 
- 					data.ip=ip;
 
- 					data.nPort=port;
 
- 					DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
 
- 				}
 
- 				ClearBuffer();
 
- 			}
 
- 		}
 
- 		else if (m_nProxyOpID==2)
 
- 		{
 
- 			if (!m_pRecvBuffer)
 
- 				m_pRecvBuffer=new char[8];
 
- 			int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,8-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();
 
- 					ClearBuffer();
 
- 				}
 
- 				return;
 
- 			}
 
- 			m_nRecvBufferPos+=numread;
 
- 			if (m_nRecvBufferPos==8)
 
- 			{
 
- 				if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
 
- 				{
 
- 					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;
 
- 				}
 
- 				//Connection to remote server established
 
- 				ClearBuffer();
 
- 				Reset();
 
- 				TriggerEvent(FD_ACCEPT, 0, TRUE);
 
- 				TriggerEvent(FD_READ, 0, TRUE);
 
- 				TriggerEvent(FD_WRITE, 0, TRUE);
 
- 			}
 
- 		}
 
- 	}
 
- 	else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
 
- 	{
 
- 		if (m_nProxyOpState==1) //Get respone to initialization message
 
- 		{
 
- 			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[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_pRecvBuffer[1])
 
- 				{ 
 
- 					//Auth needed
 
- 					if (m_pRecvBuffer[1]!=2)
 
- 					{ 
 
- 						//Unknown auth type
 
- 						DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHTYPEUNKNOWN, 0);
 
- 						if (m_nProxyOpID==PROXYOP_CONNECT)
 
- 							TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
 
- 						else
 
- 							TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
 
- 						Reset();
 
- 						ClearBuffer();
 
- 						return;
 
- 					}
 
- 					if (!m_ProxyData.bUseLogon)
 
- 					{
 
- 						DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHNOLOGON, 0);
 
- 						if (m_nProxyOpID==PROXYOP_CONNECT)
 
- 							TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
 
- 						else
 
- 							TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
 
- 						Reset();
 
- 						ClearBuffer();
 
- 						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]=1;
 
- 					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
 
- 			#ifdef MPEXT
 
- 			const
 
- 			#endif
 
- 			char *lpszAsciiHost = m_pProxyPeerHost?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;
 
- 				}
 
- 				#ifdef MPEXT
 
- 				const
 
- 				#endif
 
- 				char * lpszAsciiHost = m_pProxyPeerHost?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;
 
- 					unsigned short 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)))
 
- 			{
 
- 				char* str = new char[strlen("No valid HTTP response") + 1];
 
- 				strcpy(str, "No valid HTTP response");
 
- 				DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, str);
 
- 				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, 0, 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);
 
- 	if (m_ProxyData.nProxyType != PROXYTYPE_SOCKS4)
 
- 	{
 
- 		// We can send hostname to proxy, no need to resolve it
 
- 		
 
- 		//Connect to proxy server
 
- 		BOOL res = ConnectNext(A2CT(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
 
- 		if (!res)
 
- 		{
 
- 			if (WSAGetLastError() != WSAEWOULDBLOCK)
 
- 			{
 
- 				DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
 
- 				return FALSE;
 
- 			}
 
- 		}
 
- 		m_nProxyPeerPort = htons((u_short)nHostPort);
 
- 		m_nProxyPeerIp = 0;
 
- 		delete [] m_pProxyPeerHost;
 
- 		m_pProxyPeerHost = new char[_tcslen(lpszHostAddress)+1];
 
- 		strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
 
- 		m_nProxyOpID=PROXYOP_CONNECT;
 
- 		return TRUE;
 
- 	}
 
- 	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
 
- 			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 = new char[strlen(T2CA(lpszHostAddress))+1];
 
- 		strcpy(m_pProxyPeerHost, T2CA(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 );
 
- 	}
 
- 	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;
 
- 	USES_CONVERSION;
 
- 	BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
 
- 	if (!res)
 
- 	{
 
- 		if (WSAGetLastError()!=WSAEWOULDBLOCK)
 
- 		{
 
- 			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
 
- 			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, 0);
 
- 		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();
 
- 		DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOERROR, 0);
 
- 		//Send the initial request
 
- 		if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
 
- 		{ //SOCKS4 proxy
 
- 			//Send request
 
- 			LPCSTR lpszAscii = m_pProxyPeerHost?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 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
 
- 			{
 
- 				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)
 
- 			{
 
- 				pHost = new char[strlen(m_pProxyPeerHost)+1];
 
- 				strcpy(pHost, 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;
 
- 			USES_CONVERSION;
 
- 			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);
 
- 	USES_CONVERSION;
 
- 	//Connect to proxy server
 
- 	BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
 
- 	if (!res)
 
- 	{
 
- 		if (WSAGetLastError()!=WSAEWOULDBLOCK)
 
- 		{
 
- 			DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
 
- 			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;
 
- }
 
 
  |