TransferSocket.cpp 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165
  1. //---------------------------------------------------------------------------
  2. #include "stdafx.h"
  3. #include "TransferSocket.h"
  4. #include "mainthread.h"
  5. #include "AsyncProxySocketLayer.h"
  6. #ifndef MPEXT_NO_GSS
  7. #include "AsyncGssSocketLayer.h"
  8. #endif
  9. #define BUFSIZE 16384
  10. #define STATE_WAITING 0
  11. #define STATE_STARTING 1
  12. #define STATE_STARTED 2
  13. /////////////////////////////////////////////////////////////////////////////
  14. // CTransferSocket
  15. CTransferSocket::CTransferSocket(CFtpControlSocket *pOwner, int nMode)
  16. {
  17. DebugAssert(pOwner);
  18. InitIntern(pOwner->GetIntern());
  19. m_pOwner = pOwner;
  20. m_nMode = nMode;
  21. m_nTransferState = STATE_WAITING;
  22. m_bCheckTimeout = FALSE;
  23. m_pBuffer = 0;
  24. #ifndef MPEXT_NO_ZLIB
  25. m_pBuffer2 = 0;
  26. #endif
  27. m_bufferpos = 0;
  28. m_pFile = 0;
  29. m_bListening = FALSE;
  30. m_bSentClose = FALSE;
  31. m_nInternalMessageID = 0;
  32. m_transferdata.transfersize = 0;
  33. m_transferdata.transferleft = 0;
  34. m_nNotifyWaiting = 0;
  35. m_bShutDown = FALSE;
  36. UpdateStatusBar(true);
  37. m_pProxyLayer = NULL;
  38. m_pSslLayer = NULL;
  39. #ifndef MPEXT_NO_GSS
  40. m_pGssLayer = NULL;
  41. #endif
  42. if (m_nMode & CSMODE_LIST)
  43. {
  44. m_pListResult = new CFtpListResult(pOwner->m_CurrentServer, &pOwner->m_bUTF8);
  45. m_pListResult->InitIntern(GetIntern());
  46. }
  47. else
  48. m_pListResult = 0;
  49. m_LastUpdateTime.QuadPart = 0;
  50. #ifndef MPEXT_NO_ZLIB
  51. memset(&m_zlibStream, 0, sizeof(m_zlibStream));
  52. m_useZlib = false;
  53. #endif
  54. }
  55. CTransferSocket::~CTransferSocket()
  56. {
  57. delete [] m_pBuffer;
  58. #ifndef MPEXT_NO_ZLIB
  59. delete [] m_pBuffer2;
  60. #endif
  61. GetIntern()->PostMessage(FZ_MSG_MAKEMSG(FZ_MSG_TRANSFERSTATUS, 0), 0);
  62. Close();
  63. RemoveAllLayers();
  64. delete m_pProxyLayer;
  65. delete m_pSslLayer;
  66. #ifndef MPEXT_NO_GSS
  67. delete m_pGssLayer;
  68. #endif
  69. m_pOwner->RemoveActiveTransfer();
  70. delete m_pListResult;
  71. #ifndef MPEXT_NO_ZLIB
  72. if (m_useZlib)
  73. {
  74. if (m_nMode & CSMODE_UPLOAD)
  75. deflateEnd(&m_zlibStream);
  76. else
  77. inflateEnd(&m_zlibStream);
  78. }
  79. #endif
  80. }
  81. /////////////////////////////////////////////////////////////////////////////
  82. // Member-Funktion CTransferSocket
  83. void CTransferSocket::OnReceive(int nErrorCode)
  84. {
  85. if (GetState() != connected && GetState() != attached && GetState() != closed)
  86. return;
  87. if (m_nTransferState == STATE_WAITING)
  88. {
  89. m_nNotifyWaiting |= FD_READ;
  90. return;
  91. }
  92. if (m_bSentClose)
  93. return;
  94. if (m_bListening)
  95. return;
  96. if (m_nMode&CSMODE_LIST)
  97. {
  98. if (m_nTransferState == STATE_STARTING)
  99. OnConnect(0);
  100. char *buffer = new char[BUFSIZE];
  101. int numread = CAsyncSocketEx::Receive(buffer, BUFSIZE);
  102. if (numread != SOCKET_ERROR && numread)
  103. {
  104. m_LastActiveTime = CTime::GetCurrentTime();
  105. #ifndef MPEXT_NO_ZLIB
  106. if (m_useZlib)
  107. {
  108. m_zlibStream.next_in = (Bytef *)buffer;
  109. m_zlibStream.avail_in = numread;
  110. char *out = new char[BUFSIZE];
  111. m_zlibStream.next_out = (Bytef *)out;
  112. m_zlibStream.avail_out = BUFSIZE;
  113. int res = inflate(&m_zlibStream, 0);
  114. while (res == Z_OK)
  115. {
  116. m_pListResult->AddData(out, BUFSIZE - m_zlibStream.avail_out);
  117. out = new char[BUFSIZE];
  118. m_zlibStream.next_out = (Bytef *)out;
  119. m_zlibStream.avail_out = BUFSIZE;
  120. res = inflate(&m_zlibStream, 0);
  121. }
  122. delete [] buffer;
  123. if (res == Z_STREAM_END)
  124. m_pListResult->AddData(out, BUFSIZE - m_zlibStream.avail_out);
  125. else if (res != Z_OK && res != Z_BUF_ERROR)
  126. {
  127. delete [] out;
  128. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  129. return;
  130. }
  131. else
  132. delete [] out;
  133. }
  134. else
  135. #endif
  136. m_pListResult->AddData(buffer, numread);
  137. m_transferdata.transfersize += numread;
  138. t_ffam_transferstatus *status = new t_ffam_transferstatus;
  139. status->bFileTransfer = FALSE;
  140. status->transfersize = -1;
  141. status->bytes = m_transferdata.transfersize;
  142. GetIntern()->PostMessage(FZ_MSG_MAKEMSG(FZ_MSG_TRANSFERSTATUS, 0), (LPARAM)status);
  143. }
  144. else
  145. delete [] buffer;
  146. if (!numread)
  147. {
  148. CloseAndEnsureSendClose(0);
  149. }
  150. if (numread == SOCKET_ERROR)
  151. {
  152. int nError = GetLastError();
  153. if (nError == WSAENOTCONN)
  154. {
  155. //Not yet connected
  156. return;
  157. }
  158. else if (m_pSslLayer && nError == WSAESHUTDOWN)
  159. {
  160. // Do nothing, wait for shutdown complete notification.
  161. return;
  162. }
  163. else if (nError != WSAEWOULDBLOCK)
  164. {
  165. LogError(nError);
  166. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  167. }
  168. }
  169. }
  170. else if (m_nMode & CSMODE_DOWNLOAD)
  171. {
  172. if (m_nTransferState == STATE_STARTING)
  173. OnConnect(0);
  174. bool beenWaiting = false;
  175. _int64 ableToRead;
  176. if (GetState() != closed)
  177. ableToRead = m_pOwner->GetAbleToTransferSize(CFtpControlSocket::download, beenWaiting);
  178. else
  179. ableToRead = BUFSIZE;
  180. if (!beenWaiting)
  181. DebugAssert(ableToRead);
  182. else if (!ableToRead)
  183. {
  184. TriggerEvent(FD_READ);
  185. return;
  186. }
  187. if (!m_pBuffer)
  188. m_pBuffer = new char[BUFSIZE];
  189. int numread = CAsyncSocketEx::Receive(m_pBuffer, static_cast<int>(ableToRead));
  190. if (numread!=SOCKET_ERROR)
  191. {
  192. m_pOwner->SpeedLimitAddTransferredBytes(CFtpControlSocket::download, numread);
  193. }
  194. if (!numread)
  195. {
  196. CloseAndEnsureSendClose(0);
  197. return;
  198. }
  199. if (numread == SOCKET_ERROR)
  200. {
  201. int nError = GetLastError();
  202. if (nError == WSAENOTCONN)
  203. {
  204. //Not yet connected
  205. return;
  206. }
  207. else if (m_pSslLayer && nError == WSAESHUTDOWN)
  208. {
  209. // Do nothing, wait for shutdown complete notification.
  210. return;
  211. }
  212. else if (nError != WSAEWOULDBLOCK)
  213. {
  214. LogError(nError);
  215. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  216. }
  217. UpdateStatusBar(false);
  218. return;
  219. }
  220. int written = 0;
  221. m_LastActiveTime = CTime::GetCurrentTime();
  222. TRY
  223. {
  224. #ifndef MPEXT_NO_ZLIB
  225. if (m_useZlib)
  226. {
  227. if (!m_pBuffer2)
  228. m_pBuffer2 = new char[BUFSIZE];
  229. m_zlibStream.next_in = (Bytef *)m_pBuffer;
  230. m_zlibStream.avail_in = numread;
  231. m_zlibStream.next_out = (Bytef *)m_pBuffer2;
  232. m_zlibStream.avail_out = BUFSIZE;
  233. int res = inflate(&m_zlibStream, 0);
  234. while (res == Z_OK)
  235. {
  236. m_pFile->Write(m_pBuffer2, BUFSIZE - m_zlibStream.avail_out);
  237. written += BUFSIZE - m_zlibStream.avail_out;
  238. m_zlibStream.next_out = (Bytef *)m_pBuffer2;
  239. m_zlibStream.avail_out = BUFSIZE;
  240. res = inflate(&m_zlibStream, 0);
  241. }
  242. if (res == Z_STREAM_END)
  243. {
  244. m_pFile->Write(m_pBuffer2, BUFSIZE - m_zlibStream.avail_out);
  245. written += BUFSIZE - m_zlibStream.avail_out;
  246. }
  247. else if (res != Z_OK && res != Z_BUF_ERROR)
  248. {
  249. m_pOwner->ShowStatus(L"Compression error", FZ_LOG_ERROR);
  250. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  251. return;
  252. }
  253. }
  254. else
  255. #endif
  256. {
  257. m_pFile->Write(m_pBuffer, numread);
  258. written = numread;
  259. }
  260. }
  261. CATCH(CFileException,e)
  262. {
  263. LPTSTR msg = new TCHAR[BUFSIZE];
  264. if (e->GetErrorMessage(msg, BUFSIZE))
  265. m_pOwner->ShowStatus(msg, FZ_LOG_ERROR);
  266. delete [] msg;
  267. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  268. return;
  269. }
  270. END_CATCH;
  271. m_transferdata.transferleft -= written;
  272. UpdateStatusBar(false);
  273. }
  274. }
  275. void CTransferSocket::SetBuffers()
  276. {
  277. /* Set internal socket send buffer
  278. * this should fix the speed problems some users have reported
  279. */
  280. DWORD value = 0;
  281. int len = sizeof(value);
  282. GetSockOpt(SO_SNDBUF, &value, &len);
  283. int sndbuf = GetOptionVal(OPTION_MPEXT_SNDBUF);
  284. if (value < sndbuf)
  285. {
  286. value = sndbuf;
  287. SetSockOpt(SO_SNDBUF, &value, sizeof(value));
  288. }
  289. // For now we increase receive buffer, whenever send buffer is set.
  290. // The size is not configurable. The constant taken from FZ.
  291. if (sndbuf > 0)
  292. {
  293. value = 0;
  294. len = sizeof(value);
  295. GetSockOpt(SO_RCVBUF, &value, &len);
  296. int rcvbuf = 4 * 1024 * 1024;
  297. if (value < rcvbuf)
  298. {
  299. value = rcvbuf;
  300. SetSockOpt(SO_RCVBUF, &value, sizeof(value));
  301. }
  302. }
  303. }
  304. void CTransferSocket::OnAccept(int nErrorCode)
  305. {
  306. m_bListening=FALSE;
  307. CAsyncSocketEx tmp;
  308. Accept(tmp);
  309. SOCKET socket=tmp.Detach();
  310. CAsyncSocketEx::Close();
  311. Attach(socket);
  312. SetBuffers();
  313. if (m_nTransferState == STATE_STARTING)
  314. {
  315. m_nTransferState = STATE_STARTED;
  316. if (m_pSslLayer)
  317. {
  318. AddLayer(m_pSslLayer);
  319. int res = m_pSslLayer->InitSSLConnection(true, m_pOwner->m_pSslLayer,
  320. GetOptionVal(OPTION_MPEXT_SSLSESSIONREUSE),
  321. GetOptionVal(OPTION_MPEXT_MIN_TLS_VERSION),
  322. GetOptionVal(OPTION_MPEXT_MAX_TLS_VERSION));
  323. if (res == SSL_FAILURE_INITSSL)
  324. m_pOwner->ShowStatus(IDS_ERRORMSG_CANTINITSSL, FZ_LOG_ERROR);
  325. if (res)
  326. {
  327. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  328. return;
  329. }
  330. }
  331. #ifndef MPEXT_NO_GSS
  332. if (m_pGssLayer)
  333. {
  334. AddLayer(m_pGssLayer);
  335. }
  336. #endif
  337. m_LastActiveTime = CTime::GetCurrentTime();
  338. }
  339. }
  340. void CTransferSocket::ConfigureSocket()
  341. {
  342. // Note that FileZilla re-enables Nagle's alg during TLS negotiation.
  343. // Following post claims that TCP_NODELAY
  344. // has to be set before connect()
  345. // http://stackoverflow.com/questions/22583941/what-is-the-workaround-for-tcp-delayed-acknowledgment/25871250#25871250
  346. int nodelay = GetOptionVal(OPTION_MPEXT_NODELAY);
  347. if (nodelay != 0)
  348. {
  349. BOOL bvalue = TRUE;
  350. SetSockOpt(TCP_NODELAY, &bvalue, sizeof(bvalue), IPPROTO_TCP);
  351. }
  352. CAsyncSocketEx::ConfigureSocket();
  353. }
  354. void CTransferSocket::OnConnect(int nErrorCode)
  355. {
  356. if (nErrorCode)
  357. {
  358. TCHAR buffer[1000];
  359. memset(buffer, 0, sizeof(buffer));
  360. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, nErrorCode, 0, buffer, 999, 0);
  361. CString str;
  362. str.Format(IDS_ERRORMSG_CANTOPENTRANSFERCHANNEL,buffer);
  363. str.Replace( L"\n", L"\0" );
  364. str.Replace( L"\r", L"\0" );
  365. m_pOwner->ShowStatus(str, FZ_LOG_ERROR);
  366. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  367. }
  368. else
  369. {
  370. SetBuffers();
  371. m_pOwner->ShowStatus(L"Data connection opened", FZ_LOG_INFO);
  372. }
  373. if (m_nTransferState == STATE_WAITING)
  374. {
  375. // OnReceive (invoked by m_nNotifyWaiting including FD_READ)
  376. // will call back to OnConnected (as we won't be connected yet).
  377. // This is needed for file transfers only, where SetActive is
  378. // called only after 1xx response to RETR (and similar) arrives.
  379. // But we get FD_CONNECT earlier, hence we get to this branch.
  380. // With directory listing, SetActive is called before Connect,
  381. // so we are already STATE_STARTING on FD_CONNECT.
  382. // It should probably behave the same in both scenarios.
  383. m_nNotifyWaiting |= FD_READ;
  384. }
  385. else if (m_nTransferState == STATE_STARTING)
  386. {
  387. m_nTransferState = STATE_STARTED;
  388. m_LastActiveTime=CTime::GetCurrentTime();
  389. if (m_pSslLayer)
  390. {
  391. AddLayer(m_pSslLayer);
  392. int res = m_pSslLayer->InitSSLConnection(true, m_pOwner->m_pSslLayer,
  393. GetOptionVal(OPTION_MPEXT_SSLSESSIONREUSE),
  394. GetOptionVal(OPTION_MPEXT_MIN_TLS_VERSION),
  395. GetOptionVal(OPTION_MPEXT_MAX_TLS_VERSION));
  396. if (res == SSL_FAILURE_INITSSL)
  397. {
  398. m_pOwner->ShowStatus(IDS_ERRORMSG_CANTINITSSL, FZ_LOG_ERROR);
  399. }
  400. if (res)
  401. {
  402. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  403. return;
  404. }
  405. }
  406. #ifndef MPEXT_NO_GSS
  407. if (m_pGssLayer)
  408. {
  409. AddLayer(m_pGssLayer);
  410. }
  411. #endif
  412. }
  413. }
  414. void CTransferSocket::OnClose(int nErrorCode)
  415. {
  416. if (m_nTransferState == STATE_WAITING)
  417. {
  418. m_nNotifyWaiting |= FD_CLOSE;
  419. return;
  420. }
  421. m_pOwner->ShowStatus(L"Data connection closed", FZ_LOG_INFO);
  422. OnReceive(0);
  423. CloseAndEnsureSendClose(0);
  424. }
  425. int CTransferSocket::CheckForTimeout(int delay)
  426. {
  427. UpdateStatusBar(false);
  428. if (!m_bCheckTimeout)
  429. {
  430. // we are closed, so make sure the FTP control socket is itself checking for
  431. // timeout as we are not
  432. return 0;
  433. }
  434. CTimeSpan span = CTime::GetCurrentTime()-m_LastActiveTime;
  435. if (span.GetTotalSeconds()>=delay)
  436. {
  437. m_pOwner->ShowTimeoutError(IDS_DATA_CONNECTION);
  438. CloseAndEnsureSendClose(CSMODE_TRANSFERTIMEOUT);
  439. return 2;
  440. }
  441. return 1;
  442. }
  443. void CTransferSocket::SetActive()
  444. {
  445. if (m_nTransferState == STATE_WAITING)
  446. m_nTransferState = STATE_STARTING;
  447. m_bCheckTimeout = TRUE;
  448. m_LastActiveTime = CTime::GetCurrentTime();
  449. if (m_nNotifyWaiting & FD_READ)
  450. OnReceive(0);
  451. if (m_nNotifyWaiting & FD_WRITE)
  452. OnSend(0);
  453. if (m_nNotifyWaiting & FD_CLOSE)
  454. OnClose(0);
  455. }
  456. void CTransferSocket::OnSend(int nErrorCode)
  457. {
  458. if (m_nTransferState == STATE_WAITING)
  459. {
  460. m_nNotifyWaiting |= FD_WRITE;
  461. return;
  462. }
  463. if (m_bSentClose)
  464. {
  465. return;
  466. }
  467. if (m_bListening)
  468. {
  469. return;
  470. }
  471. if (!(m_nMode&CSMODE_UPLOAD))
  472. {
  473. return;
  474. }
  475. if (m_nTransferState == STATE_STARTING)
  476. {
  477. OnConnect(0);
  478. }
  479. #ifndef MPEXT_NO_ZLIB
  480. if (m_useZlib)
  481. {
  482. if (!m_pBuffer)
  483. {
  484. m_pBuffer = new char[BUFSIZE];
  485. m_bufferpos = 0;
  486. m_zlibStream.next_out = (Bytef *)m_pBuffer;
  487. m_zlibStream.avail_out = BUFSIZE;
  488. }
  489. if (!m_pBuffer2)
  490. {
  491. m_pBuffer2 = new char[BUFSIZE];
  492. m_zlibStream.next_in = (Bytef *)m_pBuffer2;
  493. }
  494. bool beenWaiting = false;
  495. while (true)
  496. {
  497. int numsend;
  498. if (!m_zlibStream.avail_in)
  499. {
  500. if (m_pFile)
  501. {
  502. DWORD numread;
  503. numread = ReadDataFromFile(m_pBuffer2, BUFSIZE);
  504. if (numread < 0)
  505. {
  506. return;
  507. }
  508. m_transferdata.transferleft -= numread;
  509. m_zlibStream.next_in = (Bytef *)m_pBuffer2;
  510. m_zlibStream.avail_in = numread;
  511. if (numread < BUFSIZE)
  512. m_pFile = 0;
  513. }
  514. }
  515. if (!m_zlibStream.avail_out)
  516. {
  517. if (m_bufferpos >= BUFSIZE)
  518. {
  519. m_bufferpos = 0;
  520. m_zlibStream.next_out = (Bytef *)m_pBuffer;
  521. m_zlibStream.avail_out = BUFSIZE;
  522. }
  523. }
  524. int res = Z_OK;
  525. if (m_zlibStream.avail_out)
  526. {
  527. res = deflate(&m_zlibStream, m_pFile ? 0 : Z_FINISH);
  528. if (res != Z_OK && (!m_pFile && res != Z_STREAM_END))
  529. {
  530. m_pOwner->ShowStatus("Decompression error", FZ_LOG_ERROR);
  531. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  532. return;
  533. }
  534. }
  535. numsend = BUFSIZE;
  536. int len = BUFSIZE - m_bufferpos - m_zlibStream.avail_out;
  537. if (!len && !m_pFile)
  538. {
  539. break;
  540. }
  541. if (len < BUFSIZE)
  542. numsend = len;
  543. int nLimit = (int)m_pOwner->GetAbleToTransferSize(CFtpControlSocket::upload, beenWaiting);
  544. if (nLimit != -1 && GetState() != closed && numsend > nLimit)
  545. numsend = nLimit;
  546. if (!numsend)
  547. {
  548. TriggerEvent(FD_WRITE);
  549. return;
  550. }
  551. int numsent = Send(m_pBuffer + m_bufferpos, numsend);
  552. if (numsent == SOCKET_ERROR)
  553. {
  554. int nError = GetLastError();
  555. if (nError == WSAENOTCONN)
  556. {
  557. //Not yet connected
  558. return;
  559. }
  560. else if (m_pSslLayer && nError == WSAESHUTDOWN)
  561. {
  562. // Do nothing, wait for shutdown complete notification.
  563. return;
  564. }
  565. else if (nError != WSAEWOULDBLOCK)
  566. {
  567. CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
  568. }
  569. UpdateStatusBar(false);
  570. return;
  571. }
  572. m_pOwner->SpeedLimitAddTransferredBytes(CFtpControlSocket::upload, numsent);
  573. m_LastActiveTime = CTime::GetCurrentTime();
  574. m_bufferpos += numsent;
  575. UpdateStatusBar(false);
  576. if (!m_zlibStream.avail_in && !m_pFile && m_zlibStream.avail_out &&
  577. m_zlibStream.avail_out + m_bufferpos == BUFSIZE && res == Z_STREAM_END)
  578. {
  579. CloseOnShutDownOrError(0);
  580. return;
  581. }
  582. //Check if there are other commands in the command queue.
  583. MSG msg;
  584. if (PeekMessage(&msg,0, 0, 0, PM_NOREMOVE))
  585. {
  586. TriggerEvent(FD_WRITE);
  587. return;
  588. }
  589. }
  590. }
  591. else
  592. #endif
  593. {
  594. if (!m_pFile)
  595. {
  596. return;
  597. }
  598. if (!m_pBuffer)
  599. m_pBuffer = new char[BUFSIZE];
  600. int numread;
  601. bool beenWaiting = false;
  602. _int64 currentBufferSize;
  603. if (GetState() != closed)
  604. currentBufferSize = m_pOwner->GetAbleToTransferSize(CFtpControlSocket::upload, beenWaiting);
  605. else
  606. currentBufferSize = BUFSIZE;
  607. if (!currentBufferSize && !m_bufferpos)
  608. {
  609. // Not allowed to send yet, try later
  610. TriggerEvent(FD_WRITE);
  611. return;
  612. }
  613. else if (m_bufferpos < currentBufferSize)
  614. {
  615. numread = ReadDataFromFile(m_pBuffer + m_bufferpos, static_cast<int>(currentBufferSize - m_bufferpos));
  616. if (numread < 0 )
  617. {
  618. return;
  619. }
  620. else if (!numread && !m_bufferpos)
  621. {
  622. CloseOnShutDownOrError(0);
  623. return;
  624. }
  625. }
  626. else
  627. numread = 0;
  628. DebugAssert((numread+m_bufferpos) <= BUFSIZE);
  629. DebugAssert(numread>=0);
  630. DebugAssert(m_bufferpos>=0);
  631. if (numread+m_bufferpos <= 0)
  632. {
  633. CloseOnShutDownOrError(0);
  634. return;
  635. }
  636. int numsent = Send(m_pBuffer, numread + m_bufferpos);
  637. while (TRUE)
  638. {
  639. if (numsent != SOCKET_ERROR)
  640. {
  641. m_pOwner->SpeedLimitAddTransferredBytes(CFtpControlSocket::upload, numsent);
  642. m_LastActiveTime = CTime::GetCurrentTime();
  643. m_transferdata.transferleft -= numsent;
  644. }
  645. if (numsent==SOCKET_ERROR || !numsent)
  646. {
  647. int nError = GetLastError();
  648. if (nError == WSAENOTCONN)
  649. {
  650. //Not yet connected
  651. m_bufferpos += numread;
  652. return;
  653. }
  654. else if (nError == WSAEWOULDBLOCK)
  655. {
  656. m_bufferpos += numread;
  657. }
  658. else if (m_pSslLayer && nError == WSAESHUTDOWN)
  659. {
  660. m_bufferpos += numread;
  661. // Do nothing, wait for shutdown complete notification.
  662. return;
  663. }
  664. else
  665. {
  666. CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
  667. }
  668. UpdateStatusBar(false);
  669. return;
  670. }
  671. else
  672. {
  673. int pos = numread + m_bufferpos - numsent;
  674. if (pos < 0 || (numsent + pos) > BUFSIZE)
  675. {
  676. LogMessage(FZ_LOG_WARNING, L"Index out of range");
  677. CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
  678. return;
  679. }
  680. else if (!pos && numread < (currentBufferSize-m_bufferpos) && m_bufferpos != currentBufferSize)
  681. {
  682. CloseOnShutDownOrError(0);
  683. return;
  684. }
  685. else if (!pos)
  686. {
  687. m_bufferpos = 0;
  688. }
  689. else
  690. {
  691. memmove(m_pBuffer, m_pBuffer+numsent, pos);
  692. m_bufferpos=pos;
  693. }
  694. }
  695. //Check if there are other commands in the command queue.
  696. MSG msg;
  697. if (PeekMessage(&msg, 0, m_nInternalMessageID, m_nInternalMessageID, PM_NOREMOVE))
  698. {
  699. //Send resume message
  700. LogMessage(FZ_LOG_DEBUG, L"Message waiting in queue, resuming later");
  701. TriggerEvent(FD_WRITE);
  702. UpdateStatusBar(false);
  703. return;
  704. }
  705. UpdateStatusBar(false);
  706. if (GetState() != closed)
  707. currentBufferSize = m_pOwner->GetAbleToTransferSize(CFtpControlSocket::upload, beenWaiting);
  708. else
  709. currentBufferSize = BUFSIZE;
  710. if (m_bufferpos < currentBufferSize)
  711. {
  712. numread = ReadDataFromFile(m_pBuffer + m_bufferpos, static_cast<int>(currentBufferSize - m_bufferpos));
  713. if (numread < 0 )
  714. {
  715. return;
  716. }
  717. else if (!numread && !m_bufferpos)
  718. {
  719. CloseOnShutDownOrError(0);
  720. return;
  721. }
  722. }
  723. else
  724. {
  725. numread = 0;
  726. }
  727. if (!currentBufferSize && !m_bufferpos)
  728. {
  729. // Not allowed to send yet, try later
  730. TriggerEvent(FD_WRITE);
  731. return;
  732. }
  733. DebugAssert(numread>=0);
  734. DebugAssert(m_bufferpos>=0);
  735. numsent = Send(m_pBuffer, numread+m_bufferpos);
  736. }
  737. }
  738. }
  739. void CTransferSocket::UpdateStatusBar(bool forceUpdate)
  740. {
  741. if (m_nTransferState != STATE_STARTED)
  742. return;
  743. if (!forceUpdate)
  744. {
  745. //Don't flood the main window with messages
  746. //Else performance would be really low
  747. LARGE_INTEGER curtime;
  748. LARGE_INTEGER freq;
  749. QueryPerformanceFrequency(&freq);
  750. QueryPerformanceCounter(&curtime);
  751. if (((curtime.QuadPart-m_LastUpdateTime.QuadPart) < (freq.QuadPart/15) ) )
  752. return;
  753. m_LastUpdateTime = curtime;
  754. }
  755. //Update the statusbar
  756. t_ffam_transferstatus *status=new t_ffam_transferstatus;
  757. status->bFileTransfer = m_nMode & (CSMODE_DOWNLOAD | CSMODE_UPLOAD);
  758. status->transfersize = m_transferdata.transfersize;
  759. status->bytes=m_transferdata.transfersize-m_transferdata.transferleft;
  760. GetIntern()->PostMessage(FZ_MSG_MAKEMSG(FZ_MSG_TRANSFERSTATUS, 0), (LPARAM)status);
  761. }
  762. BOOL CTransferSocket::Create(BOOL bUseSsl)
  763. {
  764. if (bUseSsl)
  765. {
  766. m_pSslLayer = new CAsyncSslSocketLayer;
  767. m_pSslLayer->SetClientCertificate(m_pOwner->m_CurrentServer.Certificate, m_pOwner->m_CurrentServer.PrivateKey);
  768. }
  769. int nProxyType = GetOptionVal(OPTION_PROXYTYPE);
  770. if (nProxyType != PROXYTYPE_NOPROXY)
  771. {
  772. USES_CONVERSION;
  773. m_pProxyLayer = new CAsyncProxySocketLayer;
  774. if (nProxyType == PROXYTYPE_SOCKS4)
  775. m_pProxyLayer->SetProxy(PROXYTYPE_SOCKS4, T2CA(GetOption(OPTION_PROXYHOST)), GetOptionVal(OPTION_PROXYPORT));
  776. else if (nProxyType == PROXYTYPE_SOCKS4A)
  777. m_pProxyLayer->SetProxy(PROXYTYPE_SOCKS4A, T2CA(GetOption(OPTION_PROXYHOST)), GetOptionVal(OPTION_PROXYPORT));
  778. else if (nProxyType == PROXYTYPE_SOCKS5)
  779. if (GetOptionVal(OPTION_PROXYUSELOGON))
  780. m_pProxyLayer->SetProxy(PROXYTYPE_SOCKS5, T2CA(GetOption(OPTION_PROXYHOST)),
  781. GetOptionVal(OPTION_PROXYPORT),
  782. T2CA(GetOption(OPTION_PROXYUSER)),
  783. T2CA(GetOption(OPTION_PROXYPASS)));
  784. else
  785. m_pProxyLayer->SetProxy(PROXYTYPE_SOCKS5, T2CA(GetOption(OPTION_PROXYHOST)),
  786. GetOptionVal(OPTION_PROXYPORT));
  787. else if (nProxyType == PROXYTYPE_HTTP11)
  788. if (GetOptionVal(OPTION_PROXYUSELOGON))
  789. m_pProxyLayer->SetProxy(PROXYTYPE_HTTP11, T2CA(GetOption(OPTION_PROXYHOST)), GetOptionVal(OPTION_PROXYPORT),
  790. T2CA(GetOption(OPTION_PROXYUSER)),
  791. T2CA(GetOption(OPTION_PROXYPASS)));
  792. else
  793. m_pProxyLayer->SetProxy(PROXYTYPE_HTTP11, T2CA(GetOption(OPTION_PROXYHOST)), GetOptionVal(OPTION_PROXYPORT));
  794. else
  795. DebugAssert(FALSE);
  796. AddLayer(m_pProxyLayer);
  797. }
  798. if (!GetOptionVal(OPTION_LIMITPORTRANGE))
  799. {
  800. if (!CAsyncSocketEx::Create(0, SOCK_STREAM, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, 0, GetFamily()))
  801. return FALSE;
  802. return TRUE;
  803. }
  804. else
  805. {
  806. int min=GetOptionVal(OPTION_PORTRANGELOW);
  807. int max=GetOptionVal(OPTION_PORTRANGEHIGH);
  808. if (min>=max)
  809. {
  810. m_pOwner->ShowStatus(IDS_ERRORMSG_CANTCREATEDUETOPORTRANGE,FZ_LOG_ERROR);
  811. return FALSE;
  812. }
  813. int startport=static_cast<int>(min+((double)rand()*(max-min))/(RAND_MAX+1));
  814. int port=startport;
  815. while (!CAsyncSocketEx::Create(port, SOCK_STREAM, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE, 0, GetFamily()))
  816. {
  817. port++;
  818. if (port>max)
  819. port=min;
  820. if (port==startport)
  821. {
  822. m_pOwner->ShowStatus(IDS_ERRORMSG_CANTCREATEDUETOPORTRANGE,FZ_LOG_ERROR);
  823. return FALSE;
  824. }
  825. }
  826. }
  827. return TRUE;
  828. }
  829. void CTransferSocket::Close()
  830. {
  831. m_bCheckTimeout = FALSE;
  832. CAsyncSocketEx::Close();
  833. }
  834. int CTransferSocket::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
  835. {
  836. for (std::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
  837. {
  838. if (iter->nType == LAYERCALLBACK_STATECHANGE)
  839. {
  840. if (CAsyncSocketEx::LogStateChange(iter->nParam1, iter->nParam2))
  841. {
  842. const TCHAR * state2Desc = CAsyncSocketEx::GetStateDesc(iter->nParam2);
  843. const TCHAR * state1Desc = CAsyncSocketEx::GetStateDesc(iter->nParam1);
  844. if (iter->pLayer == m_pProxyLayer)
  845. LogMessage(FZ_LOG_INFO, L"Proxy layer changed state from %s to %s", state2Desc, state1Desc);
  846. else if (iter->pLayer == m_pSslLayer)
  847. LogMessage(FZ_LOG_INFO, L"TLS layer changed state from %s to %s", state2Desc, state1Desc);
  848. #ifndef MPEXT_NO_GSS
  849. else if (iter->pLayer == m_pGssLayer)
  850. LogMessage(FZ_LOG_INFO, L"GSS layer changed state from %s to %s", state2Desc, state1Desc);
  851. #endif
  852. else
  853. LogMessage(FZ_LOG_INFO, L"Layer @ %d changed state from %s to %s", iter->pLayer, state2Desc, state1Desc);
  854. }
  855. }
  856. else if (iter->nType == LAYERCALLBACK_LAYERSPECIFIC)
  857. {
  858. if (iter->pLayer == m_pProxyLayer)
  859. {
  860. switch (iter->nParam1)
  861. {
  862. case PROXYERROR_NOERROR:
  863. m_pOwner->ShowStatus(IDS_PROXY_CONNECTED, FZ_LOG_STATUS);
  864. break;
  865. case PROXYERROR_NOCONN:
  866. m_pOwner->ShowStatus(IDS_ERRORMSG_PROXY_NOCONN, FZ_LOG_ERROR);
  867. break;
  868. case PROXYERROR_REQUESTFAILED:
  869. m_pOwner->ShowStatus(IDS_ERRORMSG_PROXY_REQUESTFAILED, FZ_LOG_ERROR);
  870. break;
  871. case PROXYERROR_AUTHTYPEUNKNOWN:
  872. m_pOwner->ShowStatus(IDS_ERRORMSG_PROXY_AUTHTYPEUNKNOWN, FZ_LOG_ERROR);
  873. break;
  874. case PROXYERROR_AUTHFAILED:
  875. m_pOwner->ShowStatus(IDS_ERRORMSG_PROXY_AUTHFAILED, FZ_LOG_ERROR);
  876. break;
  877. case PROXYERROR_AUTHNOLOGON:
  878. m_pOwner->ShowStatus(IDS_ERRORMSG_PROXY_AUTHNOLOGON, FZ_LOG_ERROR);
  879. break;
  880. case PROXYERROR_CANTRESOLVEHOST:
  881. m_pOwner->ShowStatus(IDS_ERRORMSG_PROXY_CANTRESOLVEHOST, FZ_LOG_ERROR);
  882. break;
  883. default:
  884. LogMessage(FZ_LOG_WARNING, L"Unknown proxy error");
  885. }
  886. }
  887. else if (iter->pLayer == m_pSslLayer)
  888. {
  889. switch (iter->nParam1)
  890. {
  891. case SSL_INFO:
  892. switch(iter->nParam2)
  893. {
  894. case SSL_INFO_SHUTDOWNCOMPLETE:
  895. CloseAndEnsureSendClose(0);
  896. break;
  897. case SSL_INFO_ESTABLISHED:
  898. m_pOwner->ShowStatus(IDS_STATUSMSG_SSLESTABLISHEDTRANSFER, FZ_LOG_STATUS);
  899. TriggerEvent(FD_FORCEREAD);
  900. break;
  901. }
  902. break;
  903. case SSL_FAILURE:
  904. switch (iter->nParam2)
  905. {
  906. case SSL_FAILURE_ESTABLISH:
  907. m_pOwner->ShowStatus(IDS_ERRORMSG_CANTESTABLISHSSLCONNECTION, FZ_LOG_ERROR);
  908. break;
  909. case SSL_FAILURE_INITSSL:
  910. m_pOwner->ShowStatus(IDS_ERRORMSG_CANTINITSSL, FZ_LOG_ERROR);
  911. break;
  912. }
  913. EnsureSendClose(CSMODE_TRANSFERERROR);
  914. break;
  915. case SSL_VERIFY_CERT:
  916. t_SslCertData data;
  917. LPTSTR CertError = NULL;
  918. if (m_pSslLayer->GetPeerCertificateData(data, CertError))
  919. m_pSslLayer->SetNotifyReply(data.priv_data, SSL_VERIFY_CERT, 1);
  920. else
  921. {
  922. CString str;
  923. str.Format(TLS_CERT_DECODE_ERROR, CertError);
  924. m_pOwner->ShowStatus(str, FZ_LOG_ERROR);
  925. CloseAndEnsureSendClose(CSMODE_TRANSFERERROR);
  926. }
  927. break;
  928. }
  929. }
  930. #ifndef MPEXT_NO_GSS
  931. else if (iter->pLayer == m_pGssLayer)
  932. {
  933. USES_CONVERSION;
  934. switch (iter->nParam1)
  935. {
  936. case GSS_INFO:
  937. LogMessageRaw(FZ_LOG_INFO, A2CT(iter->str));
  938. break;
  939. case GSS_ERROR:
  940. LogMessageRaw(FZ_LOG_APIERROR, A2CT(iter->str));
  941. break;
  942. case GSS_SHUTDOWN_COMPLETE:
  943. CloseAndEnsureSendClose(0);
  944. break;
  945. }
  946. }
  947. #endif
  948. }
  949. delete [] iter->str;
  950. }
  951. return 0;
  952. }
  953. #ifndef MPEXT_NO_GSS
  954. void CTransferSocket::UseGSS(CAsyncGssSocketLayer *pGssLayer)
  955. {
  956. m_pGssLayer = new CAsyncGssSocketLayer;
  957. m_pGssLayer->InitTransferChannel(pGssLayer);
  958. }
  959. #endif
  960. #ifndef MPEXT_NO_ZLIB
  961. bool CTransferSocket::InitZlib(int level)
  962. {
  963. int res;
  964. if (m_nMode & CSMODE_UPLOAD)
  965. res = deflateInit2(&m_zlibStream, level, Z_DEFLATED, 15, 8, Z_DEFAULT_STRATEGY);
  966. else
  967. res = inflateInit2(&m_zlibStream, 15);
  968. if (res == Z_OK)
  969. m_useZlib = true;
  970. return res == Z_OK;
  971. }
  972. #endif
  973. int CTransferSocket::ReadDataFromFile(char *buffer, int len)
  974. {
  975. TRY
  976. {
  977. // Comparing to Filezilla 2, we do not do any translation locally,
  978. // leaving it onto the server (what Filezilla 3 seems to do too)
  979. const char Bom[3] = "\xEF\xBB\xBF";
  980. int read = m_pFile->Read(buffer, len);
  981. if (GetOptionVal(OPTION_MPEXT_REMOVE_BOM) &&
  982. m_transferdata.bType && (read >= sizeof(Bom)) && (memcmp(buffer, Bom, sizeof(Bom)) == 0))
  983. {
  984. memcpy(buffer, buffer + sizeof(Bom), read - sizeof(Bom));
  985. read -= sizeof(Bom);
  986. int read2 = m_pFile->Read(buffer + read, sizeof(Bom));
  987. if (read2 > 0)
  988. {
  989. read += read2;
  990. }
  991. }
  992. return read;
  993. }
  994. CATCH_ALL(e)
  995. {
  996. TCHAR error[BUFSIZE];
  997. if (e->GetErrorMessage(error, BUFSIZE))
  998. m_pOwner->ShowStatus(error, FZ_LOG_ERROR);
  999. CloseOnShutDownOrError(CSMODE_TRANSFERERROR);
  1000. return -1;
  1001. }
  1002. END_CATCH_ALL;
  1003. }
  1004. void CTransferSocket::LogSocketMessageRaw(int nMessageType, LPCTSTR pMsg)
  1005. {
  1006. LogMessageRaw(nMessageType, pMsg);
  1007. }
  1008. void CTransferSocket::EnsureSendClose(int Mode)
  1009. {
  1010. if (!m_bSentClose)
  1011. {
  1012. if (Mode != 0)
  1013. {
  1014. m_nMode |= Mode;
  1015. }
  1016. m_bSentClose = TRUE;
  1017. VERIFY(m_pOwner->m_pOwner->PostThreadMessage(m_nInternalMessageID, FZAPI_THREADMSG_TRANSFEREND, m_nMode));
  1018. }
  1019. }
  1020. void CTransferSocket::CloseAndEnsureSendClose(int Mode)
  1021. {
  1022. Close();
  1023. EnsureSendClose(Mode);
  1024. }
  1025. void CTransferSocket::CloseOnShutDownOrError(int Mode)
  1026. {
  1027. if (ShutDown())
  1028. {
  1029. CloseAndEnsureSendClose(Mode);
  1030. }
  1031. else
  1032. {
  1033. int Error = GetLastError();
  1034. if (Error != WSAEWOULDBLOCK)
  1035. {
  1036. // Log always or only when (Mode & CSMODE_TRANSFERERROR)?
  1037. // Does it anyway make sense at all to call this with Mode == 0?
  1038. LogError(Error);
  1039. CloseAndEnsureSendClose(Mode);
  1040. }
  1041. }
  1042. }
  1043. void CTransferSocket::LogError(int Error)
  1044. {
  1045. wchar_t * Buffer;
  1046. int Len = FormatMessage(
  1047. FORMAT_MESSAGE_FROM_SYSTEM |
  1048. FORMAT_MESSAGE_IGNORE_INSERTS |
  1049. FORMAT_MESSAGE_ARGUMENT_ARRAY |
  1050. FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, Error, 0, (LPTSTR)&Buffer, 0, NULL);
  1051. if (Len > 0)
  1052. {
  1053. m_pOwner->ShowStatus(Buffer, FZ_LOG_ERROR);
  1054. LocalFree(Buffer);
  1055. }
  1056. }