AsyncProxySocketLayer.cpp 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235
  1. /*CAsyncProxySocketLayer by Tim Kosse ([email protected])
  2. Version 1.6 (2003-03-26)
  3. --------------------------------------------------------
  4. Introduction:
  5. -------------
  6. This class is layer class for CAsyncSocketEx. With this class you
  7. can connect through SOCKS4/5 and HTTP 1.1 proxies. This class works
  8. as semi-transparent layer between CAsyncSocketEx and the actual socket.
  9. This class is used in FileZilla, a powerful open-source FTP client.
  10. It can be found under http://sourceforge.net/projects/filezilla
  11. For more information about SOCKS4/5 goto
  12. http://www.socks.nec.com/socksprot.html
  13. For more information about HTTP 1.1 goto http://www.rfc-editor.org
  14. and search for RFC2616
  15. How to use?
  16. -----------
  17. You don't have to change much in you already existing code to use
  18. CAsyncProxySocketLayer.
  19. To use it, create an instance of CAsyncProxySocketLayer, call SetProxy
  20. and attach it to a CAsyncSocketEx instance.
  21. You have to process OnLayerCallback in you CAsyncSocketEx instance as it will
  22. receive all layer nofications.
  23. The following notifications are sent:
  24. //Error codes
  25. PROXYERROR_NOERROR 0
  26. PROXYERROR_NOCONN 1 //Can't connect to proxy server, use GetLastError for more information
  27. PROXYERROR_REQUESTFAILED 2 //Request failed, can't send data
  28. PROXYERROR_AUTHREQUIRED 3 //Authentication required
  29. PROXYERROR_AUTHTYPEUNKNOWN 4 //Authtype unknown or not supported
  30. PROXYERROR_AUTHFAILED 5 //Authentication failed
  31. PROXYERROR_AUTHNOLOGON 6
  32. PROXYERROR_CANTRESOLVEHOST 7
  33. //Status messages
  34. PROXYSTATUS_LISTENSOCKETCREATED 8 //Called when a listen socket was created successfully. Unlike the normal listen function,
  35. //a socksified socket has to connect to the proxy to negotiate the details with the server
  36. //on which the listen socket will be created
  37. //The two parameters will contain the ip and port of the listen socket on the server.
  38. If you want to use CAsyncProxySocketLayer to create a listen socket, you
  39. have to use this overloaded function:
  40. BOOL PrepareListen(unsigned long serverIp);
  41. serverIP is the IP of the server you are already connected
  42. through the SOCKS proxy. You can't use listen sockets over a
  43. SOCKS proxy without a primary connection. Listen sockets are only
  44. supported by SOCKS proxies, this won't work with HTTP proxies.
  45. When the listen socket is created successfully, the PROXYSTATUS_LISTENSOCKETCREATED
  46. notification is sent. The parameters will tell you the ip and the port of the listen socket.
  47. After it you have to handle the OnAccept message and accept the
  48. connection.
  49. Be carful when calling Accept: rConnected socket will NOT be filled! Instead use the instance which created the
  50. listen socket, it will handle the data connection.
  51. If you want to accept more than one connection, you have to create a listing socket for each of them!
  52. Description of important functions and their parameters:
  53. --------------------------------------------------------
  54. void SetProxy(int nProxyType);
  55. void SetProxy(int nProxyType, const char * pProxyHost, int nProxyPort);
  56. void SetProxy(int nProxyType, const char * pProxyHost, int nProxyPort, const char *pProxyUser, const char * pProxyPass);
  57. Call one of this functions to set the proxy type.
  58. Parametes:
  59. - nProxyType specifies the Proxy Type.
  60. - ProxyHost and nProxyPort specify the address of the proxy
  61. - ProxyUser and ProxyPass are only available for SOCKS5 proxies.
  62. supported proxy types:
  63. PROXYTYPE_NOPROXY
  64. PROXYTYPE_SOCKS4
  65. PROXYTYPE_SOCKS4A
  66. PROXYTYPE_SOCKS5
  67. PROXYTYPE_HTTP11
  68. There are also some other functions:
  69. GetProxyPeerName
  70. Like GetPeerName of CAsyncSocket, but returns the address of the
  71. server connected through the proxy. If using proxies, GetPeerName
  72. only returns the address of the proxy.
  73. int GetProxyType();
  74. Returns the used proxy
  75. const int GetLastProxyError() const;
  76. Returns the last proxy error
  77. License
  78. -------
  79. Feel free to use this class, as long as you don't claim that you wrote it
  80. and this copyright notice stays intact in the source files.
  81. If you use this class in commercial applications, please send a short message
  82. to [email protected]
  83. Version history
  84. ---------------
  85. - 1.6 got rid of MFC
  86. - 1.5 released CAsyncSocketExLayer version
  87. - 1.4 added UNICODE support
  88. - 1.3 added basic HTTP1.1 authentication
  89. fixed memory leak in SOCKS5 code
  90. OnSocksOperationFailed will be called after Socket has been closed
  91. fixed some minor bugs
  92. - 1.2 renamed into CAsyncProxySocketLayer
  93. added HTTP1.1 proxy support
  94. - 1.1 fixes all known bugs, mostly with SOCKS5 authentication
  95. - 1.0 initial release
  96. */
  97. #include "stdafx.h"
  98. #include "AsyncProxySocketLayer.h"
  99. #include "atlconv.h" //Unicode<->Ascii conversion macros declared here
  100. #include "CBase64coding.hpp"
  101. #ifdef _DEBUG
  102. #undef THIS_FILE
  103. static char THIS_FILE[]=__FILE__;
  104. #define new DEBUG_NEW
  105. #endif
  106. //////////////////////////////////////////////////////////////////////
  107. // Konstruktion/Destruktion
  108. //////////////////////////////////////////////////////////////////////
  109. CAsyncProxySocketLayer::CAsyncProxySocketLayer()
  110. {
  111. m_nProxyOpID=0;
  112. m_nProxyOpState=0;
  113. m_pRecvBuffer=0;
  114. m_nRecvBufferPos=0;
  115. m_ProxyData.nProxyType=0;
  116. m_nProxyPeerIp=0;
  117. m_nProxyPeerPort=0;
  118. m_pProxyPeerHost = NULL;
  119. m_pStrBuffer = NULL;
  120. m_ProxyData.pProxyHost = NULL;
  121. m_ProxyData.pProxyUser = NULL;
  122. m_ProxyData.pProxyPass = NULL;
  123. m_pProxyPeerHost = NULL;
  124. }
  125. CAsyncProxySocketLayer::~CAsyncProxySocketLayer()
  126. {
  127. delete [] m_ProxyData.pProxyHost;
  128. delete [] m_ProxyData.pProxyUser;
  129. delete [] m_ProxyData.pProxyPass;
  130. delete [] m_pProxyPeerHost;
  131. ClearBuffer();
  132. }
  133. /////////////////////////////////////////////////////////////////////////////
  134. // Member-Funktion CAsyncProxySocketLayer
  135. void CAsyncProxySocketLayer::SetProxy(int nProxyType)
  136. {
  137. //Validate the parameters
  138. ASSERT(nProxyType==PROXYTYPE_NOPROXY);
  139. m_ProxyData.nProxyType=nProxyType;
  140. }
  141. void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort)
  142. {
  143. //Validate the parameters
  144. ASSERT(nProxyType==PROXYTYPE_SOCKS4 ||
  145. nProxyType==PROXYTYPE_SOCKS4A ||
  146. nProxyType==PROXYTYPE_SOCKS5 ||
  147. nProxyType==PROXYTYPE_HTTP11);
  148. ASSERT(!m_nProxyOpID);
  149. ASSERT(pProxyHost && *pProxyHost);
  150. ASSERT(ProxyPort>0);
  151. ASSERT(ProxyPort<=65535);
  152. delete m_ProxyData.pProxyHost;
  153. delete m_ProxyData.pProxyUser;
  154. delete m_ProxyData.pProxyPass;
  155. m_ProxyData.pProxyUser = NULL;
  156. m_ProxyData.pProxyPass = NULL;
  157. m_ProxyData.nProxyType = nProxyType;
  158. m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
  159. strcpy(m_ProxyData.pProxyHost, pProxyHost);
  160. m_ProxyData.nProxyPort = ProxyPort;
  161. m_ProxyData.bUseLogon = FALSE;
  162. }
  163. void CAsyncProxySocketLayer::SetProxy(int nProxyType, const char * pProxyHost, int ProxyPort, const char * pProxyUser, const char * pProxyPass)
  164. {
  165. //Validate the parameters
  166. ASSERT(nProxyType==PROXYTYPE_SOCKS5 || nProxyType==PROXYTYPE_HTTP11);
  167. ASSERT(!m_nProxyOpID);
  168. ASSERT(pProxyHost && *pProxyHost);
  169. ASSERT(ProxyPort>0);
  170. ASSERT(ProxyPort<=65535);
  171. delete m_ProxyData.pProxyHost;
  172. delete m_ProxyData.pProxyUser;
  173. delete m_ProxyData.pProxyPass;
  174. m_ProxyData.pProxyUser = NULL;
  175. m_ProxyData.pProxyPass = NULL;
  176. m_ProxyData.nProxyType = nProxyType;
  177. m_ProxyData.pProxyHost = new char[strlen(pProxyHost)+1];
  178. strcpy(m_ProxyData.pProxyHost, pProxyHost);
  179. m_ProxyData.nProxyPort=ProxyPort;
  180. if (pProxyUser)
  181. {
  182. m_ProxyData.pProxyUser = new char[strlen(pProxyUser)+1];
  183. strcpy(m_ProxyData.pProxyUser, pProxyUser);
  184. }
  185. if (pProxyPass)
  186. {
  187. m_ProxyData.pProxyPass = new char[strlen(pProxyPass)+1];
  188. strcpy(m_ProxyData.pProxyPass, pProxyPass);
  189. }
  190. m_ProxyData.bUseLogon = TRUE;
  191. }
  192. void CAsyncProxySocketLayer::OnReceive(int nErrorCode)
  193. {
  194. //Here we handle the responses from the SOCKS proxy
  195. if (!m_nProxyOpID)
  196. {
  197. TriggerEvent(FD_READ, nErrorCode, TRUE);
  198. return;
  199. }
  200. if (nErrorCode)
  201. {
  202. TriggerEvent(FD_READ, nErrorCode, TRUE);
  203. }
  204. if (!m_nProxyOpState) //We should not receive a response yet!
  205. { //Ignore it
  206. return;
  207. }
  208. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  209. {
  210. if (m_nProxyOpState==1) //Both for PROXYOP_CONNECT and PROXYOP_BIND
  211. {
  212. if (!m_pRecvBuffer)
  213. m_pRecvBuffer=new char[8];
  214. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 8-m_nRecvBufferPos);
  215. if (numread==SOCKET_ERROR)
  216. {
  217. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  218. {
  219. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  220. if (m_nProxyOpID==PROXYOP_CONNECT)
  221. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  222. else
  223. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  224. Reset();
  225. ClearBuffer();
  226. }
  227. return;
  228. }
  229. m_nRecvBufferPos+=numread;
  230. if (m_nRecvBufferPos==8)
  231. {
  232. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  233. {
  234. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  235. if (m_nProxyOpID==PROXYOP_CONNECT)
  236. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  237. else
  238. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  239. Reset();
  240. ClearBuffer();
  241. return;
  242. }
  243. if (m_nProxyOpID==PROXYOP_CONNECT)
  244. {
  245. //OK, we are connected with the remote server
  246. ClearBuffer();
  247. Reset();
  248. TriggerEvent(FD_CONNECT, 0, TRUE);
  249. TriggerEvent(FD_READ, 0, TRUE);
  250. TriggerEvent(FD_WRITE, 0, TRUE);
  251. return;
  252. }
  253. else
  254. {
  255. //Listen socket created
  256. m_nProxyOpState++;
  257. unsigned long ip;
  258. int port;
  259. memcpy(&ip,&m_pRecvBuffer[4],4);
  260. if (!ip)
  261. { //No IP return, use the IP of the proxy server
  262. SOCKADDR SockAddr;
  263. memset(&SockAddr,0,sizeof(SockAddr));
  264. int SockAddrLen=sizeof(SockAddr);
  265. if (GetPeerName(&SockAddr, &SockAddrLen ))
  266. {
  267. ip=((LPSOCKADDR_IN)&SockAddr)->sin_addr.S_un.S_addr;
  268. }
  269. else
  270. {
  271. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  272. if (m_nProxyOpID==PROXYOP_CONNECT)
  273. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  274. else
  275. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  276. Reset();
  277. ClearBuffer();
  278. return;
  279. }
  280. }
  281. memcpy(&port,&m_pRecvBuffer[2],2);
  282. t_ListenSocketCreatedStruct data;
  283. data.ip=ip;
  284. data.nPort=port;
  285. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  286. }
  287. ClearBuffer();
  288. }
  289. }
  290. else if (m_nProxyOpID==2)
  291. {
  292. if (!m_pRecvBuffer)
  293. m_pRecvBuffer=new char[8];
  294. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,8-m_nRecvBufferPos);
  295. if (numread==SOCKET_ERROR)
  296. {
  297. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  298. {
  299. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  300. if (m_nProxyOpID==PROXYOP_CONNECT)
  301. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  302. else
  303. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  304. Reset();
  305. ClearBuffer();
  306. }
  307. return;
  308. }
  309. m_nRecvBufferPos+=numread;
  310. if (m_nRecvBufferPos==8)
  311. {
  312. if (m_pRecvBuffer[1]!=90 || m_pRecvBuffer[0]!=0)
  313. {
  314. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  315. if (m_nProxyOpID==PROXYOP_CONNECT)
  316. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  317. else
  318. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  319. Reset();
  320. ClearBuffer();
  321. return;
  322. }
  323. //Connection to remote server established
  324. ClearBuffer();
  325. Reset();
  326. TriggerEvent(FD_ACCEPT, 0, TRUE);
  327. TriggerEvent(FD_READ, 0, TRUE);
  328. TriggerEvent(FD_WRITE, 0, TRUE);
  329. }
  330. }
  331. }
  332. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  333. {
  334. if (m_nProxyOpState==1) //Get respone to initialization message
  335. {
  336. if (!m_pRecvBuffer)
  337. m_pRecvBuffer=new char[2];
  338. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,2-m_nRecvBufferPos);
  339. if (numread==SOCKET_ERROR)
  340. {
  341. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  342. {
  343. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  344. if (m_nProxyOpID==PROXYOP_CONNECT)
  345. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  346. else
  347. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  348. Reset();
  349. }
  350. return;
  351. }
  352. m_nRecvBufferPos+=numread;
  353. if (m_nRecvBufferPos==2)
  354. {
  355. if (m_pRecvBuffer[0]!=5)
  356. {
  357. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  358. if (m_nProxyOpID==PROXYOP_CONNECT)
  359. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  360. else
  361. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  362. Reset();
  363. ClearBuffer();
  364. return;
  365. }
  366. if (m_pRecvBuffer[1])
  367. { //Auth needed
  368. if (m_pRecvBuffer[1]!=2)
  369. { //Unknown auth type
  370. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHTYPEUNKNOWN, 0);
  371. if (m_nProxyOpID==PROXYOP_CONNECT)
  372. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  373. else
  374. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  375. Reset();
  376. ClearBuffer();
  377. return;
  378. }
  379. if (!m_ProxyData.bUseLogon)
  380. {
  381. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHNOLOGON, 0);
  382. if (m_nProxyOpID==PROXYOP_CONNECT)
  383. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  384. else
  385. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  386. Reset();
  387. ClearBuffer();
  388. return;
  389. }
  390. //Send authentication
  391. LPCSTR lpszAsciiUser = m_ProxyData.pProxyUser;
  392. LPCSTR lpszAsciiPass = m_ProxyData.pProxyPass;
  393. ASSERT(strlen(lpszAsciiUser)<=255);
  394. ASSERT(strlen(lpszAsciiPass)<=255);
  395. unsigned char *buffer = new unsigned char[3 + (lpszAsciiUser?strlen(lpszAsciiUser):0) + (lpszAsciiPass?strlen(lpszAsciiPass):0) + 1];
  396. sprintf((char *)buffer, " %s %s", lpszAsciiUser?lpszAsciiUser:"", lpszAsciiPass?lpszAsciiPass:"");
  397. buffer[0]=1;
  398. buffer[1]=static_cast<unsigned char>(strlen(lpszAsciiUser));
  399. buffer[2+strlen(lpszAsciiUser)]=static_cast<unsigned char>(strlen(lpszAsciiPass));
  400. int len=3+strlen(lpszAsciiUser)+strlen(lpszAsciiPass);
  401. int res=SendNext(buffer,len);
  402. delete [] buffer;
  403. if (res==SOCKET_ERROR || res<len)
  404. {
  405. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  406. {
  407. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  408. if (m_nProxyOpID==PROXYOP_CONNECT)
  409. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  410. else
  411. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  412. Reset();
  413. return;
  414. }
  415. }
  416. ClearBuffer();
  417. m_nProxyOpState++;
  418. return;
  419. }
  420. }
  421. //No auth needed
  422. //Send connection request
  423. char *lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  424. char *command=new char[10+strlen(lpszAsciiHost)+1];
  425. memset(command,0,10+strlen(lpszAsciiHost)+1);
  426. command[0]=5;
  427. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  428. command[2]=0;
  429. command[3]=m_nProxyPeerIp?1:3;
  430. int len=4;
  431. if (m_nProxyPeerIp)
  432. {
  433. memcpy(&command[len],&m_nProxyPeerIp,4);
  434. len+=4;
  435. }
  436. else
  437. {
  438. command[len]=strlen(lpszAsciiHost);
  439. strcpy(&command[len+1], lpszAsciiHost);
  440. len += strlen(lpszAsciiHost) + 1;
  441. }
  442. memcpy(&command[len], &m_nProxyPeerPort, 2);
  443. len+=2;
  444. int res=SendNext(command,len);
  445. delete [] command;
  446. if (res==SOCKET_ERROR || res<len)
  447. {
  448. if ( ( WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  449. {
  450. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  451. if (m_nProxyOpID==PROXYOP_CONNECT)
  452. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  453. else
  454. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  455. Reset();
  456. return;
  457. }
  458. }
  459. m_nProxyOpState+=2;
  460. ClearBuffer();
  461. return;
  462. }
  463. else if (m_nProxyOpState==2)
  464. {//Response to the auth request
  465. if (!m_pRecvBuffer)
  466. m_pRecvBuffer=new char[2];
  467. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos, 2-m_nRecvBufferPos);
  468. if (numread==SOCKET_ERROR)
  469. {
  470. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  471. {
  472. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  473. if (m_nProxyOpID==PROXYOP_CONNECT)
  474. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  475. else
  476. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  477. Reset();
  478. }
  479. return;
  480. }
  481. m_nRecvBufferPos+=numread;
  482. if (m_nRecvBufferPos==2)
  483. {
  484. if (m_pRecvBuffer[1]!=0)
  485. {
  486. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_AUTHFAILED, 0);
  487. if (m_nProxyOpID==PROXYOP_CONNECT)
  488. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  489. else
  490. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  491. Reset();
  492. ClearBuffer();
  493. return;
  494. }
  495. char * lpszAsciiHost = m_pProxyPeerHost?m_pProxyPeerHost:"";
  496. char *command = new char[10+strlen(lpszAsciiHost)+1];
  497. memset(command,0,10+strlen(lpszAsciiHost)+1);
  498. command[0]=5;
  499. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2;
  500. command[2]=0;
  501. command[3]=m_nProxyPeerIp?1:3;
  502. int len=4;
  503. if (m_nProxyPeerIp)
  504. {
  505. memcpy(&command[len],&m_nProxyPeerIp,4);
  506. len+=4;
  507. }
  508. else
  509. {
  510. command[len]=strlen(lpszAsciiHost);
  511. strcpy(&command[len+1],lpszAsciiHost);
  512. len+=strlen(lpszAsciiHost)+1;
  513. }
  514. memcpy(&command[len],&m_nProxyPeerPort,2);
  515. len+=2;
  516. int res=SendNext(command,len);
  517. delete [] command;
  518. if (res==SOCKET_ERROR || res<len)
  519. {
  520. if ((WSAGetLastError()!=WSAEWOULDBLOCK) || res<len)
  521. {
  522. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  523. if (m_nProxyOpID==PROXYOP_CONNECT)
  524. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  525. else
  526. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  527. Reset();
  528. return;
  529. }
  530. }
  531. m_nProxyOpState++;
  532. ClearBuffer();
  533. return;
  534. }
  535. }
  536. else if (m_nProxyOpState==3)
  537. {//Response to the connection request
  538. if (!m_pRecvBuffer)
  539. {
  540. m_pRecvBuffer=new char[10];
  541. m_nRecvBufferLen=5;
  542. }
  543. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,m_nRecvBufferLen-m_nRecvBufferPos);
  544. if (numread==SOCKET_ERROR)
  545. {
  546. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  547. {
  548. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  549. if (m_nProxyOpID==PROXYOP_CONNECT)
  550. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  551. else
  552. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  553. Reset();
  554. }
  555. return;
  556. }
  557. m_nRecvBufferPos+=numread;
  558. if (m_nRecvBufferPos==m_nRecvBufferLen)
  559. {
  560. //Check for errors
  561. if (m_pRecvBuffer[1]!=0 || m_pRecvBuffer[0]!=5)
  562. {
  563. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  564. if (m_nProxyOpID==PROXYOP_CONNECT)
  565. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  566. else
  567. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  568. Reset();
  569. ClearBuffer();
  570. return;
  571. }
  572. if (m_nRecvBufferLen==5)
  573. { //Check which kind of address the response contains
  574. if (m_pRecvBuffer[3]==1)
  575. m_nRecvBufferLen=10;
  576. else
  577. {
  578. char *tmp=new char[m_nRecvBufferLen+=m_pRecvBuffer[4]+2];
  579. memcpy(tmp,m_pRecvBuffer,5);
  580. delete [] m_pRecvBuffer;
  581. m_pRecvBuffer=tmp;
  582. m_nRecvBufferLen+=m_pRecvBuffer[4]+2;
  583. }
  584. return;
  585. }
  586. if (m_nProxyOpID==PROXYOP_CONNECT)
  587. {
  588. //OK, we are connected with the remote server
  589. Reset();
  590. ClearBuffer();
  591. TriggerEvent(FD_CONNECT, 0, TRUE);
  592. TriggerEvent(FD_READ, 0, TRUE);
  593. TriggerEvent(FD_WRITE, 0, TRUE);
  594. }
  595. else
  596. {
  597. //Listen socket created
  598. m_nProxyOpState++;
  599. unsigned long ip;
  600. unsigned short port;
  601. ASSERT(m_pRecvBuffer[3]==1);
  602. memcpy(&ip, &m_pRecvBuffer[4], 4);
  603. memcpy(&port, &m_pRecvBuffer[8], 2);
  604. t_ListenSocketCreatedStruct data;
  605. data.ip=ip;
  606. data.nPort=port;
  607. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYSTATUS_LISTENSOCKETCREATED, (int)&data);
  608. }
  609. ClearBuffer();
  610. }
  611. }
  612. else if (m_nProxyOpState==4)
  613. {
  614. if (!m_pRecvBuffer)
  615. m_pRecvBuffer=new char[10];
  616. int numread=ReceiveNext(m_pRecvBuffer+m_nRecvBufferPos,10-m_nRecvBufferPos);
  617. if (numread==SOCKET_ERROR)
  618. {
  619. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  620. {
  621. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  622. if (m_nProxyOpID==PROXYOP_CONNECT)
  623. TriggerEvent(FD_CONNECT, WSAGetLastError(), TRUE);
  624. else
  625. TriggerEvent(FD_ACCEPT, WSAGetLastError(), TRUE);
  626. Reset();
  627. }
  628. return;
  629. }
  630. m_nRecvBufferPos+=numread;
  631. if (m_nRecvBufferPos==10)
  632. {
  633. if (m_pRecvBuffer[1]!=0)
  634. {
  635. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  636. if (m_nProxyOpID==PROXYOP_CONNECT)
  637. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  638. else
  639. {
  640. VERIFY(m_nProxyOpID==PROXYOP_LISTEN);
  641. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  642. }
  643. Reset();
  644. ClearBuffer();
  645. return;
  646. }
  647. //Connection to remote server established
  648. ClearBuffer();
  649. Reset();
  650. TriggerEvent(FD_ACCEPT, 0, TRUE);
  651. TriggerEvent(FD_READ, 0, TRUE);
  652. TriggerEvent(FD_WRITE, 0, TRUE);
  653. }
  654. }
  655. }
  656. if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  657. {
  658. ASSERT (m_nProxyOpID==PROXYOP_CONNECT);
  659. char buffer[9]={0};
  660. for(;;)
  661. {
  662. int numread = ReceiveNext(buffer, m_pStrBuffer?1:8);
  663. if (numread==SOCKET_ERROR)
  664. {
  665. int nError=WSAGetLastError();
  666. if (nError!=WSAEWOULDBLOCK)
  667. {
  668. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  669. Reset();
  670. ClearBuffer();
  671. TriggerEvent(FD_CONNECT, nError, TRUE );
  672. }
  673. return;
  674. }
  675. //Response begins with HTTP/
  676. if (!m_pStrBuffer)
  677. {
  678. m_pStrBuffer = new char[strlen(buffer) + 1];
  679. strcpy(m_pStrBuffer, buffer);
  680. }
  681. else
  682. {
  683. char *tmp = m_pStrBuffer;
  684. m_pStrBuffer = new char[strlen(tmp) + strlen(buffer) + 1];
  685. strcpy(m_pStrBuffer, tmp);
  686. strcpy(m_pStrBuffer + strlen(tmp), buffer);
  687. delete [] tmp;
  688. }
  689. memset(buffer, 0, 9);
  690. const char start[] = "HTTP/";
  691. if (memcmp(start, m_pStrBuffer, (strlen(start)>strlen(m_pStrBuffer)) ? strlen(m_pStrBuffer) : strlen(start)))
  692. {
  693. char* str = new char[strlen("No valid HTTP reponse") + 1];
  694. strcpy(str, "No valid HTTP reponse");
  695. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, str);
  696. Reset();
  697. ClearBuffer();
  698. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE );
  699. return;
  700. }
  701. char *pos = strstr(m_pStrBuffer, "\r\n");
  702. if (pos)
  703. {
  704. char *pos2 = strstr(m_pStrBuffer, " ");
  705. if (!pos2 || *(pos2+1)!='2' || pos2>pos)
  706. {
  707. char *tmp = new char[pos-m_pStrBuffer + 1];
  708. tmp[pos-m_pStrBuffer] = 0;
  709. strncpy(tmp, m_pStrBuffer, pos-m_pStrBuffer);
  710. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0, tmp);
  711. Reset();
  712. ClearBuffer();
  713. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE );
  714. return;
  715. }
  716. }
  717. if (strlen(m_pStrBuffer)>3 && !memcmp(m_pStrBuffer+strlen(m_pStrBuffer)-4, "\r\n\r\n", 4)) //End of the HTTP header
  718. {
  719. Reset();
  720. ClearBuffer();
  721. TriggerEvent(FD_CONNECT, 0, TRUE);
  722. TriggerEvent(FD_READ, 0, TRUE);
  723. TriggerEvent(FD_WRITE, 0, TRUE);
  724. return;
  725. }
  726. }
  727. }
  728. }
  729. BOOL CAsyncProxySocketLayer::Connect( LPCTSTR lpszHostAddress, UINT nHostPort )
  730. {
  731. if (!m_ProxyData.nProxyType)
  732. //Connect normally because there is no proxy
  733. return ConnectNext(lpszHostAddress, nHostPort);
  734. USES_CONVERSION;
  735. //Translate the host address
  736. ASSERT(lpszHostAddress != NULL);
  737. if (m_ProxyData.nProxyType != PROXYTYPE_SOCKS4)
  738. {
  739. // We can send hostname to proxy, no need to resolve it
  740. //Connect to proxy server
  741. BOOL res = ConnectNext(A2CT(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  742. if (!res)
  743. {
  744. if (WSAGetLastError() != WSAEWOULDBLOCK)
  745. {
  746. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  747. return FALSE;
  748. }
  749. }
  750. m_nProxyPeerPort = htons((u_short)nHostPort);
  751. m_nProxyPeerIp = 0;
  752. delete [] m_pProxyPeerHost;
  753. m_pProxyPeerHost = new char[_tcslen(lpszHostAddress)+1];
  754. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  755. m_nProxyOpID=PROXYOP_CONNECT;
  756. return TRUE;
  757. }
  758. SOCKADDR_IN sockAddr;
  759. memset(&sockAddr,0,sizeof(sockAddr));
  760. LPCSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  761. sockAddr.sin_family = AF_INET;
  762. sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  763. if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  764. {
  765. LPHOSTENT lphost;
  766. lphost = gethostbyname(lpszAscii);
  767. if (lphost != NULL)
  768. sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  769. else
  770. {
  771. //Can't resolve hostname
  772. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_CANTRESOLVEHOST, 0);
  773. WSASetLastError(WSAEINVAL);
  774. return FALSE;
  775. }
  776. }
  777. sockAddr.sin_port = htons((u_short)nHostPort);
  778. BOOL res=CAsyncProxySocketLayer::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  779. if (res || WSAGetLastError()==WSAEWOULDBLOCK)
  780. {
  781. delete [] m_pProxyPeerHost;
  782. m_pProxyPeerHost = new char[strlen(T2CA(lpszHostAddress))+1];
  783. strcpy(m_pProxyPeerHost, T2CA(lpszHostAddress));
  784. }
  785. return res;
  786. }
  787. BOOL CAsyncProxySocketLayer::Connect( const SOCKADDR* lpSockAddr, int nSockAddrLen )
  788. {
  789. if (!m_ProxyData.nProxyType)
  790. //Connect normally because there is no proxy
  791. return ConnectNext(lpSockAddr, nSockAddrLen );
  792. LPSOCKADDR_IN sockAddr=(LPSOCKADDR_IN)lpSockAddr;
  793. //Save server details
  794. m_nProxyPeerIp=sockAddr->sin_addr.S_un.S_addr;
  795. m_nProxyPeerPort=sockAddr->sin_port;
  796. delete [] m_pProxyPeerHost;
  797. m_pProxyPeerHost = NULL;
  798. m_nProxyOpID=PROXYOP_CONNECT;
  799. USES_CONVERSION;
  800. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  801. if (!res)
  802. {
  803. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  804. {
  805. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  806. return FALSE;
  807. }
  808. }
  809. return res;
  810. }
  811. void CAsyncProxySocketLayer::OnConnect(int nErrorCode)
  812. {
  813. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  814. {
  815. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  816. return;
  817. }
  818. ASSERT(m_nProxyOpID);
  819. if (!m_nProxyOpID)
  820. {
  821. //This should not happen
  822. return;
  823. };
  824. if (nErrorCode)
  825. { //Can't connect to proxy
  826. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  827. if (m_nProxyOpID==PROXYOP_CONNECT)
  828. TriggerEvent(FD_CONNECT, nErrorCode, TRUE);
  829. else
  830. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  831. Reset();
  832. ClearBuffer();
  833. return;
  834. }
  835. if (m_nProxyOpID==PROXYOP_CONNECT || m_nProxyOpID==PROXYOP_LISTEN)
  836. {
  837. if (m_nProxyOpState)
  838. //Somehow OnConnect has been called more than once
  839. return;
  840. ASSERT(m_ProxyData.nProxyType!=PROXYTYPE_NOPROXY);
  841. ClearBuffer();
  842. //Send the initial request
  843. if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS4 || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  844. { //SOCKS4 proxy
  845. //Send request
  846. LPCSTR lpszAscii = m_pProxyPeerHost?m_pProxyPeerHost:"";
  847. char *command=new char [9+strlen(lpszAscii)+1];
  848. memset(command,0,9+strlen(lpszAscii)+1);
  849. int len=9;
  850. command[0]=4;
  851. command[1]=(m_nProxyOpID==PROXYOP_CONNECT)?1:2; //CONNECT or BIND request
  852. memcpy(&command[2],&m_nProxyPeerPort,2); //Copy target address
  853. if (!m_nProxyPeerIp || m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A)
  854. {
  855. ASSERT(m_ProxyData.nProxyType==PROXYTYPE_SOCKS4A);
  856. ASSERT(strcmp(lpszAscii, ""));
  857. //Set the IP to 0.0.0.x (x is nonzero)
  858. command[4]=0;
  859. command[5]=0;
  860. command[6]=0;
  861. command[7]=1;
  862. //Add host as URL
  863. strcpy(&command[9],lpszAscii);
  864. len+=strlen(lpszAscii)+1;
  865. }
  866. else
  867. memcpy(&command[4],&m_nProxyPeerIp,4);
  868. int res=SendNext(command,len); //Send command
  869. delete [] command;
  870. int nErrorCode=WSAGetLastError();
  871. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  872. {
  873. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  874. if (m_nProxyOpID==PROXYOP_CONNECT)
  875. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  876. else
  877. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  878. Reset();
  879. ClearBuffer();
  880. return;
  881. }
  882. else if (res<len)
  883. {
  884. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  885. if (m_nProxyOpID==PROXYOP_CONNECT)
  886. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  887. else
  888. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  889. Reset();
  890. ClearBuffer();
  891. return;
  892. }
  893. }
  894. else if (m_ProxyData.nProxyType==PROXYTYPE_SOCKS5)
  895. { //SOCKS5 proxy
  896. //Send initialization request
  897. unsigned char command[10];
  898. memset(command,0,10);
  899. command[0]=5;
  900. //CAsyncProxySocketLayer supports to logon types: No logon and
  901. //cleartext username/password (if set) logon
  902. command[1]=m_ProxyData.bUseLogon?2:1; //Number of logon types
  903. command[2]=m_ProxyData.bUseLogon?2:0; //2=user/pass, 0=no logon
  904. int len=m_ProxyData.bUseLogon?4:3; //length of request
  905. int res=SendNext(command,len);
  906. int nErrorCode=WSAGetLastError();
  907. if (res==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  908. {
  909. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  910. if (m_nProxyOpID==PROXYOP_CONNECT)
  911. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  912. else
  913. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  914. Reset();
  915. ClearBuffer();
  916. return;
  917. }
  918. else if (res<len)
  919. {
  920. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  921. if (m_nProxyOpID==PROXYOP_CONNECT)
  922. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  923. else
  924. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  925. Reset();
  926. ClearBuffer();
  927. return;
  928. }
  929. }
  930. else if (m_ProxyData.nProxyType==PROXYTYPE_HTTP11)
  931. {
  932. char str[4096]; //This should be large enough
  933. char * pHost = NULL;
  934. if (m_pProxyPeerHost && *m_pProxyPeerHost)
  935. {
  936. pHost = new char[strlen(m_pProxyPeerHost)+1];
  937. strcpy(pHost, m_pProxyPeerHost);
  938. }
  939. else
  940. {
  941. pHost = new char[16];
  942. sprintf(pHost, "%d.%d.%d.%d", m_nProxyPeerIp%256, (m_nProxyPeerIp>>8) % 256, (m_nProxyPeerIp>>16) %256, m_nProxyPeerIp>>24);
  943. }
  944. if (!m_ProxyData.bUseLogon)
  945. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n\r\n", pHost, ntohs(m_nProxyPeerPort),
  946. pHost, ntohs(m_nProxyPeerPort));
  947. else
  948. {
  949. sprintf(str, "CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n", pHost, ntohs(m_nProxyPeerPort),
  950. pHost, ntohs(m_nProxyPeerPort));
  951. char userpass[4096];
  952. sprintf(userpass, "%s:%s", m_ProxyData.pProxyUser?m_ProxyData.pProxyUser:"", m_ProxyData.pProxyPass?m_ProxyData.pProxyPass:"");
  953. char base64str[4096];
  954. CBase64Coding base64coding;
  955. if (!base64coding.Encode(userpass, strlen(userpass), base64str))
  956. {
  957. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  958. if (m_nProxyOpID==PROXYOP_CONNECT)
  959. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  960. else
  961. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  962. Reset();
  963. ClearBuffer();
  964. delete [] pHost;
  965. return;
  966. }
  967. strcat(str, "Authorization: Basic ");
  968. strcat(str, base64str);
  969. strcat(str, "\r\nProxy-Authorization: Basic ");
  970. strcat(str, base64str);
  971. strcat(str, "\r\n\r\n");
  972. }
  973. delete [] pHost;
  974. int numsent=SendNext(str, strlen(str) );
  975. int nErrorCode=WSAGetLastError();
  976. if (numsent==SOCKET_ERROR)//nErrorCode!=WSAEWOULDBLOCK)
  977. {
  978. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  979. if (m_nProxyOpID==PROXYOP_CONNECT)
  980. TriggerEvent(FD_CONNECT, (nErrorCode==WSAEWOULDBLOCK)?WSAECONNABORTED:nErrorCode, TRUE);
  981. else
  982. TriggerEvent(FD_ACCEPT, nErrorCode, TRUE);
  983. Reset();
  984. ClearBuffer();
  985. return;
  986. }
  987. else if ( numsent < static_cast<int>( strlen(str) ) )
  988. {
  989. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_REQUESTFAILED, 0);
  990. if (m_nProxyOpID==PROXYOP_CONNECT)
  991. TriggerEvent(FD_CONNECT, WSAECONNABORTED, TRUE);
  992. else
  993. TriggerEvent(FD_ACCEPT, WSAECONNABORTED, TRUE);
  994. Reset();
  995. ClearBuffer();
  996. return;
  997. }
  998. m_nProxyOpState++;
  999. return;
  1000. }
  1001. else
  1002. ASSERT(FALSE);
  1003. //Now we'll wait for the response, handled in OnReceive
  1004. m_nProxyOpState++;
  1005. }
  1006. }
  1007. void CAsyncProxySocketLayer::ClearBuffer()
  1008. {
  1009. delete [] m_pStrBuffer;
  1010. m_pStrBuffer = NULL;
  1011. if (m_pRecvBuffer)
  1012. {
  1013. delete [] m_pRecvBuffer;
  1014. m_pRecvBuffer=0;
  1015. }
  1016. m_nRecvBufferLen=0;
  1017. m_nRecvBufferPos=0;
  1018. }
  1019. BOOL CAsyncProxySocketLayer::Listen( int nConnectionBacklog)
  1020. {
  1021. if (GetProxyType()==PROXYTYPE_NOPROXY)
  1022. return ListenNext(nConnectionBacklog);
  1023. USES_CONVERSION;
  1024. //Connect to proxy server
  1025. BOOL res = ConnectNext(A2T(m_ProxyData.pProxyHost), m_ProxyData.nProxyPort);
  1026. if (!res)
  1027. {
  1028. if (WSAGetLastError()!=WSAEWOULDBLOCK)
  1029. {
  1030. DoLayerCallback(LAYERCALLBACK_LAYERSPECIFIC, PROXYERROR_NOCONN, 0);
  1031. return FALSE;
  1032. }
  1033. }
  1034. m_nProxyPeerPort=0;
  1035. m_nProxyPeerIp=(unsigned int)nConnectionBacklog;
  1036. m_nProxyOpID=PROXYOP_LISTEN;
  1037. return TRUE;
  1038. }
  1039. #ifdef _AFX
  1040. BOOL CAsyncProxySocketLayer::GetPeerName(CString &rPeerAddress, UINT &rPeerPort)
  1041. {
  1042. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  1043. return GetPeerNameNext(rPeerAddress, rPeerPort);
  1044. if (GetLayerState()==notsock)
  1045. {
  1046. WSASetLastError(WSAENOTSOCK);
  1047. return FALSE;
  1048. }
  1049. else if (GetLayerState()!=connected)
  1050. {
  1051. WSASetLastError(WSAENOTCONN);
  1052. return FALSE;
  1053. }
  1054. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  1055. {
  1056. WSASetLastError(WSAENOTCONN);
  1057. return FALSE;
  1058. }
  1059. ASSERT(m_ProxyData.nProxyType);
  1060. BOOL res=GetPeerNameNext( rPeerAddress, rPeerPort );
  1061. if (res)
  1062. {
  1063. rPeerPort=ntohs(m_nProxyPeerPort);
  1064. rPeerAddress.Format(_T("%d.%d.%d.%d"), m_nProxyPeerIp%256,(m_nProxyPeerIp>>8)%256,(m_nProxyPeerIp>>16)%256, m_nProxyPeerIp>>24);
  1065. }
  1066. return res;
  1067. }
  1068. #endif
  1069. BOOL CAsyncProxySocketLayer::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1070. {
  1071. if (m_ProxyData.nProxyType==PROXYTYPE_NOPROXY)
  1072. return GetPeerNameNext(lpSockAddr, lpSockAddrLen);
  1073. if (GetLayerState()==notsock)
  1074. {
  1075. WSASetLastError(WSAENOTSOCK);
  1076. return FALSE;
  1077. }
  1078. else if (GetLayerState()!=connected)
  1079. {
  1080. WSASetLastError(WSAENOTCONN);
  1081. return FALSE;
  1082. }
  1083. else if (!m_nProxyPeerIp || !m_nProxyPeerPort)
  1084. {
  1085. WSASetLastError(WSAENOTCONN);
  1086. return FALSE;
  1087. }
  1088. ASSERT(m_ProxyData.nProxyType);
  1089. BOOL res=GetPeerNameNext(lpSockAddr,lpSockAddrLen);
  1090. if (res)
  1091. {
  1092. LPSOCKADDR_IN addr=(LPSOCKADDR_IN)lpSockAddr;
  1093. addr->sin_port=m_nProxyPeerPort;
  1094. addr->sin_addr.S_un.S_addr=m_nProxyPeerIp;
  1095. }
  1096. return res;
  1097. }
  1098. int CAsyncProxySocketLayer::GetProxyType() const
  1099. {
  1100. return m_ProxyData.nProxyType;
  1101. }
  1102. void CAsyncProxySocketLayer::Close()
  1103. {
  1104. delete [] m_ProxyData.pProxyHost;
  1105. delete [] m_ProxyData.pProxyUser;
  1106. delete [] m_ProxyData.pProxyPass;
  1107. delete [] m_pProxyPeerHost;
  1108. m_ProxyData.pProxyHost = NULL;
  1109. m_ProxyData.pProxyUser = NULL;
  1110. m_ProxyData.pProxyPass = NULL;
  1111. m_pProxyPeerHost = NULL;
  1112. ClearBuffer();
  1113. Reset();
  1114. CloseNext();
  1115. }
  1116. void CAsyncProxySocketLayer::Reset()
  1117. {
  1118. m_nProxyOpState=0;
  1119. m_nProxyOpID=0;
  1120. }
  1121. int CAsyncProxySocketLayer::Send(const void* lpBuf, int nBufLen, int nFlags)
  1122. {
  1123. if (m_nProxyOpID)
  1124. {
  1125. WSASetLastError(WSAEWOULDBLOCK);
  1126. return SOCKET_ERROR;
  1127. }
  1128. return SendNext(lpBuf, nBufLen, nFlags);
  1129. }
  1130. int CAsyncProxySocketLayer::Receive(void* lpBuf, int nBufLen, int nFlags)
  1131. {
  1132. if (m_nProxyOpID)
  1133. {
  1134. WSASetLastError(WSAEWOULDBLOCK);
  1135. return SOCKET_ERROR;
  1136. }
  1137. return ReceiveNext(lpBuf, nBufLen, nFlags);
  1138. }
  1139. BOOL CAsyncProxySocketLayer::PrepareListen(unsigned long ip)
  1140. {
  1141. if (GetLayerState()!=notsock && GetLayerState()!=unconnected)
  1142. return FALSE;
  1143. m_nProxyPeerIp=ip;
  1144. return TRUE;
  1145. }
  1146. BOOL CAsyncProxySocketLayer::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  1147. {
  1148. if (!m_ProxyData.nProxyType)
  1149. return AcceptNext(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  1150. GetPeerName(lpSockAddr, lpSockAddrLen);
  1151. return TRUE;
  1152. }