| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964 | // CAsyncProxySocketLayer by Tim Kosse ([email protected])//                 Version 1.6 (2003-03-26)//---------------------------------------------------------------------------// 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]//---------------------------------------------------------------------------#include "stdafx.h"#include "AsyncProxySocketLayer.h"#include "atlconv.h" //Unicode<->Ascii conversion macros declared here#include <Soap.EncdDecd.hpp>//////////////////////////////////////////////////////////////////////// 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 CAsyncProxySocketLayervoid CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort, bool bUseLogon, const char * pProxyUser, const char * pProxyPass){  USES_CONVERSION;  //Validate the parameters  DebugAssert(!m_nProxyOpID);  DebugAssert(pProxyHost && *pProxyHost);  DebugAssert(ProxyPort>0);  DebugAssert(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 = bUseLogon;}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)        {          ConnectionFailed(WSAGetLastError());        }        return;      }      m_nRecvBufferPos+=numread;      if (m_nRecvBufferPos==8)      {        if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)        {          ConnectionFailed(WSAECONNABORTED);          return;        }        if (m_nProxyOpID==PROXYOP_CONNECT)        {          //OK, we are connected with the remote server          ConnectionEstablished();          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            {              ConnectionFailed(WSAECONNABORTED);              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==PROXYOP_LISTEN)    {      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)        {          ConnectionFailed(WSAGetLastError());        }        return;      }      m_nRecvBufferPos+=numread;      if (m_nRecvBufferPos==8)      {        if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)        {          ConnectionFailed(WSAECONNABORTED);          return;        }        //Connection to remote server established        ConnectionEstablished();      }    }  }  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)        {          ConnectionFailed(WSAGetLastError());        }        return;      }      m_nRecvBufferPos+=numread;      if (m_nRecvBufferPos==2)      {        if (m_pRecvBuffer[0]!=5)        {          ConnectionFailed(WSAECONNABORTED);          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;          DebugAssert(strlen(lpszAsciiUser)<=255);          DebugAssert(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)            {              ConnectionFailed(WSAGetLastError());              return;            }          }          ClearBuffer();          m_nProxyOpState++;          return;        }      }      //No auth needed      //Send connection request      const 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)        {          ConnectionFailed(WSAGetLastError());          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)        {          ConnectionFailed(WSAGetLastError());        }        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;        }        const 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)          {            ConnectionFailed(WSAGetLastError());            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)        {          ConnectionFailed(WSAGetLastError());        }        return;      }      m_nRecvBufferPos+=numread;      if (m_nRecvBufferPos==m_nRecvBufferLen)      {        //Check for errors        if (m_pRecvBuffer[1]!=0 || m_pRecvBuffer[0]!=5)        {          ConnectionFailed(WSAECONNABORTED);          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          ConnectionEstablished();        }        else        {          //Listen socket created          m_nProxyOpState++;          unsigned long ip;          unsigned short port;          DebugAssert(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)    {      DebugAssert(m_nProxyOpID == PROXYOP_LISTEN);      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)        {          ConnectionFailed(WSAGetLastError());        }        return;      }      m_nRecvBufferPos+=numread;      if (m_nRecvBufferPos==10)      {        if (m_pRecvBuffer[1]!=0)        {          ConnectionFailed(WSAECONNABORTED);          return;        }        //Connection to remote server established        ConnectionEstablished();      }    }  }  else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)  {    DebugAssert(m_nProxyOpID==PROXYOP_CONNECT);    char buffer[9]={0};    bool responseLogged = false;    for(;;)    {      int numread = ReceiveNext(buffer, m_pStrBuffer?1:8);      if (numread==SOCKET_ERROR)      {        int nError=WSAGetLastError();        if (nError!=WSAEWOULDBLOCK)        {          ConnectionFailed(nError);        }        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");        ConnectionFailed(WSAECONNABORTED, str);        return;      }      char *pos = strstr(m_pStrBuffer, "\r\n");      if (pos)      {        if (!responseLogged)        {          CString status;          status.Format(L"HTTP proxy response: %s", UnicodeString(m_pStrBuffer, pos - m_pStrBuffer).c_str());          LogSocketMessageRaw(FZ_LOG_PROGRESS, status);          responseLogged = true;        }        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);          ConnectionFailed(WSAECONNABORTED, tmp);          return;        }      }      if (strlen(m_pStrBuffer)>3 && !memcmp(m_pStrBuffer+strlen(m_pStrBuffer)-4, "\r\n\r\n", 4)) //End of the HTTP header      {        CString status;        status.Format(L"HTTP proxy headers: %s", UnicodeString(pos).c_str());        LogSocketMessageRaw(FZ_LOG_PROGRESS, status);        ConnectionEstablished();        return;      }    }  }}void CAsyncProxySocketLayer::ConnectionFailed(int nErrorCode, char * Str){  DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, Str);  if (m_nProxyOpID == PROXYOP_CONNECT)  {    TriggerEvent(FD_CONNECT, nErrorCode, TRUE);  }  else  {    TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);  }  Reset();  ClearBuffer();}void CAsyncProxySocketLayer::ConnectionEstablished(){  int Event = (m_nProxyOpID == PROXYOP_CONNECT) ? FD_CONNECT : FD_ACCEPT;  ClearBuffer();  Reset();  TriggerEvent(Event, 0, TRUE);  TriggerEvent(FD_READ, 0, TRUE);  TriggerEvent(FD_WRITE, 0, TRUE);}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  DebugAssert(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;  }  DebugAssert(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;    DebugAssert(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)      {        DebugAssert(m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A);        DebugAssert(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)      {        ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);        return;      }      else if (res<len)      {        ConnectionFailed(WSAECONNABORTED);        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)      {        ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);        return;      }      else if (res<len)      {        ConnectionFailed(WSAECONNABORTED);        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:"");        AnsiString base64str = EncodeBase64(userpass, strlen(userpass));        strcat(str, "Authorization: Basic ");        strcat(str, base64str.c_str());        strcat(str, "\r\nProxy-Authorization: Basic ");        strcat(str, base64str.c_str());        strcat(str, "\r\n\r\n");      }      delete [] pHost;      USES_CONVERSION;      CString status;      status.Format(L"HTTP proxy command: %s", UnicodeString(str).c_str());      LogSocketMessageRaw(FZ_LOG_PROGRESS, status);      int numsent=SendNext(str, strlen(str) );      int nErrorCode=WSAGetLastError();      if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)      {        ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);        return;      }      else if (  numsent < static_cast<int>( strlen(str) )  )      {        ConnectionFailed(WSAECONNABORTED);        return;      }      m_nProxyOpState++;      return;    }    else      DebugFail();    //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 (m_ProxyData.nProxyType==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;}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;  }  DebugAssert(m_ProxyData.nProxyType);  BOOL res=GetPeerNameNext( rPeerAddress, rPeerPort );  if (res)  {    rPeerPort=ntohs(m_nProxyPeerPort);    rPeerAddress.Format(L"%d.%d.%d.%d", m_nProxyPeerIp%256,(m_nProxyPeerIp>>8)%256,(m_nProxyPeerIp>>16)%256, m_nProxyPeerIp>>24);  }  return res;}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;  }  DebugAssert(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;}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::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ ){  if (!m_ProxyData.nProxyType)    return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);  GetPeerName(lpSockAddr, lpSockAddrLen);  return TRUE;}
 |