AsyncProxySocketLayer.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950
  1. // CAsyncProxySocketLayer by Tim Kosse ([email protected])
  2. // Version 1.6 (2003-03-26)
  3. //---------------------------------------------------------------------------
  4. // Feel free to use this class, as long as you don't claim that you wrote it
  5. // and this copyright notice stays intact in the source files.
  6. // If you use this class in commercial applications, please send a short message
  7. // to [email protected]
  8. //---------------------------------------------------------------------------
  9. #include "stdafx.h"
  10. #include "AsyncProxySocketLayer.h"
  11. #include "atlconv.h" //Unicode<->Ascii conversion macros declared here
  12. #include <Soap.EncdDecd.hpp>
  13. //////////////////////////////////////////////////////////////////////
  14. // Konstruktion/Destruktion
  15. //////////////////////////////////////////////////////////////////////
  16. CAsyncProxySocketLayer::CAsyncProxySocketLayer()
  17. {
  18. m_nProxyOpID=0;
  19. m_nProxyOpState=0;
  20. m_pRecvBuffer=0;
  21. m_nRecvBufferLen=0;
  22. m_nRecvBufferPos=0;
  23. m_ProxyData.nProxyType=0;
  24. m_nProxyPeerIp=0;
  25. m_nProxyPeerPort=0;
  26. m_pProxyPeerHost = NULL;
  27. m_pStrBuffer = NULL;
  28. m_ProxyData.pProxyHost = NULL;
  29. m_ProxyData.pProxyUser = NULL;
  30. m_ProxyData.pProxyPass = NULL;
  31. m_pProxyPeerHost = NULL;
  32. }
  33. CAsyncProxySocketLayer::~CAsyncProxySocketLayer()
  34. {
  35. delete [] m_ProxyData.pProxyHost;
  36. delete [] m_ProxyData.pProxyUser;
  37. delete [] m_ProxyData.pProxyPass;
  38. delete [] m_pProxyPeerHost;
  39. ClearBuffer();
  40. }
  41. /////////////////////////////////////////////////////////////////////////////
  42. // Member-Funktion CAsyncProxySocketLayer
  43. void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort, bool bUseLogon, const char * pProxyUser, const char * pProxyPass)
  44. {
  45. USES_CONVERSION;
  46. //Validate the parameters
  47. DebugAssert(!m_nProxyOpID);
  48. DebugAssert(pProxyHost && *pProxyHost);
  49. DebugAssert(ProxyPort>0);
  50. DebugAssert(ProxyPort<=65535);
  51. delete m_ProxyData.pProxyHost;
  52. delete m_ProxyData.pProxyUser;
  53. delete m_ProxyData.pProxyPass;
  54. m_ProxyData.pProxyUser = NULL;
  55. m_ProxyData.pProxyPass = NULL;
  56. m_ProxyData.nProxyType = nProxyType;
  57. m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
  58. strcpy(m_ProxyData.pProxyHost, pProxyHost);
  59. m_ProxyData.nProxyPort=ProxyPort;
  60. if (pProxyUser)
  61. {
  62. m_ProxyData.pProxyUser = new char[strlen(pProxyUser)+1];
  63. strcpy(m_ProxyData.pProxyUser, pProxyUser);
  64. }
  65. if (pProxyPass)
  66. {
  67. m_ProxyData.pProxyPass = new char[strlen(pProxyPass)+1];
  68. strcpy(m_ProxyData.pProxyPass, pProxyPass);
  69. }
  70. m_ProxyData.bUseLogon = bUseLogon;
  71. }
  72. void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
  73. {
  74. //Here we handle the responses from the SOCKS proxy
  75. if (!m_nProxyOpID)
  76. {
  77. TriggerEvent(FD_READ, nErrorCode, TRUE);
  78. return;
  79. }
  80. if (nErrorCode)
  81. {
  82. TriggerEvent(FD_READ, nErrorCode, TRUE);
  83. }
  84. if (!m_nProxyOpState) //We should not receive a response yet!
  85. {
  86. //Ignore it
  87. return;
  88. }
  89. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  90. {
  91. if (m_nProxyOpState==1) //Both for PROXYOP_CONNECT and PROXYOP_BIND
  92. {
  93. if (!m_pRecvBuffer)
  94. m_pRecvBuffer=new char[8];
  95. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 8-m_nRecvBufferPos);
  96. if (numread==SOCKET_ERROR)
  97. {
  98. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  99. {
  100. ConnectionFailed(WSAGetLastError());
  101. }
  102. return;
  103. }
  104. m_nRecvBufferPos+=numread;
  105. if (m_nRecvBufferPos==8)
  106. {
  107. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  108. {
  109. ConnectionFailed(WSAECONNABORTED);
  110. return;
  111. }
  112. if (m_nProxyOpID==PROXYOP_CONNECT)
  113. {
  114. //OK, we are connected with the remote server
  115. ConnectionEstablished();
  116. return;
  117. }
  118. else
  119. {
  120. //Listen socket created
  121. m_nProxyOpState++;
  122. unsigned long ip;
  123. int port;
  124. memcpy(&ip,&m_pRecvBuffer[4],4);
  125. if (!ip)
  126. {
  127. //No IP return, use the IP of the proxy server
  128. SOCKADDR SockAddr;
  129. memset(&SockAddr,0,sizeof(SockAddr));
  130. int SockAddrLen=sizeof(SockAddr);
  131. if (GetPeerName(&SockAddr, &SockAddrLen ))
  132. {
  133. ip=((LPSOCKADDR_IN)&SockAddr)->sin_addr.S_un.S_addr;
  134. }
  135. else
  136. {
  137. ConnectionFailed(WSAECONNABORTED);
  138. return;
  139. }
  140. }
  141. memcpy(&port,&m_pRecvBuffer[2],2);
  142. t_ListenSocketCreatedStruct data;
  143. data.ip=ip;
  144. data.nPort=port;
  145. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  146. }
  147. ClearBuffer();
  148. }
  149. }
  150. else if (m_nProxyOpID==PROXYOP_LISTEN)
  151. {
  152. if (!m_pRecvBuffer)
  153. m_pRecvBuffer=new char[8];
  154. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,8-m_nRecvBufferPos);
  155. if (numread==SOCKET_ERROR)
  156. {
  157. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  158. {
  159. ConnectionFailed(WSAGetLastError());
  160. }
  161. return;
  162. }
  163. m_nRecvBufferPos+=numread;
  164. if (m_nRecvBufferPos==8)
  165. {
  166. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  167. {
  168. ConnectionFailed(WSAECONNABORTED);
  169. return;
  170. }
  171. //Connection to remote server established
  172. ConnectionEstablished();
  173. }
  174. }
  175. }
  176. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  177. {
  178. if (m_nProxyOpState==1) //Get respone to initialization message
  179. {
  180. if (!m_pRecvBuffer)
  181. m_pRecvBuffer=new char[2];
  182. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,2-m_nRecvBufferPos);
  183. if (numread==SOCKET_ERROR)
  184. {
  185. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  186. {
  187. ConnectionFailed(WSAGetLastError());
  188. }
  189. return;
  190. }
  191. m_nRecvBufferPos+=numread;
  192. if (m_nRecvBufferPos==2)
  193. {
  194. if (m_pRecvBuffer[0]!=5)
  195. {
  196. ConnectionFailed(WSAECONNABORTED);
  197. return;
  198. }
  199. if (m_pRecvBuffer[1])
  200. {
  201. //Auth needed
  202. if (m_pRecvBuffer[1]!=2)
  203. {
  204. //Unknown auth type
  205. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHTYPEUNKNOWN, 0);
  206. if (m_nProxyOpID==PROXYOP_CONNECT)
  207. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  208. else
  209. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  210. Reset();
  211. ClearBuffer();
  212. return;
  213. }
  214. if (!m_ProxyData.bUseLogon)
  215. {
  216. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHNOLOGON, 0);
  217. if (m_nProxyOpID==PROXYOP_CONNECT)
  218. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  219. else
  220. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  221. Reset();
  222. ClearBuffer();
  223. return;
  224. }
  225. //Send authentication
  226. LPCSTR lpszAsciiUser = m_ProxyData.pProxyUser;
  227. LPCSTR lpszAsciiPass = m_ProxyData.pProxyPass;
  228. DebugAssert(strlen(lpszAsciiUser)<=255);
  229. DebugAssert(strlen(lpszAsciiPass)<=255);
  230. unsigned char *buffer = new unsigned char[3 + (lpszAsciiUser?strlen(lpszAsciiUser):0) + (lpszAsciiPass?strlen(lpszAsciiPass):0) + 1];
  231. sprintf((char *)buffer, " %s %s", lpszAsciiUser?lpszAsciiUser:"", lpszAsciiPass?lpszAsciiPass:"");
  232. buffer[0]=1;
  233. buffer[1]=static_cast<unsigned char>(strlen(lpszAsciiUser));
  234. buffer[2+strlen(lpszAsciiUser)]=static_cast<unsigned char>(strlen(lpszAsciiPass));
  235. int len=3+strlen(lpszAsciiUser)+strlen(lpszAsciiPass);
  236. int res=SendNext(buffer,len);
  237. delete [] buffer;
  238. if (res==SOCKET_ERROR || res<len)
  239. {
  240. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  241. {
  242. ConnectionFailed(WSAGetLastError());
  243. return;
  244. }
  245. }
  246. ClearBuffer();
  247. m_nProxyOpState++;
  248. return;
  249. }
  250. }
  251. //No auth needed
  252. //Send connection request
  253. const char *lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  254. char *command=new char[10+strlen(lpszAsciiHost)+1];
  255. memset(command,0,10+strlen(lpszAsciiHost)+1);
  256. command[0]=5;
  257. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  258. command[2]=0;
  259. command[3]=m_nProxyPeerIp?1:3;
  260. int len=4;
  261. if (m_nProxyPeerIp)
  262. {
  263. memcpy(&command[len],&m_nProxyPeerIp,4);
  264. len+=4;
  265. }
  266. else
  267. {
  268. command[len]=strlen(lpszAsciiHost);
  269. strcpy(&command[len+1], lpszAsciiHost);
  270. len += strlen(lpszAsciiHost) + 1;
  271. }
  272. memcpy(&command[len], &m_nProxyPeerPort, 2);
  273. len+=2;
  274. int res=SendNext(command,len);
  275. delete [] command;
  276. if (res==SOCKET_ERROR || res<len)
  277. {
  278. if ( ( WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  279. {
  280. ConnectionFailed(WSAGetLastError());
  281. return;
  282. }
  283. }
  284. m_nProxyOpState+=2;
  285. ClearBuffer();
  286. return;
  287. }
  288. else if (m_nProxyOpState==2)
  289. {
  290. //Response to the auth request
  291. if (!m_pRecvBuffer)
  292. m_pRecvBuffer=new char[2];
  293. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 2-m_nRecvBufferPos);
  294. if (numread==SOCKET_ERROR)
  295. {
  296. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  297. {
  298. ConnectionFailed(WSAGetLastError());
  299. }
  300. return;
  301. }
  302. m_nRecvBufferPos+=numread;
  303. if (m_nRecvBufferPos==2)
  304. {
  305. if (m_pRecvBuffer[1]!=0)
  306. {
  307. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHFAILED, 0);
  308. if (m_nProxyOpID==PROXYOP_CONNECT)
  309. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  310. else
  311. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  312. Reset();
  313. ClearBuffer();
  314. return;
  315. }
  316. const char * lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  317. char *command = new char[10+strlen(lpszAsciiHost)+1];
  318. memset(command,0,10+strlen(lpszAsciiHost)+1);
  319. command[0]=5;
  320. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  321. command[2]=0;
  322. command[3]=m_nProxyPeerIp?1:3;
  323. int len=4;
  324. if (m_nProxyPeerIp)
  325. {
  326. memcpy(&command[len],&m_nProxyPeerIp,4);
  327. len+=4;
  328. }
  329. else
  330. {
  331. command[len]=strlen(lpszAsciiHost);
  332. strcpy(&command[len+1],lpszAsciiHost);
  333. len+=strlen(lpszAsciiHost)+1;
  334. }
  335. memcpy(&command[len],&m_nProxyPeerPort,2);
  336. len+=2;
  337. int res=SendNext(command,len);
  338. delete [] command;
  339. if (res==SOCKET_ERROR || res<len)
  340. {
  341. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  342. {
  343. ConnectionFailed(WSAGetLastError());
  344. return;
  345. }
  346. }
  347. m_nProxyOpState++;
  348. ClearBuffer();
  349. return;
  350. }
  351. }
  352. else if (m_nProxyOpState==3)
  353. {
  354. //Response to the connection request
  355. if (!m_pRecvBuffer)
  356. {
  357. m_pRecvBuffer=new char[10];
  358. m_nRecvBufferLen=5;
  359. }
  360. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,m_nRecvBufferLen-m_nRecvBufferPos);
  361. if (numread==SOCKET_ERROR)
  362. {
  363. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  364. {
  365. ConnectionFailed(WSAGetLastError());
  366. }
  367. return;
  368. }
  369. m_nRecvBufferPos+=numread;
  370. if (m_nRecvBufferPos==m_nRecvBufferLen)
  371. {
  372. //Check for errors
  373. if (m_pRecvBuffer[1]!=0 || m_pRecvBuffer[0]!=5)
  374. {
  375. ConnectionFailed(WSAECONNABORTED);
  376. return;
  377. }
  378. if (m_nRecvBufferLen==5)
  379. {
  380. //Check which kind of address the response contains
  381. if (m_pRecvBuffer[3]==1)
  382. m_nRecvBufferLen=10;
  383. else
  384. {
  385. char *tmp=new char[m_nRecvBufferLen+=m_pRecvBuffer[4]+2];
  386. memcpy(tmp,m_pRecvBuffer,5);
  387. delete [] m_pRecvBuffer;
  388. m_pRecvBuffer=tmp;
  389. m_nRecvBufferLen+=m_pRecvBuffer[4]+2;
  390. }
  391. return;
  392. }
  393. if (m_nProxyOpID==PROXYOP_CONNECT)
  394. {
  395. //OK, we are connected with the remote server
  396. ConnectionEstablished();
  397. }
  398. else
  399. {
  400. //Listen socket created
  401. m_nProxyOpState++;
  402. unsigned long ip;
  403. unsigned short port;
  404. DebugAssert(m_pRecvBuffer[3]==1);
  405. memcpy(&ip, &m_pRecvBuffer[4], 4);
  406. memcpy(&port, &m_pRecvBuffer[8], 2);
  407. t_ListenSocketCreatedStruct data;
  408. data.ip=ip;
  409. data.nPort=port;
  410. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  411. }
  412. ClearBuffer();
  413. }
  414. }
  415. else if (m_nProxyOpState==4)
  416. {
  417. DebugAssert(m_nProxyOpID == PROXYOP_LISTEN);
  418. if (!m_pRecvBuffer)
  419. m_pRecvBuffer=new char[10];
  420. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,10-m_nRecvBufferPos);
  421. if (numread==SOCKET_ERROR)
  422. {
  423. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  424. {
  425. ConnectionFailed(WSAGetLastError());
  426. }
  427. return;
  428. }
  429. m_nRecvBufferPos+=numread;
  430. if (m_nRecvBufferPos==10)
  431. {
  432. if (m_pRecvBuffer[1]!=0)
  433. {
  434. ConnectionFailed(WSAECONNABORTED);
  435. return;
  436. }
  437. //Connection to remote server established
  438. ConnectionEstablished();
  439. }
  440. }
  441. }
  442. else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  443. {
  444. DebugAssert(m_nProxyOpID==PROXYOP_CONNECT);
  445. char buffer[9]={0};
  446. for(;;)
  447. {
  448. int numread = ReceiveNext(buffer, m_pStrBuffer?1:8);
  449. if (numread==SOCKET_ERROR)
  450. {
  451. int nError=WSAGetLastError();
  452. if (nError!=WSAEWOULDBLOCK)
  453. {
  454. ConnectionFailed(nError);
  455. }
  456. return;
  457. }
  458. //Response begins with HTTP/
  459. if (!m_pStrBuffer)
  460. {
  461. m_pStrBuffer = new char[strlen(buffer) + 1];
  462. strcpy(m_pStrBuffer, buffer);
  463. }
  464. else
  465. {
  466. char *tmp = m_pStrBuffer;
  467. m_pStrBuffer = new char[strlen(tmp) + strlen(buffer) + 1];
  468. strcpy(m_pStrBuffer, tmp);
  469. strcpy(m_pStrBuffer + strlen(tmp), buffer);
  470. delete [] tmp;
  471. }
  472. memset(buffer, 0, 9);
  473. const char start[] = "HTTP/";
  474. if (memcmp(start, m_pStrBuffer, (strlen(start)>strlen(m_pStrBuffer)) ? strlen(m_pStrBuffer) : strlen(start)))
  475. {
  476. char* str = new char[strlen("No valid HTTP response") + 1];
  477. strcpy(str, "No valid HTTP response");
  478. ConnectionFailed(WSAECONNABORTED, str);
  479. return;
  480. }
  481. char *pos = strstr(m_pStrBuffer, "\r\n");
  482. if (pos)
  483. {
  484. char *pos2 = strstr(m_pStrBuffer, " ");
  485. if (!pos2 || *(pos2+1)!='2' || pos2>pos)
  486. {
  487. char *tmp = new char[pos-m_pStrBuffer + 1];
  488. tmp[pos-m_pStrBuffer] = 0;
  489. strncpy(tmp, m_pStrBuffer, pos-m_pStrBuffer);
  490. ConnectionFailed(WSAECONNABORTED, tmp);
  491. return;
  492. }
  493. }
  494. if (strlen(m_pStrBuffer)>3 && !memcmp(m_pStrBuffer+strlen(m_pStrBuffer)-4, "\r\n\r\n", 4)) //End of the HTTP header
  495. {
  496. ConnectionEstablished();
  497. return;
  498. }
  499. }
  500. }
  501. }
  502. void CAsyncProxySocketLayer::ConnectionFailed(int nErrorCode, char * Str)
  503. {
  504. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, Str);
  505. if (m_nProxyOpID == PROXYOP_CONNECT)
  506. {
  507. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  508. }
  509. else
  510. {
  511. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  512. }
  513. Reset();
  514. ClearBuffer();
  515. }
  516. void CAsyncProxySocketLayer::ConnectionEstablished()
  517. {
  518. int Event = (m_nProxyOpID == PROXYOP_CONNECT) ? FD_CONNECT : FD_ACCEPT;
  519. ClearBuffer();
  520. Reset();
  521. TriggerEvent(Event, 0, TRUE);
  522. TriggerEvent(FD_READ, 0, TRUE);
  523. TriggerEvent(FD_WRITE, 0, TRUE);
  524. }
  525. BOOL CAsyncProxySocketLayer::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
  526. {
  527. if (!m_ProxyData.nProxyType)
  528. //Connect normally because there is no proxy
  529. return ConnectNext(lpszHostAddress, nHostPort);
  530. USES_CONVERSION;
  531. //Translate the host address
  532. DebugAssert(lpszHostAddress != NULL);
  533. if (m_ProxyData.nProxyType != PROXYTYPE_SOCKS4)
  534. {
  535. // We can send hostname to proxy, no need to resolve it
  536. //Connect to proxy server
  537. BOOL res = ConnectNext(A2CT(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  538. if (!res)
  539. {
  540. if (WSAGetLastError() != WSAEWOULDBLOCK)
  541. {
  542. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  543. return FALSE;
  544. }
  545. }
  546. m_nProxyPeerPort = htons((u_short)nHostPort);
  547. m_nProxyPeerIp = 0;
  548. delete [] m_pProxyPeerHost;
  549. m_pProxyPeerHost = new char[_tcslen(lpszHostAddress)+1];
  550. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  551. m_nProxyOpID=PROXYOP_CONNECT;
  552. return TRUE;
  553. }
  554. SOCKADDR_IN sockAddr;
  555. memset(&sockAddr,0,sizeof(sockAddr));
  556. LPCSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  557. sockAddr.sin_family = AF_INET;
  558. sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  559. if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  560. {
  561. LPHOSTENT lphost;
  562. lphost = gethostbyname(lpszAscii);
  563. if (lphost != NULL)
  564. sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  565. else
  566. {
  567. //Can't resolve hostname
  568. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_CANTRESOLVEHOST, 0);
  569. WSASetLastError(WSAEINVAL);
  570. return FALSE;
  571. }
  572. }
  573. sockAddr.sin_port = htons((u_short)nHostPort);
  574. BOOL res=CAsyncProxySocketLayer::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  575. if (res || WSAGetLastError()==WSAEWOULDBLOCK)
  576. {
  577. delete [] m_pProxyPeerHost;
  578. m_pProxyPeerHost = new char[strlen(T2CA(lpszHostAddress))+1];
  579. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  580. }
  581. return res;
  582. }
  583. BOOL CAsyncProxySocketLayer::Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen )
  584. {
  585. if (!m_ProxyData.nProxyType)
  586. {
  587. //Connect normally because there is no proxy
  588. return ConnectNext(lpSockAddr, nSockAddrLen );
  589. }
  590. LPSOCKADDR_IN sockAddr=(LPSOCKADDR_IN)lpSockAddr;
  591. //Save server details
  592. m_nProxyPeerIp=sockAddr->sin_addr.S_un.S_addr;
  593. m_nProxyPeerPort=sockAddr->sin_port;
  594. delete [] m_pProxyPeerHost;
  595. m_pProxyPeerHost = NULL;
  596. m_nProxyOpID=PROXYOP_CONNECT;
  597. USES_CONVERSION;
  598. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  599. if (!res)
  600. {
  601. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  602. {
  603. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  604. return FALSE;
  605. }
  606. }
  607. return res;
  608. }
  609. void CAsyncProxySocketLayer::OnConnect(int nErrorCode)
  610. {
  611. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  612. {
  613. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  614. return;
  615. }
  616. DebugAssert(m_nProxyOpID);
  617. if (!m_nProxyOpID)
  618. {
  619. //This should not happen
  620. return;
  621. };
  622. if (nErrorCode)
  623. { //Can't connect to proxy
  624. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  625. if (m_nProxyOpID==PROXYOP_CONNECT)
  626. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  627. else
  628. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  629. Reset();
  630. ClearBuffer();
  631. return;
  632. }
  633. if (m_nProxyOpID==PROXYOP_CONNECT || m_nProxyOpID==PROXYOP_LISTEN)
  634. {
  635. if (m_nProxyOpState)
  636. //Somehow OnConnect has been called more than once
  637. return;
  638. DebugAssert(m_ProxyData.nProxyType!=PROXYTYPE_NOPROXY);
  639. ClearBuffer();
  640. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOERROR, 0);
  641. //Send the initial request
  642. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  643. { //SOCKS4 proxy
  644. //Send request
  645. LPCSTR lpszAscii = m_pProxyPeerHost?m_pProxyPeerHost:"";
  646. char *command=new char [9+strlen(lpszAscii)+1];
  647. memset(command,0,9+strlen(lpszAscii)+1);
  648. int len=9;
  649. command[0]=4;
  650. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2; //CONNECT or BIND request
  651. memcpy(&command[2],&m_nProxyPeerPort,2); //Copy target address
  652. if (!m_nProxyPeerIp || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  653. {
  654. DebugAssert(m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A);
  655. DebugAssert(strcmp(lpszAscii, ""));
  656. //Set the IP to 0.0.0.x (x is nonzero)
  657. command[4]=0;
  658. command[5]=0;
  659. command[6]=0;
  660. command[7]=1;
  661. //Add host as URL
  662. strcpy(&command[9],lpszAscii);
  663. len+=strlen(lpszAscii)+1;
  664. }
  665. else
  666. memcpy(&command[4],&m_nProxyPeerIp,4);
  667. int res=SendNext(command,len); //Send command
  668. delete [] command;
  669. int nErrorCode=WSAGetLastError();
  670. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  671. {
  672. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  673. return;
  674. }
  675. else if (res<len)
  676. {
  677. ConnectionFailed(WSAECONNABORTED);
  678. return;
  679. }
  680. }
  681. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  682. { //SOCKS5 proxy
  683. //Send initialization request
  684. unsigned char command[10];
  685. memset(command,0,10);
  686. command[0]=5;
  687. //CAsyncProxySocketLayer supports to logon types: No logon and
  688. //cleartext username/password (if set) logon
  689. command[1]=m_ProxyData.bUseLogon?2:1; //Number of logon types
  690. command[2]=m_ProxyData.bUseLogon?2:0; //2=user/pass, 0=no logon
  691. int len=m_ProxyData.bUseLogon?4:3; //length of request
  692. int res=SendNext(command,len);
  693. int nErrorCode=WSAGetLastError();
  694. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  695. {
  696. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  697. return;
  698. }
  699. else if (res<len)
  700. {
  701. ConnectionFailed(WSAECONNABORTED);
  702. return;
  703. }
  704. }
  705. else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  706. {
  707. char str[4096]; //This should be large enough
  708. char * pHost = NULL;
  709. if (m_pProxyPeerHost && *m_pProxyPeerHost)
  710. {
  711. pHost = new char[strlen(m_pProxyPeerHost)+1];
  712. strcpy(pHost, m_pProxyPeerHost);
  713. }
  714. else
  715. {
  716. pHost = new char[16];
  717. sprintf(pHost, "%d.%d.%d.%d", m_nProxyPeerIp%256, (m_nProxyPeerIp>>8) % 256, (m_nProxyPeerIp>>16) %256, m_nProxyPeerIp>>24);
  718. }
  719. if (!m_ProxyData.bUseLogon)
  720. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", pHost, ntohs(m_nProxyPeerPort),
  721. pHost, ntohs(m_nProxyPeerPort));
  722. else
  723. {
  724. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", pHost, ntohs(m_nProxyPeerPort),
  725. pHost, ntohs(m_nProxyPeerPort));
  726. char userpass[4096];
  727. sprintf(userpass, "%s:%s", m_ProxyData.pProxyUser?m_ProxyData.pProxyUser:"", m_ProxyData.pProxyPass?m_ProxyData.pProxyPass:"");
  728. AnsiString base64str = EncodeBase64(userpass, strlen(userpass));
  729. strcat(str, "Authorization: Basic ");
  730. strcat(str, base64str.c_str());
  731. strcat(str, "\r\nProxy-Authorization: Basic ");
  732. strcat(str, base64str.c_str());
  733. strcat(str, "\r\n\r\n");
  734. }
  735. delete [] pHost;
  736. USES_CONVERSION;
  737. int numsent=SendNext(str, strlen(str) );
  738. int nErrorCode=WSAGetLastError();
  739. if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  740. {
  741. ConnectionFailed((m_nProxyOpID == PROXYOP_CONNECT) && (nErrorCode == WSAEWOULDBLOCK) ? WSAECONNABORTED : nErrorCode);
  742. return;
  743. }
  744. else if ( numsent < static_cast<int>( strlen(str) ) )
  745. {
  746. ConnectionFailed(WSAECONNABORTED);
  747. return;
  748. }
  749. m_nProxyOpState++;
  750. return;
  751. }
  752. else
  753. DebugFail();
  754. //Now we'll wait for the response, handled in OnReceive
  755. m_nProxyOpState++;
  756. }
  757. }
  758. void CAsyncProxySocketLayer::ClearBuffer()
  759. {
  760. delete [] m_pStrBuffer;
  761. m_pStrBuffer = NULL;
  762. if (m_pRecvBuffer)
  763. {
  764. delete [] m_pRecvBuffer;
  765. m_pRecvBuffer=0;
  766. }
  767. m_nRecvBufferLen=0;
  768. m_nRecvBufferPos=0;
  769. }
  770. BOOL CAsyncProxySocketLayer::Listen( int nConnectionBacklog)
  771. {
  772. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  773. return ListenNext(nConnectionBacklog);
  774. USES_CONVERSION;
  775. //Connect to proxy server
  776. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  777. if (!res)
  778. {
  779. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  780. {
  781. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  782. return FALSE;
  783. }
  784. }
  785. m_nProxyPeerPort=0;
  786. m_nProxyPeerIp=(unsigned int)nConnectionBacklog;
  787. m_nProxyOpID=PROXYOP_LISTEN;
  788. return TRUE;
  789. }
  790. BOOL CAsyncProxySocketLayer::GetPeerName(CString &rPeerAddress, UINT &rPeerPort)
  791. {
  792. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  793. {
  794. return GetPeerNameNext(rPeerAddress, rPeerPort);
  795. }
  796. if (GetLayerState()==notsock)
  797. {
  798. WSASetLastError(WSAENOTSOCK);
  799. return FALSE;
  800. }
  801. else if (GetLayerState()!=connected)
  802. {
  803. WSASetLastError(WSAENOTCONN);
  804. return FALSE;
  805. }
  806. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  807. {
  808. WSASetLastError(WSAENOTCONN);
  809. return FALSE;
  810. }
  811. DebugAssert(m_ProxyData.nProxyType);
  812. BOOL res=GetPeerNameNext( rPeerAddress, rPeerPort );
  813. if (res)
  814. {
  815. rPeerPort=ntohs(m_nProxyPeerPort);
  816. rPeerAddress.Format(L"%d.%d.%d.%d", m_nProxyPeerIp%256,(m_nProxyPeerIp>>8)%256,(m_nProxyPeerIp>>16)%256, m_nProxyPeerIp>>24);
  817. }
  818. return res;
  819. }
  820. BOOL CAsyncProxySocketLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  821. {
  822. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  823. {
  824. return GetPeerNameNext(lpSockAddr, lpSockAddrLen);
  825. }
  826. if (GetLayerState()==notsock)
  827. {
  828. WSASetLastError(WSAENOTSOCK);
  829. return FALSE;
  830. }
  831. else if (GetLayerState()!=connected)
  832. {
  833. WSASetLastError(WSAENOTCONN);
  834. return FALSE;
  835. }
  836. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  837. {
  838. WSASetLastError(WSAENOTCONN);
  839. return FALSE;
  840. }
  841. DebugAssert(m_ProxyData.nProxyType);
  842. BOOL res=GetPeerNameNext(lpSockAddr,lpSockAddrLen);
  843. if (res)
  844. {
  845. LPSOCKADDR_IN addr=(LPSOCKADDR_IN)lpSockAddr;
  846. addr->sin_port=m_nProxyPeerPort;
  847. addr->sin_addr.S_un.S_addr=m_nProxyPeerIp;
  848. }
  849. return res;
  850. }
  851. void CAsyncProxySocketLayer::Close()
  852. {
  853. delete [] m_ProxyData.pProxyHost;
  854. delete [] m_ProxyData.pProxyUser;
  855. delete [] m_ProxyData.pProxyPass;
  856. delete [] m_pProxyPeerHost;
  857. m_ProxyData.pProxyHost = NULL;
  858. m_ProxyData.pProxyUser = NULL;
  859. m_ProxyData.pProxyPass = NULL;
  860. m_pProxyPeerHost = NULL;
  861. ClearBuffer();
  862. Reset();
  863. CloseNext();
  864. }
  865. void CAsyncProxySocketLayer::Reset()
  866. {
  867. m_nProxyOpState=0;
  868. m_nProxyOpID=0;
  869. }
  870. int CAsyncProxySocketLayer::Send(const void* lpBuf, int nBufLen, int nFlags)
  871. {
  872. if (m_nProxyOpID)
  873. {
  874. WSASetLastError(WSAEWOULDBLOCK);
  875. return SOCKET_ERROR;
  876. }
  877. return SendNext(lpBuf, nBufLen, nFlags);
  878. }
  879. int CAsyncProxySocketLayer::Receive(void* lpBuf, int nBufLen, int nFlags)
  880. {
  881. if (m_nProxyOpID)
  882. {
  883. WSASetLastError(WSAEWOULDBLOCK);
  884. return SOCKET_ERROR;
  885. }
  886. return ReceiveNext(lpBuf, nBufLen, nFlags);
  887. }
  888. BOOL CAsyncProxySocketLayer::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  889. {
  890. if (!m_ProxyData.nProxyType)
  891. return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  892. GetPeerName(lpSockAddr, lpSockAddrLen);
  893. return TRUE;
  894. }