12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256 |
- /*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;
- }
|