/indra/llmessage/llxfermanager.cpp

https://bitbucket.org/lindenlab/viewer-beta/ · C++ · 1277 lines · 905 code · 201 blank · 171 comment · 165 complexity · d51f91f93569cf78f5baaf51e30cfb6c MD5 · raw file

  1. /**
  2. * @file llxfermanager.cpp
  3. * @brief implementation of LLXferManager class for a collection of xfers
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llxfermanager.h"
  28. #include "llxfer.h"
  29. #include "llxfer_file.h"
  30. #include "llxfer_mem.h"
  31. #include "llxfer_vfile.h"
  32. #include "llerror.h"
  33. #include "lluuid.h"
  34. #include "u64.h"
  35. const F32 LL_XFER_REGISTRATION_TIMEOUT = 60.0f; // timeout if a registered transfer hasn't been requested in 60 seconds
  36. const F32 LL_PACKET_TIMEOUT = 3.0f; // packet timeout at 3 s
  37. const S32 LL_PACKET_RETRY_LIMIT = 10; // packet retransmission limit
  38. const S32 LL_DEFAULT_MAX_SIMULTANEOUS_XFERS = 10;
  39. const S32 LL_DEFAULT_MAX_REQUEST_FIFO_XFERS = 1000;
  40. #define LL_XFER_PROGRESS_MESSAGES 0
  41. #define LL_XFER_TEST_REXMIT 0
  42. ///////////////////////////////////////////////////////////
  43. LLXferManager::LLXferManager (LLVFS *vfs)
  44. {
  45. init(vfs);
  46. }
  47. ///////////////////////////////////////////////////////////
  48. LLXferManager::~LLXferManager ()
  49. {
  50. cleanup();
  51. }
  52. ///////////////////////////////////////////////////////////
  53. void LLXferManager::init (LLVFS *vfs)
  54. {
  55. mSendList = NULL;
  56. mReceiveList = NULL;
  57. setMaxOutgoingXfersPerCircuit(LL_DEFAULT_MAX_SIMULTANEOUS_XFERS);
  58. setMaxIncomingXfers(LL_DEFAULT_MAX_REQUEST_FIFO_XFERS);
  59. mVFS = vfs;
  60. // Turn on or off ack throttling
  61. mUseAckThrottling = FALSE;
  62. setAckThrottleBPS(100000);
  63. }
  64. ///////////////////////////////////////////////////////////
  65. void LLXferManager::cleanup ()
  66. {
  67. LLXfer *xferp;
  68. LLXfer *delp;
  69. for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer());
  70. mOutgoingHosts.clear();
  71. delp = mSendList;
  72. while (delp)
  73. {
  74. xferp = delp->mNext;
  75. delete delp;
  76. delp = xferp;
  77. }
  78. mSendList = NULL;
  79. delp = mReceiveList;
  80. while (delp)
  81. {
  82. xferp = delp->mNext;
  83. delete delp;
  84. delp = xferp;
  85. }
  86. mReceiveList = NULL;
  87. }
  88. ///////////////////////////////////////////////////////////
  89. void LLXferManager::setMaxIncomingXfers(S32 max_num)
  90. {
  91. mMaxIncomingXfers = max_num;
  92. }
  93. ///////////////////////////////////////////////////////////
  94. void LLXferManager::setMaxOutgoingXfersPerCircuit(S32 max_num)
  95. {
  96. mMaxOutgoingXfersPerCircuit = max_num;
  97. }
  98. void LLXferManager::setUseAckThrottling(const BOOL use)
  99. {
  100. mUseAckThrottling = use;
  101. }
  102. void LLXferManager::setAckThrottleBPS(const F32 bps)
  103. {
  104. // Let's figure out the min we can set based on the ack retry rate
  105. // and number of simultaneous.
  106. // Assuming we're running as slow as possible, this is the lowest ack
  107. // rate we can use.
  108. F32 min_bps = (1000.f * 8.f* mMaxIncomingXfers) / LL_PACKET_TIMEOUT;
  109. // Set
  110. F32 actual_rate = llmax(min_bps*1.1f, bps);
  111. LL_DEBUGS("AppInit") << "LLXferManager ack throttle min rate: " << min_bps << LL_ENDL;
  112. LL_DEBUGS("AppInit") << "LLXferManager ack throttle actual rate: " << actual_rate << LL_ENDL;
  113. mAckThrottle.setRate(actual_rate);
  114. }
  115. ///////////////////////////////////////////////////////////
  116. void LLXferManager::updateHostStatus()
  117. {
  118. LLXfer *xferp;
  119. LLHostStatus *host_statusp = NULL;
  120. for_each(mOutgoingHosts.begin(), mOutgoingHosts.end(), DeletePointer());
  121. mOutgoingHosts.clear();
  122. for (xferp = mSendList; xferp; xferp = xferp->mNext)
  123. {
  124. for (status_list_t::iterator iter = mOutgoingHosts.begin();
  125. iter != mOutgoingHosts.end(); ++iter)
  126. {
  127. host_statusp = *iter;
  128. if (host_statusp->mHost == xferp->mRemoteHost)
  129. {
  130. break;
  131. }
  132. }
  133. if (!host_statusp)
  134. {
  135. host_statusp = new LLHostStatus();
  136. if (host_statusp)
  137. {
  138. host_statusp->mHost = xferp->mRemoteHost;
  139. mOutgoingHosts.push_front(host_statusp);
  140. }
  141. }
  142. if (host_statusp)
  143. {
  144. if (xferp->mStatus == e_LL_XFER_PENDING)
  145. {
  146. host_statusp->mNumPending++;
  147. }
  148. else if (xferp->mStatus == e_LL_XFER_IN_PROGRESS)
  149. {
  150. host_statusp->mNumActive++;
  151. }
  152. }
  153. }
  154. }
  155. ///////////////////////////////////////////////////////////
  156. void LLXferManager::printHostStatus()
  157. {
  158. LLHostStatus *host_statusp = NULL;
  159. if (!mOutgoingHosts.empty())
  160. {
  161. llinfos << "Outgoing Xfers:" << llendl;
  162. for (status_list_t::iterator iter = mOutgoingHosts.begin();
  163. iter != mOutgoingHosts.end(); ++iter)
  164. {
  165. host_statusp = *iter;
  166. llinfos << " " << host_statusp->mHost << " active: " << host_statusp->mNumActive << " pending: " << host_statusp->mNumPending << llendl;
  167. }
  168. }
  169. }
  170. ///////////////////////////////////////////////////////////
  171. LLXfer *LLXferManager::findXfer (U64 id, LLXfer *list_head)
  172. {
  173. LLXfer *xferp;
  174. for (xferp = list_head; xferp; xferp = xferp->mNext)
  175. {
  176. if (xferp->mID == id)
  177. {
  178. return(xferp);
  179. }
  180. }
  181. return(NULL);
  182. }
  183. ///////////////////////////////////////////////////////////
  184. void LLXferManager::removeXfer (LLXfer *delp, LLXfer **list_head)
  185. {
  186. // This function assumes that delp will only occur in the list
  187. // zero or one times.
  188. if (delp)
  189. {
  190. if (*list_head == delp)
  191. {
  192. *list_head = delp->mNext;
  193. delete (delp);
  194. }
  195. else
  196. {
  197. LLXfer *xferp = *list_head;
  198. while (xferp->mNext)
  199. {
  200. if (xferp->mNext == delp)
  201. {
  202. xferp->mNext = delp->mNext;
  203. delete (delp);
  204. break;
  205. }
  206. xferp = xferp->mNext;
  207. }
  208. }
  209. }
  210. }
  211. ///////////////////////////////////////////////////////////
  212. U32 LLXferManager::numActiveListEntries(LLXfer *list_head)
  213. {
  214. U32 num_entries = 0;
  215. while (list_head)
  216. {
  217. if ((list_head->mStatus == e_LL_XFER_IN_PROGRESS))
  218. {
  219. num_entries++;
  220. }
  221. list_head = list_head->mNext;
  222. }
  223. return(num_entries);
  224. }
  225. ///////////////////////////////////////////////////////////
  226. S32 LLXferManager::numPendingXfers(const LLHost &host)
  227. {
  228. LLHostStatus *host_statusp = NULL;
  229. for (status_list_t::iterator iter = mOutgoingHosts.begin();
  230. iter != mOutgoingHosts.end(); ++iter)
  231. {
  232. host_statusp = *iter;
  233. if (host_statusp->mHost == host)
  234. {
  235. return (host_statusp->mNumPending);
  236. }
  237. }
  238. return 0;
  239. }
  240. ///////////////////////////////////////////////////////////
  241. S32 LLXferManager::numActiveXfers(const LLHost &host)
  242. {
  243. LLHostStatus *host_statusp = NULL;
  244. for (status_list_t::iterator iter = mOutgoingHosts.begin();
  245. iter != mOutgoingHosts.end(); ++iter)
  246. {
  247. host_statusp = *iter;
  248. if (host_statusp->mHost == host)
  249. {
  250. return (host_statusp->mNumActive);
  251. }
  252. }
  253. return 0;
  254. }
  255. ///////////////////////////////////////////////////////////
  256. void LLXferManager::changeNumActiveXfers(const LLHost &host, S32 delta)
  257. {
  258. LLHostStatus *host_statusp = NULL;
  259. for (status_list_t::iterator iter = mOutgoingHosts.begin();
  260. iter != mOutgoingHosts.end(); ++iter)
  261. {
  262. host_statusp = *iter;
  263. if (host_statusp->mHost == host)
  264. {
  265. host_statusp->mNumActive += delta;
  266. }
  267. }
  268. }
  269. ///////////////////////////////////////////////////////////
  270. void LLXferManager::registerCallbacks(LLMessageSystem *msgsystem)
  271. {
  272. msgsystem->setHandlerFuncFast(_PREHASH_ConfirmXferPacket, process_confirm_packet, NULL);
  273. msgsystem->setHandlerFuncFast(_PREHASH_RequestXfer, process_request_xfer, NULL);
  274. msgsystem->setHandlerFuncFast(_PREHASH_SendXferPacket, continue_file_receive, NULL);
  275. msgsystem->setHandlerFuncFast(_PREHASH_AbortXfer, process_abort_xfer, NULL);
  276. }
  277. ///////////////////////////////////////////////////////////
  278. U64 LLXferManager::getNextID ()
  279. {
  280. LLUUID a_guid;
  281. a_guid.generate();
  282. return(*((U64*)(a_guid.mData)));
  283. }
  284. ///////////////////////////////////////////////////////////
  285. S32 LLXferManager::encodePacketNum(S32 packet_num, BOOL is_EOF)
  286. {
  287. if (is_EOF)
  288. {
  289. packet_num |= 0x80000000;
  290. }
  291. return packet_num;
  292. }
  293. ///////////////////////////////////////////////////////////
  294. S32 LLXferManager::decodePacketNum(S32 packet_num)
  295. {
  296. return(packet_num & 0x0FFFFFFF);
  297. }
  298. ///////////////////////////////////////////////////////////
  299. BOOL LLXferManager::isLastPacket(S32 packet_num)
  300. {
  301. return(packet_num & 0x80000000);
  302. }
  303. ///////////////////////////////////////////////////////////
  304. U64 LLXferManager::registerXfer(const void *datap, const S32 length)
  305. {
  306. LLXfer *xferp;
  307. U64 xfer_id = getNextID();
  308. xferp = (LLXfer *) new LLXfer_Mem();
  309. if (xferp)
  310. {
  311. xferp->mNext = mSendList;
  312. mSendList = xferp;
  313. xfer_id = ((LLXfer_Mem *)xferp)->registerXfer(xfer_id, datap,length);
  314. if (!xfer_id)
  315. {
  316. removeXfer(xferp,&mSendList);
  317. }
  318. }
  319. else
  320. {
  321. llerrs << "Xfer allocation error" << llendl;
  322. xfer_id = 0;
  323. }
  324. return(xfer_id);
  325. }
  326. ///////////////////////////////////////////////////////////
  327. void LLXferManager::requestFile(const std::string& local_filename,
  328. const std::string& remote_filename,
  329. ELLPath remote_path,
  330. const LLHost& remote_host,
  331. BOOL delete_remote_on_completion,
  332. void (*callback)(void**,S32,LLExtStat),
  333. void** user_data,
  334. BOOL is_priority,
  335. BOOL use_big_packets)
  336. {
  337. LLXfer *xferp;
  338. for (xferp = mReceiveList; xferp ; xferp = xferp->mNext)
  339. {
  340. if (xferp->getXferTypeTag() == LLXfer::XFER_FILE
  341. && (((LLXfer_File*)xferp)->matchesLocalFilename(local_filename))
  342. && (((LLXfer_File*)xferp)->matchesRemoteFilename(remote_filename, remote_path))
  343. && (remote_host == xferp->mRemoteHost)
  344. && (callback == xferp->mCallback)
  345. && (user_data == xferp->mCallbackDataHandle))
  346. {
  347. // cout << "requested a xfer already in progress" << endl;
  348. return;
  349. }
  350. }
  351. S32 chunk_size = use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1;
  352. xferp = (LLXfer *) new LLXfer_File(chunk_size);
  353. if (xferp)
  354. {
  355. addToList(xferp, mReceiveList, is_priority);
  356. // Remove any file by the same name that happens to be lying
  357. // around.
  358. // Note: according to AaronB, this is here to deal with locks on files that were
  359. // in transit during a crash,
  360. if(delete_remote_on_completion &&
  361. (remote_filename.substr(remote_filename.length()-4) == ".tmp"))
  362. {
  363. LLFile::remove(local_filename);
  364. }
  365. ((LLXfer_File *)xferp)->initializeRequest(
  366. getNextID(),
  367. local_filename,
  368. remote_filename,
  369. remote_path,
  370. remote_host,
  371. delete_remote_on_completion,
  372. callback,user_data);
  373. startPendingDownloads();
  374. }
  375. else
  376. {
  377. llerrs << "Xfer allocation error" << llendl;
  378. }
  379. }
  380. void LLXferManager::requestFile(const std::string& remote_filename,
  381. ELLPath remote_path,
  382. const LLHost& remote_host,
  383. BOOL delete_remote_on_completion,
  384. void (*callback)(void*,S32,void**,S32,LLExtStat),
  385. void** user_data,
  386. BOOL is_priority)
  387. {
  388. LLXfer *xferp;
  389. xferp = (LLXfer *) new LLXfer_Mem();
  390. if (xferp)
  391. {
  392. addToList(xferp, mReceiveList, is_priority);
  393. ((LLXfer_Mem *)xferp)->initializeRequest(getNextID(),
  394. remote_filename,
  395. remote_path,
  396. remote_host,
  397. delete_remote_on_completion,
  398. callback, user_data);
  399. startPendingDownloads();
  400. }
  401. else
  402. {
  403. llerrs << "Xfer allocation error" << llendl;
  404. }
  405. }
  406. void LLXferManager::requestVFile(const LLUUID& local_id,
  407. const LLUUID& remote_id,
  408. LLAssetType::EType type, LLVFS* vfs,
  409. const LLHost& remote_host,
  410. void (*callback)(void**,S32,LLExtStat),
  411. void** user_data,
  412. BOOL is_priority)
  413. {
  414. LLXfer *xferp;
  415. for (xferp = mReceiveList; xferp ; xferp = xferp->mNext)
  416. {
  417. if (xferp->getXferTypeTag() == LLXfer::XFER_VFILE
  418. && (((LLXfer_VFile*)xferp)->matchesLocalFile(local_id, type))
  419. && (((LLXfer_VFile*)xferp)->matchesRemoteFile(remote_id, type))
  420. && (remote_host == xferp->mRemoteHost)
  421. && (callback == xferp->mCallback)
  422. && (user_data == xferp->mCallbackDataHandle))
  423. {
  424. // cout << "requested a xfer already in progress" << endl;
  425. return;
  426. }
  427. }
  428. xferp = (LLXfer *) new LLXfer_VFile();
  429. if (xferp)
  430. {
  431. addToList(xferp, mReceiveList, is_priority);
  432. ((LLXfer_VFile *)xferp)->initializeRequest(getNextID(),
  433. vfs,
  434. local_id,
  435. remote_id,
  436. type,
  437. remote_host,
  438. callback,
  439. user_data);
  440. startPendingDownloads();
  441. }
  442. else
  443. {
  444. llerrs << "Xfer allocation error" << llendl;
  445. }
  446. }
  447. /*
  448. void LLXferManager::requestXfer(
  449. const std::string& local_filename,
  450. BOOL delete_remote_on_completion,
  451. U64 xfer_id,
  452. const LLHost &remote_host,
  453. void (*callback)(void **,S32),
  454. void **user_data)
  455. {
  456. LLXfer *xferp;
  457. for (xferp = mReceiveList; xferp ; xferp = xferp->mNext)
  458. {
  459. if (xferp->getXferTypeTag() == LLXfer::XFER_FILE
  460. && (((LLXfer_File*)xferp)->matchesLocalFilename(local_filename))
  461. && (xfer_id == xferp->mID)
  462. && (remote_host == xferp->mRemoteHost)
  463. && (callback == xferp->mCallback)
  464. && (user_data == xferp->mCallbackDataHandle))
  465. {
  466. // cout << "requested a xfer already in progress" << endl;
  467. return;
  468. }
  469. }
  470. xferp = (LLXfer *) new LLXfer_File();
  471. if (xferp)
  472. {
  473. xferp->mNext = mReceiveList;
  474. mReceiveList = xferp;
  475. ((LLXfer_File *)xferp)->initializeRequest(xfer_id,local_filename,"",LL_PATH_NONE,remote_host,delete_remote_on_completion,callback,user_data);
  476. startPendingDownloads();
  477. }
  478. else
  479. {
  480. llerrs << "Xfer allcoation error" << llendl;
  481. }
  482. }
  483. void LLXferManager::requestXfer(U64 xfer_id, const LLHost &remote_host, BOOL delete_remote_on_completion, void (*callback)(void *,S32,void **,S32),void **user_data)
  484. {
  485. LLXfer *xferp;
  486. xferp = (LLXfer *) new LLXfer_Mem();
  487. if (xferp)
  488. {
  489. xferp->mNext = mReceiveList;
  490. mReceiveList = xferp;
  491. ((LLXfer_Mem *)xferp)->initializeRequest(xfer_id,"",LL_PATH_NONE,remote_host,delete_remote_on_completion,callback,user_data);
  492. startPendingDownloads();
  493. }
  494. else
  495. {
  496. llerrs << "Xfer allcoation error" << llendl;
  497. }
  498. }
  499. */
  500. ///////////////////////////////////////////////////////////
  501. void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user_data*/)
  502. {
  503. // there's sometimes an extra 4 bytes added to an xfer payload
  504. const S32 BUF_SIZE = LL_XFER_LARGE_PAYLOAD + 4;
  505. char fdata_buf[LL_XFER_LARGE_PAYLOAD + 4]; /* Flawfinder : ignore */
  506. S32 fdata_size;
  507. U64 id;
  508. S32 packetnum;
  509. LLXfer * xferp;
  510. mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id);
  511. mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetnum);
  512. fdata_size = mesgsys->getSizeFast(_PREHASH_DataPacket,_PREHASH_Data);
  513. mesgsys->getBinaryDataFast(_PREHASH_DataPacket, _PREHASH_Data, fdata_buf, 0, 0, BUF_SIZE);
  514. xferp = findXfer(id, mReceiveList);
  515. if (!xferp)
  516. {
  517. char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
  518. llwarns << "received xfer data from " << mesgsys->getSender()
  519. << " for non-existent xfer id: "
  520. << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << llendl;
  521. return;
  522. }
  523. S32 xfer_size;
  524. if (decodePacketNum(packetnum) != xferp->mPacketNum) // is the packet different from what we were expecting?
  525. {
  526. // confirm it if it was a resend of the last one, since the confirmation might have gotten dropped
  527. if (decodePacketNum(packetnum) == (xferp->mPacketNum - 1))
  528. {
  529. llinfos << "Reconfirming xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet " << packetnum << llendl; sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender());
  530. }
  531. else
  532. {
  533. llinfos << "Ignoring xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " recv'd packet " << packetnum << "; expecting " << xferp->mPacketNum << llendl;
  534. }
  535. return;
  536. }
  537. S32 result = 0;
  538. if (xferp->mPacketNum == 0) // first packet has size encoded as additional S32 at beginning of data
  539. {
  540. ntohmemcpy(&xfer_size,fdata_buf,MVT_S32,sizeof(S32));
  541. // do any necessary things on first packet ie. allocate memory
  542. xferp->setXferSize(xfer_size);
  543. // adjust buffer start and size
  544. result = xferp->receiveData(&(fdata_buf[sizeof(S32)]),fdata_size-(sizeof(S32)));
  545. }
  546. else
  547. {
  548. result = xferp->receiveData(fdata_buf,fdata_size);
  549. }
  550. if (result == LL_ERR_CANNOT_OPEN_FILE)
  551. {
  552. xferp->abort(LL_ERR_CANNOT_OPEN_FILE);
  553. removeXfer(xferp,&mReceiveList);
  554. startPendingDownloads();
  555. return;
  556. }
  557. xferp->mPacketNum++; // expect next packet
  558. if (!mUseAckThrottling)
  559. {
  560. // No throttling, confirm right away
  561. sendConfirmPacket(mesgsys, id, decodePacketNum(packetnum), mesgsys->getSender());
  562. }
  563. else
  564. {
  565. // Throttling, put on queue to be confirmed later.
  566. LLXferAckInfo ack_info;
  567. ack_info.mID = id;
  568. ack_info.mPacketNum = decodePacketNum(packetnum);
  569. ack_info.mRemoteHost = mesgsys->getSender();
  570. mXferAckQueue.push(ack_info);
  571. }
  572. if (isLastPacket(packetnum))
  573. {
  574. xferp->processEOF();
  575. removeXfer(xferp,&mReceiveList);
  576. startPendingDownloads();
  577. }
  578. }
  579. ///////////////////////////////////////////////////////////
  580. void LLXferManager::sendConfirmPacket (LLMessageSystem *mesgsys, U64 id, S32 packetnum, const LLHost &remote_host)
  581. {
  582. #if LL_XFER_PROGRESS_MESSAGES
  583. if (!(packetnum % 50))
  584. {
  585. cout << "confirming xfer packet #" << packetnum << endl;
  586. }
  587. #endif
  588. mesgsys->newMessageFast(_PREHASH_ConfirmXferPacket);
  589. mesgsys->nextBlockFast(_PREHASH_XferID);
  590. mesgsys->addU64Fast(_PREHASH_ID, id);
  591. mesgsys->addU32Fast(_PREHASH_Packet, packetnum);
  592. mesgsys->sendMessage(remote_host);
  593. }
  594. ///////////////////////////////////////////////////////////
  595. static bool find_and_remove(std::multiset<std::string>& files,
  596. const std::string& filename)
  597. {
  598. std::multiset<std::string>::iterator ptr;
  599. if ( (ptr = files.find(filename)) != files.end())
  600. {
  601. //erase(filename) erases *all* entries with that key
  602. files.erase(ptr);
  603. return true;
  604. }
  605. return false;
  606. }
  607. void LLXferManager::expectFileForRequest(const std::string& filename)
  608. {
  609. mExpectedRequests.insert(filename);
  610. }
  611. bool LLXferManager::validateFileForRequest(const std::string& filename)
  612. {
  613. return find_and_remove(mExpectedRequests, filename);
  614. }
  615. void LLXferManager::expectFileForTransfer(const std::string& filename)
  616. {
  617. mExpectedTransfers.insert(filename);
  618. }
  619. bool LLXferManager::validateFileForTransfer(const std::string& filename)
  620. {
  621. return find_and_remove(mExpectedTransfers, filename);
  622. }
  623. static bool remove_prefix(std::string& filename, const std::string& prefix)
  624. {
  625. if (std::equal(prefix.begin(), prefix.end(), filename.begin()))
  626. {
  627. filename = filename.substr(prefix.length());
  628. return true;
  629. }
  630. return false;
  631. }
  632. static bool verify_cache_filename(const std::string& filename)
  633. {
  634. //NOTE: This routine is only used to check file names that our own
  635. // code places in the cache directory. As such, it can be limited
  636. // to this very restrictive file name pattern. It does not need to
  637. // handle other characters. The only known uses of this are (with examples):
  638. // sim to sim object pass: fc0b72d8-9456-63d9-a802-a557ef847313.tmp
  639. // sim to viewer mute list: mute_b78eacd0-1244-448e-93ca-28ede242f647.tmp
  640. // sim to viewer task inventory: inventory_d8ab59d2-baf0-0e79-c4c2-a3f99b9fcf45.tmp
  641. //IMPORTANT: Do not broaden the filenames accepted by this routine
  642. // without careful analysis. Anything allowed by this function can
  643. // be downloaded by the viewer.
  644. size_t len = filename.size();
  645. //const boost::regex expr("[0-9a-zA-Z_-]<1,46>\.tmp");
  646. if (len < 5 || len > 50)
  647. {
  648. return false;
  649. }
  650. for(size_t i=0; i<(len-4); ++i)
  651. {
  652. char c = filename[i];
  653. bool ok = isalnum(c) || '_'==c || '-'==c;
  654. if (!ok)
  655. {
  656. return false;
  657. }
  658. }
  659. return filename[len-4] == '.'
  660. && filename[len-3] == 't'
  661. && filename[len-2] == 'm'
  662. && filename[len-1] == 'p';
  663. }
  664. void LLXferManager::processFileRequest (LLMessageSystem *mesgsys, void ** /*user_data*/)
  665. {
  666. U64 id;
  667. std::string local_filename;
  668. ELLPath local_path = LL_PATH_NONE;
  669. S32 result = LL_ERR_NOERR;
  670. LLUUID uuid;
  671. LLAssetType::EType type;
  672. S16 type_s16;
  673. BOOL b_use_big_packets;
  674. mesgsys->getBOOL("XferID", "UseBigPackets", b_use_big_packets);
  675. mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id);
  676. char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
  677. llinfos << "xfer request id: " << U64_to_str(id, U64_BUF, sizeof(U64_BUF))
  678. << " to " << mesgsys->getSender() << llendl;
  679. mesgsys->getStringFast(_PREHASH_XferID, _PREHASH_Filename, local_filename);
  680. {
  681. U8 local_path_u8;
  682. mesgsys->getU8("XferID", "FilePath", local_path_u8);
  683. local_path = (ELLPath)local_path_u8;
  684. }
  685. mesgsys->getUUIDFast(_PREHASH_XferID, _PREHASH_VFileID, uuid);
  686. mesgsys->getS16Fast(_PREHASH_XferID, _PREHASH_VFileType, type_s16);
  687. type = (LLAssetType::EType)type_s16;
  688. LLXfer *xferp;
  689. if (uuid != LLUUID::null)
  690. {
  691. if(NULL == LLAssetType::lookup(type))
  692. {
  693. llwarns << "Invalid type for xfer request: " << uuid << ":"
  694. << type_s16 << " to " << mesgsys->getSender() << llendl;
  695. return;
  696. }
  697. llinfos << "starting vfile transfer: " << uuid << "," << LLAssetType::lookup(type) << " to " << mesgsys->getSender() << llendl;
  698. if (! mVFS)
  699. {
  700. llwarns << "Attempt to send VFile w/o available VFS" << llendl;
  701. return;
  702. }
  703. xferp = (LLXfer *)new LLXfer_VFile(mVFS, uuid, type);
  704. if (xferp)
  705. {
  706. xferp->mNext = mSendList;
  707. mSendList = xferp;
  708. result = xferp->startSend(id,mesgsys->getSender());
  709. }
  710. else
  711. {
  712. llerrs << "Xfer allcoation error" << llendl;
  713. }
  714. }
  715. else if (!local_filename.empty())
  716. {
  717. // See DEV-21775 for detailed security issues
  718. if (local_path == LL_PATH_NONE)
  719. {
  720. // this handles legacy simulators that are passing objects
  721. // by giving a filename that explicitly names the cache directory
  722. static const std::string legacy_cache_prefix = "data/";
  723. if (remove_prefix(local_filename, legacy_cache_prefix))
  724. {
  725. local_path = LL_PATH_CACHE;
  726. }
  727. }
  728. switch (local_path)
  729. {
  730. case LL_PATH_NONE:
  731. if(!validateFileForTransfer(local_filename))
  732. {
  733. llwarns << "SECURITY: Unapproved filename '" << local_filename << llendl;
  734. return;
  735. }
  736. break;
  737. case LL_PATH_CACHE:
  738. if(!verify_cache_filename(local_filename))
  739. {
  740. llwarns << "SECURITY: Illegal cache filename '" << local_filename << llendl;
  741. return;
  742. }
  743. break;
  744. default:
  745. llwarns << "SECURITY: Restricted file dir enum: " << (U32)local_path << llendl;
  746. return;
  747. }
  748. std::string expanded_filename = gDirUtilp->getExpandedFilename( local_path, local_filename );
  749. llinfos << "starting file transfer: " << expanded_filename << " to " << mesgsys->getSender() << llendl;
  750. BOOL delete_local_on_completion = FALSE;
  751. mesgsys->getBOOL("XferID", "DeleteOnCompletion", delete_local_on_completion);
  752. // -1 chunk_size causes it to use the default
  753. xferp = (LLXfer *)new LLXfer_File(expanded_filename, delete_local_on_completion, b_use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1);
  754. if (xferp)
  755. {
  756. xferp->mNext = mSendList;
  757. mSendList = xferp;
  758. result = xferp->startSend(id,mesgsys->getSender());
  759. }
  760. else
  761. {
  762. llerrs << "Xfer allcoation error" << llendl;
  763. }
  764. }
  765. else
  766. {
  767. char U64_BUF[MAX_STRING]; /* Flawfinder : ignore */
  768. llinfos << "starting memory transfer: "
  769. << U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << " to "
  770. << mesgsys->getSender() << llendl;
  771. xferp = findXfer(id, mSendList);
  772. if (xferp)
  773. {
  774. result = xferp->startSend(id,mesgsys->getSender());
  775. }
  776. else
  777. {
  778. llinfos << "Warning: " << U64_BUF << " not found." << llendl;
  779. result = LL_ERR_FILE_NOT_FOUND;
  780. }
  781. }
  782. if (result)
  783. {
  784. if (xferp)
  785. {
  786. xferp->abort(result);
  787. removeXfer(xferp,&mSendList);
  788. }
  789. else // can happen with a memory transfer not found
  790. {
  791. llinfos << "Aborting xfer to " << mesgsys->getSender() << " with error: " << result << llendl;
  792. mesgsys->newMessageFast(_PREHASH_AbortXfer);
  793. mesgsys->nextBlockFast(_PREHASH_XferID);
  794. mesgsys->addU64Fast(_PREHASH_ID, id);
  795. mesgsys->addS32Fast(_PREHASH_Result, result);
  796. mesgsys->sendMessage(mesgsys->getSender());
  797. }
  798. }
  799. else if(xferp && (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit))
  800. {
  801. xferp->sendNextPacket();
  802. changeNumActiveXfers(xferp->mRemoteHost,1);
  803. // llinfos << "***STARTING XFER IMMEDIATELY***" << llendl;
  804. }
  805. else
  806. {
  807. if(xferp)
  808. {
  809. llinfos << " queueing xfer request, " << numPendingXfers(xferp->mRemoteHost) << " ahead of this one" << llendl;
  810. }
  811. else
  812. {
  813. llwarns << "LLXferManager::processFileRequest() - no xfer found!"
  814. << llendl;
  815. }
  816. }
  817. }
  818. ///////////////////////////////////////////////////////////
  819. void LLXferManager::processConfirmation (LLMessageSystem *mesgsys, void ** /*user_data*/)
  820. {
  821. U64 id = 0;
  822. S32 packetNum = 0;
  823. mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id);
  824. mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Packet, packetNum);
  825. LLXfer* xferp = findXfer(id, mSendList);
  826. if (xferp)
  827. {
  828. // cout << "confirmed packet #" << packetNum << " ping: "<< xferp->ACKTimer.getElapsedTimeF32() << endl;
  829. xferp->mWaitingForACK = FALSE;
  830. if (xferp->mStatus == e_LL_XFER_IN_PROGRESS)
  831. {
  832. xferp->sendNextPacket();
  833. }
  834. else
  835. {
  836. removeXfer(xferp, &mSendList);
  837. }
  838. }
  839. }
  840. ///////////////////////////////////////////////////////////
  841. void LLXferManager::retransmitUnackedPackets ()
  842. {
  843. LLXfer *xferp;
  844. LLXfer *delp;
  845. xferp = mReceiveList;
  846. while(xferp)
  847. {
  848. if (xferp->mStatus == e_LL_XFER_IN_PROGRESS)
  849. {
  850. // if the circuit dies, abort
  851. if (! gMessageSystem->mCircuitInfo.isCircuitAlive( xferp->mRemoteHost ))
  852. {
  853. llinfos << "Xfer found in progress on dead circuit, aborting" << llendl;
  854. xferp->mCallbackResult = LL_ERR_CIRCUIT_GONE;
  855. xferp->processEOF();
  856. delp = xferp;
  857. xferp = xferp->mNext;
  858. removeXfer(delp,&mReceiveList);
  859. continue;
  860. }
  861. }
  862. xferp = xferp->mNext;
  863. }
  864. xferp = mSendList;
  865. updateHostStatus();
  866. F32 et;
  867. while (xferp)
  868. {
  869. if (xferp->mWaitingForACK && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_PACKET_TIMEOUT))
  870. {
  871. if (xferp->mRetries > LL_PACKET_RETRY_LIMIT)
  872. {
  873. llinfos << "dropping xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet retransmit limit exceeded, xfer dropped" << llendl;
  874. xferp->abort(LL_ERR_TCP_TIMEOUT);
  875. delp = xferp;
  876. xferp = xferp->mNext;
  877. removeXfer(delp,&mSendList);
  878. }
  879. else
  880. {
  881. llinfos << "resending xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << " packet unconfirmed after: "<< et << " sec, packet " << xferp->mPacketNum << llendl;
  882. xferp->resendLastPacket();
  883. xferp = xferp->mNext;
  884. }
  885. }
  886. else if ((xferp->mStatus == e_LL_XFER_REGISTERED) && ( (et = xferp->ACKTimer.getElapsedTimeF32()) > LL_XFER_REGISTRATION_TIMEOUT))
  887. {
  888. llinfos << "registered xfer never requested, xfer dropped" << llendl;
  889. xferp->abort(LL_ERR_TCP_TIMEOUT);
  890. delp = xferp;
  891. xferp = xferp->mNext;
  892. removeXfer(delp,&mSendList);
  893. }
  894. else if (xferp->mStatus == e_LL_XFER_ABORTED)
  895. {
  896. llwarns << "Removing aborted xfer " << xferp->mRemoteHost << ":" << xferp->getFileName() << llendl;
  897. delp = xferp;
  898. xferp = xferp->mNext;
  899. removeXfer(delp,&mSendList);
  900. }
  901. else if (xferp->mStatus == e_LL_XFER_PENDING)
  902. {
  903. // llinfos << "*** numActiveXfers = " << numActiveXfers(xferp->mRemoteHost) << " mMaxOutgoingXfersPerCircuit = " << mMaxOutgoingXfersPerCircuit << llendl;
  904. if (numActiveXfers(xferp->mRemoteHost) < mMaxOutgoingXfersPerCircuit)
  905. {
  906. // llinfos << "bumping pending xfer to active" << llendl;
  907. xferp->sendNextPacket();
  908. changeNumActiveXfers(xferp->mRemoteHost,1);
  909. }
  910. xferp = xferp->mNext;
  911. }
  912. else
  913. {
  914. xferp = xferp->mNext;
  915. }
  916. }
  917. //
  918. // HACK - if we're using xfer confirm throttling, throttle our xfer confirms here
  919. // so we don't blow through bandwidth.
  920. //
  921. while (mXferAckQueue.getLength())
  922. {
  923. if (mAckThrottle.checkOverflow(1000.0f*8.0f))
  924. {
  925. break;
  926. }
  927. //llinfos << "Confirm packet queue length:" << mXferAckQueue.getLength() << llendl;
  928. LLXferAckInfo ack_info;
  929. mXferAckQueue.pop(ack_info);
  930. //llinfos << "Sending confirm packet" << llendl;
  931. sendConfirmPacket(gMessageSystem, ack_info.mID, ack_info.mPacketNum, ack_info.mRemoteHost);
  932. mAckThrottle.throttleOverflow(1000.f*8.f); // Assume 1000 bytes/packet
  933. }
  934. }
  935. ///////////////////////////////////////////////////////////
  936. void LLXferManager::processAbort (LLMessageSystem *mesgsys, void ** /*user_data*/)
  937. {
  938. U64 id = 0;
  939. S32 result_code = 0;
  940. LLXfer * xferp;
  941. mesgsys->getU64Fast(_PREHASH_XferID, _PREHASH_ID, id);
  942. mesgsys->getS32Fast(_PREHASH_XferID, _PREHASH_Result, result_code);
  943. xferp = findXfer(id, mReceiveList);
  944. if (xferp)
  945. {
  946. xferp->mCallbackResult = result_code;
  947. xferp->processEOF();
  948. removeXfer(xferp, &mReceiveList);
  949. startPendingDownloads();
  950. }
  951. }
  952. ///////////////////////////////////////////////////////////
  953. void LLXferManager::startPendingDownloads()
  954. {
  955. // This method goes through the list, and starts pending
  956. // operations until active downloads == mMaxIncomingXfers. I copy
  957. // the pending xfers into a temporary data structure because the
  958. // xfers are stored as an intrusive linked list where older
  959. // requests get pushed toward the back. Thus, if we didn't do a
  960. // stateful iteration, it would be possible for old requests to
  961. // never start.
  962. LLXfer* xferp = mReceiveList;
  963. std::list<LLXfer*> pending_downloads;
  964. S32 download_count = 0;
  965. S32 pending_count = 0;
  966. while(xferp)
  967. {
  968. if(xferp->mStatus == e_LL_XFER_PENDING)
  969. {
  970. ++pending_count;
  971. pending_downloads.push_front(xferp);
  972. }
  973. else if(xferp->mStatus == e_LL_XFER_IN_PROGRESS)
  974. {
  975. ++download_count;
  976. }
  977. xferp = xferp->mNext;
  978. }
  979. S32 start_count = mMaxIncomingXfers - download_count;
  980. lldebugs << "LLXferManager::startPendingDownloads() - XFER_IN_PROGRESS: "
  981. << download_count << " XFER_PENDING: " << pending_count
  982. << " startring " << llmin(start_count, pending_count) << llendl;
  983. if((start_count > 0) && (pending_count > 0))
  984. {
  985. S32 result;
  986. for (std::list<LLXfer*>::iterator iter = pending_downloads.begin();
  987. iter != pending_downloads.end(); ++iter)
  988. {
  989. xferp = *iter;
  990. if (start_count-- <= 0)
  991. break;
  992. result = xferp->startDownload();
  993. if(result)
  994. {
  995. xferp->abort(result);
  996. ++start_count;
  997. }
  998. }
  999. }
  1000. }
  1001. ///////////////////////////////////////////////////////////
  1002. void LLXferManager::addToList(LLXfer* xferp, LLXfer*& head, BOOL is_priority)
  1003. {
  1004. if(is_priority)
  1005. {
  1006. xferp->mNext = NULL;
  1007. LLXfer* next = head;
  1008. if(next)
  1009. {
  1010. while(next->mNext)
  1011. {
  1012. next = next->mNext;
  1013. }
  1014. next->mNext = xferp;
  1015. }
  1016. else
  1017. {
  1018. head = xferp;
  1019. }
  1020. }
  1021. else
  1022. {
  1023. xferp->mNext = head;
  1024. head = xferp;
  1025. }
  1026. }
  1027. ///////////////////////////////////////////////////////////
  1028. // Globals and C routines
  1029. ///////////////////////////////////////////////////////////
  1030. LLXferManager *gXferManager = NULL;
  1031. void start_xfer_manager(LLVFS *vfs)
  1032. {
  1033. gXferManager = new LLXferManager(vfs);
  1034. }
  1035. void cleanup_xfer_manager()
  1036. {
  1037. if (gXferManager)
  1038. {
  1039. delete(gXferManager);
  1040. gXferManager = NULL;
  1041. }
  1042. }
  1043. void process_confirm_packet (LLMessageSystem *mesgsys, void **user_data)
  1044. {
  1045. gXferManager->processConfirmation(mesgsys,user_data);
  1046. }
  1047. void process_request_xfer(LLMessageSystem *mesgsys, void **user_data)
  1048. {
  1049. gXferManager->processFileRequest(mesgsys,user_data);
  1050. }
  1051. void continue_file_receive(LLMessageSystem *mesgsys, void **user_data)
  1052. {
  1053. #if LL_TEST_XFER_REXMIT
  1054. if (ll_frand() > 0.05f)
  1055. {
  1056. #endif
  1057. gXferManager->processReceiveData(mesgsys,user_data);
  1058. #if LL_TEST_XFER_REXMIT
  1059. }
  1060. else
  1061. {
  1062. cout << "oops! dropped a xfer packet" << endl;
  1063. }
  1064. #endif
  1065. }
  1066. void process_abort_xfer(LLMessageSystem *mesgsys, void **user_data)
  1067. {
  1068. gXferManager->processAbort(mesgsys,user_data);
  1069. }