llxfermanager.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:31k
源码类别:

游戏引擎

开发平台:

C++ Builder

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