PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llmessage/lltransfermanager.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1381 lines | 978 code | 213 blank | 190 comment | 137 complexity | 6eb764d6104a08f6bd1975547ebad0a1 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file lltransfermanager.cpp
  3. * @brief Improved transfer mechanism for moving data through the
  4. * message system.
  5. *
  6. * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  7. * Second Life Viewer Source Code
  8. * Copyright (C) 2010, Linden Research, Inc.
  9. *
  10. * This library is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU Lesser General Public
  12. * License as published by the Free Software Foundation;
  13. * version 2.1 of the License only.
  14. *
  15. * This library is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * Lesser General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU Lesser General Public
  21. * License along with this library; if not, write to the Free Software
  22. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  23. *
  24. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  25. * $/LicenseInfo$
  26. */
  27. #include "linden_common.h"
  28. #include "lltransfermanager.h"
  29. #include "llerror.h"
  30. #include "message.h"
  31. #include "lldatapacker.h"
  32. #include "lltransfersourcefile.h"
  33. #include "lltransfersourceasset.h"
  34. #include "lltransfertargetfile.h"
  35. #include "lltransfertargetvfile.h"
  36. const S32 MAX_PACKET_DATA_SIZE = 2048;
  37. const S32 MAX_PARAMS_SIZE = 1024;
  38. LLTransferManager gTransferManager;
  39. LLTransferSource::stype_scfunc_map LLTransferSource::sSourceCreateMap;
  40. //
  41. // LLTransferManager implementation
  42. //
  43. LLTransferManager::LLTransferManager() :
  44. mValid(FALSE)
  45. {
  46. S32 i;
  47. for (i = 0; i < LLTTT_NUM_TYPES; i++)
  48. {
  49. mTransferBitsIn[i] = 0;
  50. mTransferBitsOut[i] = 0;
  51. }
  52. }
  53. LLTransferManager::~LLTransferManager()
  54. {
  55. if (mValid)
  56. {
  57. llwarns << "LLTransferManager::~LLTransferManager - Should have been cleaned up by message system shutdown process" << llendl;
  58. cleanup();
  59. }
  60. }
  61. void LLTransferManager::init()
  62. {
  63. if (mValid)
  64. {
  65. llerrs << "Double initializing LLTransferManager!" << llendl;
  66. }
  67. mValid = TRUE;
  68. // Register message system handlers
  69. gMessageSystem->setHandlerFunc("TransferRequest", processTransferRequest, NULL);
  70. gMessageSystem->setHandlerFunc("TransferInfo", processTransferInfo, NULL);
  71. gMessageSystem->setHandlerFunc("TransferPacket", processTransferPacket, NULL);
  72. gMessageSystem->setHandlerFunc("TransferAbort", processTransferAbort, NULL);
  73. }
  74. void LLTransferManager::cleanup()
  75. {
  76. mValid = FALSE;
  77. host_tc_map::iterator iter;
  78. for (iter = mTransferConnections.begin(); iter != mTransferConnections.end(); iter++)
  79. {
  80. delete iter->second;
  81. }
  82. mTransferConnections.clear();
  83. }
  84. void LLTransferManager::updateTransfers()
  85. {
  86. host_tc_map::iterator iter,cur;
  87. iter = mTransferConnections.begin();
  88. while (iter !=mTransferConnections.end())
  89. {
  90. cur = iter;
  91. iter++;
  92. cur->second->updateTransfers();
  93. }
  94. }
  95. void LLTransferManager::cleanupConnection(const LLHost &host)
  96. {
  97. host_tc_map::iterator iter;
  98. iter = mTransferConnections.find(host);
  99. if (iter == mTransferConnections.end())
  100. {
  101. // This can happen legitimately if we've never done a transfer, and we're
  102. // cleaning up a circuit.
  103. //llwarns << "Cleaning up nonexistent transfer connection to " << host << llendl;
  104. return;
  105. }
  106. LLTransferConnection *connp = iter->second;
  107. delete connp;
  108. mTransferConnections.erase(iter);
  109. }
  110. LLTransferConnection *LLTransferManager::getTransferConnection(const LLHost &host)
  111. {
  112. host_tc_map::iterator iter;
  113. iter = mTransferConnections.find(host);
  114. if (iter == mTransferConnections.end())
  115. {
  116. mTransferConnections[host] = new LLTransferConnection(host);
  117. return mTransferConnections[host];
  118. }
  119. return iter->second;
  120. }
  121. LLTransferSourceChannel *LLTransferManager::getSourceChannel(const LLHost &host, const LLTransferChannelType type)
  122. {
  123. LLTransferConnection *tcp = getTransferConnection(host);
  124. if (!tcp)
  125. {
  126. return NULL;
  127. }
  128. return tcp->getSourceChannel(type);
  129. }
  130. LLTransferTargetChannel *LLTransferManager::getTargetChannel(const LLHost &host, const LLTransferChannelType type)
  131. {
  132. LLTransferConnection *tcp = getTransferConnection(host);
  133. if (!tcp)
  134. {
  135. return NULL;
  136. }
  137. return tcp->getTargetChannel(type);
  138. }
  139. // virtual
  140. LLTransferSourceParams::~LLTransferSourceParams()
  141. { }
  142. LLTransferSource *LLTransferManager::findTransferSource(const LLUUID &transfer_id)
  143. {
  144. // This linear traversal could screw us later if we do lots of
  145. // searches for sources. However, this ONLY happens right now
  146. // in asset transfer callbacks, so this should be relatively quick.
  147. host_tc_map::iterator iter;
  148. for (iter = mTransferConnections.begin(); iter != mTransferConnections.end(); iter++)
  149. {
  150. LLTransferConnection *tcp = iter->second;
  151. LLTransferConnection::tsc_iter sc_iter;
  152. for (sc_iter = tcp->mTransferSourceChannels.begin(); sc_iter != tcp->mTransferSourceChannels.end(); sc_iter++)
  153. {
  154. LLTransferSourceChannel *scp = *sc_iter;
  155. LLTransferSource *sourcep = scp->findTransferSource(transfer_id);
  156. if (sourcep)
  157. {
  158. return sourcep;
  159. }
  160. }
  161. }
  162. return NULL;
  163. }
  164. //
  165. // Message handlers
  166. //
  167. //static
  168. void LLTransferManager::processTransferRequest(LLMessageSystem *msgp, void **)
  169. {
  170. //llinfos << "LLTransferManager::processTransferRequest" << llendl;
  171. LLUUID transfer_id;
  172. LLTransferSourceType source_type;
  173. LLTransferChannelType channel_type;
  174. F32 priority;
  175. msgp->getUUID("TransferInfo", "TransferID", transfer_id);
  176. msgp->getS32("TransferInfo", "SourceType", (S32 &)source_type);
  177. msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type);
  178. msgp->getF32("TransferInfo", "Priority", priority);
  179. LLTransferSourceChannel *tscp = gTransferManager.getSourceChannel(msgp->getSender(), channel_type);
  180. if (!tscp)
  181. {
  182. llwarns << "Source channel not found" << llendl;
  183. return;
  184. }
  185. if (tscp->findTransferSource(transfer_id))
  186. {
  187. llwarns << "Duplicate request for transfer " << transfer_id << ", aborting!" << llendl;
  188. return;
  189. }
  190. S32 size = msgp->getSize("TransferInfo", "Params");
  191. if(size > MAX_PARAMS_SIZE)
  192. {
  193. llwarns << "LLTransferManager::processTransferRequest params too big."
  194. << llendl;
  195. return;
  196. }
  197. //llinfos << transfer_id << ":" << source_type << ":" << channel_type << ":" << priority << llendl;
  198. LLTransferSource* tsp = LLTransferSource::createSource(
  199. source_type,
  200. transfer_id,
  201. priority);
  202. if(!tsp)
  203. {
  204. llwarns << "LLTransferManager::processTransferRequest couldn't create"
  205. << " transfer source!" << llendl;
  206. return;
  207. }
  208. U8 tmp[MAX_PARAMS_SIZE];
  209. msgp->getBinaryData("TransferInfo", "Params", tmp, size);
  210. LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE);
  211. BOOL unpack_ok = tsp->unpackParams(dpb);
  212. if (!unpack_ok)
  213. {
  214. // This should only happen if the data is corrupt or
  215. // incorrectly packed.
  216. // *NOTE: We may want to call abortTransfer().
  217. llwarns << "LLTransferManager::processTransferRequest: bad parameters."
  218. << llendl;
  219. delete tsp;
  220. return;
  221. }
  222. tscp->addTransferSource(tsp);
  223. tsp->initTransfer();
  224. }
  225. //static
  226. void LLTransferManager::processTransferInfo(LLMessageSystem *msgp, void **)
  227. {
  228. //llinfos << "LLTransferManager::processTransferInfo" << llendl;
  229. LLUUID transfer_id;
  230. LLTransferTargetType target_type;
  231. LLTransferChannelType channel_type;
  232. LLTSCode status;
  233. S32 size;
  234. msgp->getUUID("TransferInfo", "TransferID", transfer_id);
  235. msgp->getS32("TransferInfo", "TargetType", (S32 &)target_type);
  236. msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type);
  237. msgp->getS32("TransferInfo", "Status", (S32 &)status);
  238. msgp->getS32("TransferInfo", "Size", size);
  239. //llinfos << transfer_id << ":" << target_type<< ":" << channel_type << llendl;
  240. LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type);
  241. if (!ttcp)
  242. {
  243. llwarns << "Target channel not found" << llendl;
  244. // Should send a message to abort the transfer.
  245. return;
  246. }
  247. LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id);
  248. if (!ttp)
  249. {
  250. llwarns << "TransferInfo for unknown transfer! Not able to handle this yet!" << llendl;
  251. // This could happen if we're doing a push transfer, although to avoid confusion,
  252. // maybe it should be a different message.
  253. return;
  254. }
  255. if (status != LLTS_OK)
  256. {
  257. llwarns << transfer_id << ": Non-ok status, cleaning up" << llendl;
  258. ttp->completionCallback(status);
  259. // Clean up the transfer.
  260. ttcp->deleteTransfer(ttp);
  261. return;
  262. }
  263. // unpack the params
  264. S32 params_size = msgp->getSize("TransferInfo", "Params");
  265. if(params_size > MAX_PARAMS_SIZE)
  266. {
  267. llwarns << "LLTransferManager::processTransferInfo params too big."
  268. << llendl;
  269. return;
  270. }
  271. else if(params_size > 0)
  272. {
  273. U8 tmp[MAX_PARAMS_SIZE];
  274. msgp->getBinaryData("TransferInfo", "Params", tmp, params_size);
  275. LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE);
  276. if (!ttp->unpackParams(dpb))
  277. {
  278. // This should only happen if the data is corrupt or
  279. // incorrectly packed.
  280. llwarns << "LLTransferManager::processTransferRequest: bad params."
  281. << llendl;
  282. ttp->abortTransfer();
  283. ttcp->deleteTransfer(ttp);
  284. return;
  285. }
  286. }
  287. //llinfos << "Receiving " << transfer_id << ", size " << size << " bytes" << llendl;
  288. ttp->setSize(size);
  289. ttp->setGotInfo(TRUE);
  290. // OK, at this point we to handle any delayed transfer packets (which could happen
  291. // if this packet was lost)
  292. // This is a lame cut and paste of code down below. If we change the logic down there,
  293. // we HAVE to change the logic up here.
  294. while (1)
  295. {
  296. S32 packet_id = 0;
  297. U8 tmp_data[MAX_PACKET_DATA_SIZE];
  298. // See if we've got any delayed packets
  299. packet_id = ttp->getNextPacketID();
  300. if (ttp->mDelayedPacketMap.find(packet_id) != ttp->mDelayedPacketMap.end())
  301. {
  302. // Perhaps this stuff should be inside a method in LLTransferPacket?
  303. // I'm too lazy to do it now, though.
  304. // llinfos << "Playing back delayed packet " << packet_id << llendl;
  305. LLTransferPacket *packetp = ttp->mDelayedPacketMap[packet_id];
  306. // This is somewhat inefficient, but avoids us having to duplicate
  307. // code between the off-the-wire and delayed paths.
  308. packet_id = packetp->mPacketID;
  309. size = packetp->mSize;
  310. if (size)
  311. {
  312. if ((packetp->mDatap != NULL) && (size<(S32)sizeof(tmp_data)))
  313. {
  314. memcpy(tmp_data, packetp->mDatap, size); /*Flawfinder: ignore*/
  315. }
  316. }
  317. status = packetp->mStatus;
  318. ttp->mDelayedPacketMap.erase(packet_id);
  319. delete packetp;
  320. }
  321. else
  322. {
  323. // No matching delayed packet, we're done.
  324. break;
  325. }
  326. LLTSCode ret_code = ttp->dataCallback(packet_id, tmp_data, size);
  327. if (ret_code == LLTS_OK)
  328. {
  329. ttp->setLastPacketID(packet_id);
  330. }
  331. if (status != LLTS_OK)
  332. {
  333. if (status != LLTS_DONE)
  334. {
  335. llwarns << "LLTransferManager::processTransferInfo Error in playback!" << llendl;
  336. }
  337. else
  338. {
  339. llinfos << "LLTransferManager::processTransferInfo replay FINISHED for " << transfer_id << llendl;
  340. }
  341. // This transfer is done, either via error or not.
  342. ttp->completionCallback(status);
  343. ttcp->deleteTransfer(ttp);
  344. return;
  345. }
  346. }
  347. }
  348. //static
  349. void LLTransferManager::processTransferPacket(LLMessageSystem *msgp, void **)
  350. {
  351. //llinfos << "LLTransferManager::processTransferPacket" << llendl;
  352. LLUUID transfer_id;
  353. LLTransferChannelType channel_type;
  354. S32 packet_id;
  355. LLTSCode status;
  356. S32 size;
  357. msgp->getUUID("TransferData", "TransferID", transfer_id);
  358. msgp->getS32("TransferData", "ChannelType", (S32 &)channel_type);
  359. msgp->getS32("TransferData", "Packet", packet_id);
  360. msgp->getS32("TransferData", "Status", (S32 &)status);
  361. // Find the transfer associated with this packet.
  362. //llinfos << transfer_id << ":" << channel_type << llendl;
  363. LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type);
  364. if (!ttcp)
  365. {
  366. llwarns << "Target channel not found" << llendl;
  367. return;
  368. }
  369. LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id);
  370. if (!ttp)
  371. {
  372. llwarns << "Didn't find matching transfer for " << transfer_id
  373. << " processing packet " << packet_id
  374. << " from " << msgp->getSender() << llendl;
  375. return;
  376. }
  377. size = msgp->getSize("TransferData", "Data");
  378. S32 msg_bytes = 0;
  379. if (msgp->getReceiveCompressedSize())
  380. {
  381. msg_bytes = msgp->getReceiveCompressedSize();
  382. }
  383. else
  384. {
  385. msg_bytes = msgp->getReceiveSize();
  386. }
  387. gTransferManager.addTransferBitsIn(ttcp->mChannelType, msg_bytes*8);
  388. if ((size < 0) || (size > MAX_PACKET_DATA_SIZE))
  389. {
  390. llwarns << "Invalid transfer packet size " << size << llendl;
  391. return;
  392. }
  393. U8 tmp_data[MAX_PACKET_DATA_SIZE];
  394. if (size > 0)
  395. {
  396. // Only pull the data out if the size is > 0
  397. msgp->getBinaryData("TransferData", "Data", tmp_data, size);
  398. }
  399. if ((!ttp->gotInfo()) || (ttp->getNextPacketID() != packet_id))
  400. {
  401. // Put this on a list of packets to be delivered later.
  402. if(!ttp->addDelayedPacket(packet_id, status, tmp_data, size))
  403. {
  404. // Whoops - failed to add a delayed packet for some reason.
  405. llwarns << "Too many delayed packets processing transfer "
  406. << transfer_id << " from " << msgp->getSender() << llendl;
  407. ttp->abortTransfer();
  408. ttcp->deleteTransfer(ttp);
  409. return;
  410. }
  411. #if 0
  412. // Spammy!
  413. const S32 LL_TRANSFER_WARN_GAP = 10;
  414. if(!ttp->gotInfo())
  415. {
  416. llwarns << "Got data packet before information in transfer "
  417. << transfer_id << " from " << msgp->getSender()
  418. << ", got " << packet_id << llendl;
  419. }
  420. else if((packet_id - ttp->getNextPacketID()) > LL_TRANSFER_WARN_GAP)
  421. {
  422. llwarns << "Out of order packet in transfer " << transfer_id
  423. << " from " << msgp->getSender() << ", got " << packet_id
  424. << " expecting " << ttp->getNextPacketID() << llendl;
  425. }
  426. #endif
  427. return;
  428. }
  429. // Loop through this until we're done with all delayed packets
  430. //
  431. // NOTE: THERE IS A CUT AND PASTE OF THIS CODE IN THE TRANSFERINFO HANDLER
  432. // SO WE CAN PLAY BACK DELAYED PACKETS THERE!!!!!!!!!!!!!!!!!!!!!!!!!
  433. //
  434. BOOL done = FALSE;
  435. while (!done)
  436. {
  437. LLTSCode ret_code = ttp->dataCallback(packet_id, tmp_data, size);
  438. if (ret_code == LLTS_OK)
  439. {
  440. ttp->setLastPacketID(packet_id);
  441. }
  442. if (status != LLTS_OK)
  443. {
  444. if (status != LLTS_DONE)
  445. {
  446. llwarns << "LLTransferManager::processTransferPacket Error in transfer!" << llendl;
  447. }
  448. else
  449. {
  450. // llinfos << "LLTransferManager::processTransferPacket done for " << transfer_id << llendl;
  451. }
  452. // This transfer is done, either via error or not.
  453. ttp->completionCallback(status);
  454. ttcp->deleteTransfer(ttp);
  455. return;
  456. }
  457. // See if we've got any delayed packets
  458. packet_id = ttp->getNextPacketID();
  459. if (ttp->mDelayedPacketMap.find(packet_id) != ttp->mDelayedPacketMap.end())
  460. {
  461. // Perhaps this stuff should be inside a method in LLTransferPacket?
  462. // I'm too lazy to do it now, though.
  463. // llinfos << "Playing back delayed packet " << packet_id << llendl;
  464. LLTransferPacket *packetp = ttp->mDelayedPacketMap[packet_id];
  465. // This is somewhat inefficient, but avoids us having to duplicate
  466. // code between the off-the-wire and delayed paths.
  467. packet_id = packetp->mPacketID;
  468. size = packetp->mSize;
  469. if (size)
  470. {
  471. if ((packetp->mDatap != NULL) && (size<(S32)sizeof(tmp_data)))
  472. {
  473. memcpy(tmp_data, packetp->mDatap, size); /*Flawfinder: ignore*/
  474. }
  475. }
  476. status = packetp->mStatus;
  477. ttp->mDelayedPacketMap.erase(packet_id);
  478. delete packetp;
  479. }
  480. else
  481. {
  482. // No matching delayed packet, abort it.
  483. done = TRUE;
  484. }
  485. }
  486. }
  487. //static
  488. void LLTransferManager::processTransferAbort(LLMessageSystem *msgp, void **)
  489. {
  490. //llinfos << "LLTransferManager::processTransferPacket" << llendl;
  491. LLUUID transfer_id;
  492. LLTransferChannelType channel_type;
  493. msgp->getUUID("TransferInfo", "TransferID", transfer_id);
  494. msgp->getS32("TransferInfo", "ChannelType", (S32 &)channel_type);
  495. // See if it's a target that we're trying to abort
  496. // Find the transfer associated with this packet.
  497. LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(msgp->getSender(), channel_type);
  498. if (ttcp)
  499. {
  500. LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id);
  501. if (ttp)
  502. {
  503. ttp->abortTransfer();
  504. ttcp->deleteTransfer(ttp);
  505. return;
  506. }
  507. }
  508. // Hmm, not a target. Maybe it's a source.
  509. LLTransferSourceChannel *tscp = gTransferManager.getSourceChannel(msgp->getSender(), channel_type);
  510. if (tscp)
  511. {
  512. LLTransferSource *tsp = tscp->findTransferSource(transfer_id);
  513. if (tsp)
  514. {
  515. tsp->abortTransfer();
  516. tscp->deleteTransfer(tsp);
  517. return;
  518. }
  519. }
  520. llwarns << "Couldn't find transfer " << transfer_id << " to abort!" << llendl;
  521. }
  522. //static
  523. void LLTransferManager::reliablePacketCallback(void **user_data, S32 result)
  524. {
  525. LLUUID *transfer_idp = (LLUUID *)user_data;
  526. if (result)
  527. {
  528. llwarns << "Aborting reliable transfer " << *transfer_idp << " due to failed reliable resends!" << llendl;
  529. LLTransferSource *tsp = gTransferManager.findTransferSource(*transfer_idp);
  530. if (tsp)
  531. {
  532. LLTransferSourceChannel *tscp = tsp->mChannelp;
  533. tsp->abortTransfer();
  534. tscp->deleteTransfer(tsp);
  535. }
  536. }
  537. delete transfer_idp;
  538. }
  539. //
  540. // LLTransferConnection implementation
  541. //
  542. LLTransferConnection::LLTransferConnection(const LLHost &host)
  543. {
  544. mHost = host;
  545. }
  546. LLTransferConnection::~LLTransferConnection()
  547. {
  548. tsc_iter itersc;
  549. for (itersc = mTransferSourceChannels.begin(); itersc != mTransferSourceChannels.end(); itersc++)
  550. {
  551. delete *itersc;
  552. }
  553. mTransferSourceChannels.clear();
  554. ttc_iter itertc;
  555. for (itertc = mTransferTargetChannels.begin(); itertc != mTransferTargetChannels.end(); itertc++)
  556. {
  557. delete *itertc;
  558. }
  559. mTransferTargetChannels.clear();
  560. }
  561. void LLTransferConnection::updateTransfers()
  562. {
  563. // Do stuff for source transfers (basically, send data out).
  564. tsc_iter iter, cur;
  565. iter = mTransferSourceChannels.begin();
  566. while (iter !=mTransferSourceChannels.end())
  567. {
  568. cur = iter;
  569. iter++;
  570. (*cur)->updateTransfers();
  571. }
  572. // Do stuff for target transfers
  573. // Primarily, we should be aborting transfers that are irredeemably broken
  574. // (large packet gaps that don't appear to be getting filled in, most likely)
  575. // Probably should NOT be doing timeouts for other things, as new priority scheme
  576. // means that a high priority transfer COULD block a transfer for a long time.
  577. }
  578. LLTransferSourceChannel *LLTransferConnection::getSourceChannel(const LLTransferChannelType channel_type)
  579. {
  580. tsc_iter iter;
  581. for (iter = mTransferSourceChannels.begin(); iter != mTransferSourceChannels.end(); iter++)
  582. {
  583. if ((*iter)->getChannelType() == channel_type)
  584. {
  585. return *iter;
  586. }
  587. }
  588. LLTransferSourceChannel *tscp = new LLTransferSourceChannel(channel_type, mHost);
  589. mTransferSourceChannels.push_back(tscp);
  590. return tscp;
  591. }
  592. LLTransferTargetChannel *LLTransferConnection::getTargetChannel(const LLTransferChannelType channel_type)
  593. {
  594. ttc_iter iter;
  595. for (iter = mTransferTargetChannels.begin(); iter != mTransferTargetChannels.end(); iter++)
  596. {
  597. if ((*iter)->getChannelType() == channel_type)
  598. {
  599. return *iter;
  600. }
  601. }
  602. LLTransferTargetChannel *ttcp = new LLTransferTargetChannel(channel_type, mHost);
  603. mTransferTargetChannels.push_back(ttcp);
  604. return ttcp;
  605. }
  606. //
  607. // LLTransferSourceChannel implementation
  608. //
  609. const S32 DEFAULT_PACKET_SIZE = 1000;
  610. LLTransferSourceChannel::LLTransferSourceChannel(const LLTransferChannelType channel_type, const LLHost &host) :
  611. mChannelType(channel_type),
  612. mHost(host),
  613. mTransferSources(LLTransferSource::sSetPriority, LLTransferSource::sGetPriority),
  614. mThrottleID(TC_ASSET)
  615. {
  616. }
  617. LLTransferSourceChannel::~LLTransferSourceChannel()
  618. {
  619. LLPriQueueMap<LLTransferSource*>::pqm_iter iter =
  620. mTransferSources.mMap.begin();
  621. LLPriQueueMap<LLTransferSource*>::pqm_iter end =
  622. mTransferSources.mMap.end();
  623. for (; iter != end; ++iter)
  624. {
  625. // Just kill off all of the transfers
  626. (*iter).second->abortTransfer();
  627. delete iter->second;
  628. }
  629. mTransferSources.mMap.clear();
  630. }
  631. void LLTransferSourceChannel::updatePriority(LLTransferSource *tsp, const F32 priority)
  632. {
  633. mTransferSources.reprioritize(priority, tsp);
  634. }
  635. void LLTransferSourceChannel::updateTransfers()
  636. {
  637. // Actually, this should do the following:
  638. // Decide if we can actually send data.
  639. // If so, update priorities so we know who gets to send it.
  640. // Send data from the sources, while updating until we've sent our throttle allocation.
  641. LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(getHost());
  642. if (!cdp)
  643. {
  644. return;
  645. }
  646. if (cdp->isBlocked())
  647. {
  648. // *NOTE: We need to make sure that the throttle bits
  649. // available gets reset.
  650. // We DON'T want to send any packets if they're blocked, they'll just end up
  651. // piling up on the other end.
  652. //llwarns << "Blocking transfers due to blocked circuit for " << getHost() << llendl;
  653. return;
  654. }
  655. const S32 throttle_id = mThrottleID;
  656. LLThrottleGroup &tg = cdp->getThrottleGroup();
  657. if (tg.checkOverflow(throttle_id, 0.f))
  658. {
  659. return;
  660. }
  661. LLPriQueueMap<LLTransferSource *>::pqm_iter iter, next;
  662. BOOL done = FALSE;
  663. for (iter = mTransferSources.mMap.begin(); (iter != mTransferSources.mMap.end()) && !done;)
  664. {
  665. //llinfos << "LLTransferSourceChannel::updateTransfers()" << llendl;
  666. // Do stuff.
  667. next = iter;
  668. next++;
  669. LLTransferSource *tsp = iter->second;
  670. U8 *datap = NULL;
  671. S32 data_size = 0;
  672. BOOL delete_data = FALSE;
  673. S32 packet_id = 0;
  674. S32 sent_bytes = 0;
  675. LLTSCode status = LLTS_OK;
  676. // Get the packetID for the next packet that we're transferring.
  677. packet_id = tsp->getNextPacketID();
  678. status = tsp->dataCallback(packet_id, DEFAULT_PACKET_SIZE, &datap, data_size, delete_data);
  679. if (status == LLTS_SKIP)
  680. {
  681. // We don't have any data, but we're not done, just go on.
  682. // This will presumably be used for streaming or async transfers that
  683. // are stalled waiting for data from another source.
  684. iter=next;
  685. continue;
  686. }
  687. LLUUID *cb_uuid = new LLUUID(tsp->getID());
  688. LLUUID transaction_id = tsp->getID();
  689. // Send the data now, even if it's an error.
  690. // The status code will tell the other end what to do.
  691. gMessageSystem->newMessage("TransferPacket");
  692. gMessageSystem->nextBlock("TransferData");
  693. gMessageSystem->addUUID("TransferID", tsp->getID());
  694. gMessageSystem->addS32("ChannelType", getChannelType());
  695. gMessageSystem->addS32("Packet", packet_id); // HACK! Need to put in a REAL packet id
  696. gMessageSystem->addS32("Status", status);
  697. gMessageSystem->addBinaryData("Data", datap, data_size);
  698. sent_bytes = gMessageSystem->getCurrentSendTotal();
  699. gMessageSystem->sendReliable(getHost(), LL_DEFAULT_RELIABLE_RETRIES, TRUE, 0.f,
  700. LLTransferManager::reliablePacketCallback, (void**)cb_uuid);
  701. // Do bookkeeping for the throttle
  702. done = tg.throttleOverflow(throttle_id, sent_bytes*8.f);
  703. gTransferManager.addTransferBitsOut(mChannelType, sent_bytes*8);
  704. // Clean up our temporary data.
  705. if (delete_data)
  706. {
  707. delete[] datap;
  708. datap = NULL;
  709. }
  710. if (findTransferSource(transaction_id) == NULL)
  711. {
  712. //Warning! In the case of an aborted transfer, the sendReliable call above calls
  713. //AbortTransfer which in turn calls deleteTransfer which means that somewhere way
  714. //down the chain our current iter can get invalidated resulting in an infrequent
  715. //sim crash. This check gets us to a valid transfer source in this event.
  716. iter=next;
  717. continue;
  718. }
  719. // Update the packet counter
  720. tsp->setLastPacketID(packet_id);
  721. switch (status)
  722. {
  723. case LLTS_OK:
  724. // We're OK, don't need to do anything. Keep sending data.
  725. break;
  726. case LLTS_ERROR:
  727. llwarns << "Error in transfer dataCallback!" << llendl;
  728. // fall through
  729. case LLTS_DONE:
  730. // We need to clean up this transfer source.
  731. //llinfos << "LLTransferSourceChannel::updateTransfers() " << tsp->getID() << " done" << llendl;
  732. tsp->completionCallback(status);
  733. delete tsp;
  734. mTransferSources.mMap.erase(iter);
  735. iter = next;
  736. break;
  737. default:
  738. llerrs << "Unknown transfer error code!" << llendl;
  739. }
  740. // At this point, we should do priority adjustment (since some transfers like
  741. // streaming transfers will adjust priority based on how much they've sent and time,
  742. // but I'm not going to bother yet. - djs.
  743. }
  744. }
  745. void LLTransferSourceChannel::addTransferSource(LLTransferSource *sourcep)
  746. {
  747. sourcep->mChannelp = this;
  748. mTransferSources.push(sourcep->getPriority(), sourcep);
  749. }
  750. LLTransferSource *LLTransferSourceChannel::findTransferSource(const LLUUID &transfer_id)
  751. {
  752. LLPriQueueMap<LLTransferSource *>::pqm_iter iter;
  753. for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++)
  754. {
  755. LLTransferSource *tsp = iter->second;
  756. if (tsp->getID() == transfer_id)
  757. {
  758. return tsp;
  759. }
  760. }
  761. return NULL;
  762. }
  763. BOOL LLTransferSourceChannel::deleteTransfer(LLTransferSource *tsp)
  764. {
  765. LLPriQueueMap<LLTransferSource *>::pqm_iter iter;
  766. for (iter = mTransferSources.mMap.begin(); iter != mTransferSources.mMap.end(); iter++)
  767. {
  768. if (iter->second == tsp)
  769. {
  770. delete tsp;
  771. mTransferSources.mMap.erase(iter);
  772. return TRUE;
  773. }
  774. }
  775. llerrs << "Unable to find transfer source to delete!" << llendl;
  776. return FALSE;
  777. }
  778. //
  779. // LLTransferTargetChannel implementation
  780. //
  781. LLTransferTargetChannel::LLTransferTargetChannel(const LLTransferChannelType channel_type, const LLHost &host) :
  782. mChannelType(channel_type),
  783. mHost(host)
  784. {
  785. }
  786. LLTransferTargetChannel::~LLTransferTargetChannel()
  787. {
  788. tt_iter iter;
  789. for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++)
  790. {
  791. // Abort all of the current transfers
  792. (*iter)->abortTransfer();
  793. delete *iter;
  794. }
  795. mTransferTargets.clear();
  796. }
  797. void LLTransferTargetChannel::requestTransfer(
  798. const LLTransferSourceParams& source_params,
  799. const LLTransferTargetParams& target_params,
  800. const F32 priority)
  801. {
  802. LLUUID id;
  803. id.generate();
  804. LLTransferTarget* ttp = LLTransferTarget::createTarget(
  805. target_params.getType(),
  806. id,
  807. source_params.getType());
  808. if (!ttp)
  809. {
  810. llwarns << "LLTransferManager::requestTransfer aborting due to target creation failure!" << llendl;
  811. return;
  812. }
  813. ttp->applyParams(target_params);
  814. addTransferTarget(ttp);
  815. sendTransferRequest(ttp, source_params, priority);
  816. }
  817. void LLTransferTargetChannel::sendTransferRequest(LLTransferTarget *targetp,
  818. const LLTransferSourceParams &params,
  819. const F32 priority)
  820. {
  821. //
  822. // Pack the message with data which explains how to get the source, and
  823. // send it off to the source for this channel.
  824. //
  825. llassert(targetp);
  826. llassert(targetp->getChannel() == this);
  827. gMessageSystem->newMessage("TransferRequest");
  828. gMessageSystem->nextBlock("TransferInfo");
  829. gMessageSystem->addUUID("TransferID", targetp->getID());
  830. gMessageSystem->addS32("SourceType", params.getType());
  831. gMessageSystem->addS32("ChannelType", getChannelType());
  832. gMessageSystem->addF32("Priority", priority);
  833. U8 tmp[MAX_PARAMS_SIZE];
  834. LLDataPackerBinaryBuffer dp(tmp, MAX_PARAMS_SIZE);
  835. params.packParams(dp);
  836. S32 len = dp.getCurrentSize();
  837. gMessageSystem->addBinaryData("Params", tmp, len);
  838. gMessageSystem->sendReliable(mHost);
  839. }
  840. void LLTransferTargetChannel::addTransferTarget(LLTransferTarget *targetp)
  841. {
  842. targetp->mChannelp = this;
  843. mTransferTargets.push_back(targetp);
  844. }
  845. LLTransferTarget *LLTransferTargetChannel::findTransferTarget(const LLUUID &transfer_id)
  846. {
  847. tt_iter iter;
  848. for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++)
  849. {
  850. LLTransferTarget *ttp = *iter;
  851. if (ttp->getID() == transfer_id)
  852. {
  853. return ttp;
  854. }
  855. }
  856. return NULL;
  857. }
  858. BOOL LLTransferTargetChannel::deleteTransfer(LLTransferTarget *ttp)
  859. {
  860. tt_iter iter;
  861. for (iter = mTransferTargets.begin(); iter != mTransferTargets.end(); iter++)
  862. {
  863. if (*iter == ttp)
  864. {
  865. delete ttp;
  866. mTransferTargets.erase(iter);
  867. return TRUE;
  868. }
  869. }
  870. llerrs << "Unable to find transfer target to delete!" << llendl;
  871. return FALSE;
  872. }
  873. //
  874. // LLTransferSource implementation
  875. //
  876. LLTransferSource::LLTransferSource(const LLTransferSourceType type,
  877. const LLUUID &transfer_id,
  878. const F32 priority) :
  879. mType(type),
  880. mID(transfer_id),
  881. mChannelp(NULL),
  882. mPriority(priority),
  883. mSize(0),
  884. mLastPacketID(-1)
  885. {
  886. setPriority(priority);
  887. }
  888. LLTransferSource::~LLTransferSource()
  889. {
  890. // No actual cleanup of the transfer is done here, this is purely for
  891. // memory cleanup. The completionCallback is guaranteed to get called
  892. // before this happens.
  893. }
  894. void LLTransferSource::sendTransferStatus(LLTSCode status)
  895. {
  896. gMessageSystem->newMessage("TransferInfo");
  897. gMessageSystem->nextBlock("TransferInfo");
  898. gMessageSystem->addUUID("TransferID", getID());
  899. gMessageSystem->addS32("TargetType", LLTTT_UNKNOWN);
  900. gMessageSystem->addS32("ChannelType", mChannelp->getChannelType());
  901. gMessageSystem->addS32("Status", status);
  902. gMessageSystem->addS32("Size", mSize);
  903. U8 tmp[MAX_PARAMS_SIZE];
  904. LLDataPackerBinaryBuffer dp(tmp, MAX_PARAMS_SIZE);
  905. packParams(dp);
  906. S32 len = dp.getCurrentSize();
  907. gMessageSystem->addBinaryData("Params", tmp, len);
  908. gMessageSystem->sendReliable(mChannelp->getHost());
  909. // Abort if there was as asset system issue.
  910. if (status != LLTS_OK)
  911. {
  912. completionCallback(status);
  913. mChannelp->deleteTransfer(this);
  914. }
  915. }
  916. // This should never be called directly, the transfer manager is responsible for
  917. // aborting the transfer from the channel. I might want to rethink this in the
  918. // future, though.
  919. void LLTransferSource::abortTransfer()
  920. {
  921. // Send a message down, call the completion callback
  922. llinfos << "LLTransferSource::Aborting transfer " << getID() << " to " << mChannelp->getHost() << llendl;
  923. gMessageSystem->newMessage("TransferAbort");
  924. gMessageSystem->nextBlock("TransferInfo");
  925. gMessageSystem->addUUID("TransferID", getID());
  926. gMessageSystem->addS32("ChannelType", mChannelp->getChannelType());
  927. gMessageSystem->sendReliable(mChannelp->getHost());
  928. completionCallback(LLTS_ABORT);
  929. }
  930. //static
  931. void LLTransferSource::registerSourceType(const LLTransferSourceType stype, LLTransferSourceCreateFunc func)
  932. {
  933. if (sSourceCreateMap.count(stype))
  934. {
  935. // Disallow changing what class handles a source type
  936. // Unclear when you would want to do this, and whether it would work.
  937. llerrs << "Reregistering source type " << stype << llendl;
  938. }
  939. else
  940. {
  941. sSourceCreateMap[stype] = func;
  942. }
  943. }
  944. //static
  945. LLTransferSource *LLTransferSource::createSource(const LLTransferSourceType stype,
  946. const LLUUID &id,
  947. const F32 priority)
  948. {
  949. switch (stype)
  950. {
  951. // *NOTE: The source file transfer mechanism is highly insecure and could
  952. // lead to easy exploitation of a server process.
  953. // I have removed all uses of it from the codebase. Phoenix.
  954. //
  955. //case LLTST_FILE:
  956. // return new LLTransferSourceFile(id, priority);
  957. case LLTST_ASSET:
  958. return new LLTransferSourceAsset(id, priority);
  959. default:
  960. {
  961. if (!sSourceCreateMap.count(stype))
  962. {
  963. // Use the callback to create the source type if it's not there.
  964. llwarns << "Unknown transfer source type: " << stype << llendl;
  965. return NULL;
  966. }
  967. return (sSourceCreateMap[stype])(id, priority);
  968. }
  969. }
  970. }
  971. // static
  972. void LLTransferSource::sSetPriority(LLTransferSource *&tsp, const F32 priority)
  973. {
  974. tsp->setPriority(priority);
  975. }
  976. // static
  977. F32 LLTransferSource::sGetPriority(LLTransferSource *&tsp)
  978. {
  979. return tsp->getPriority();
  980. }
  981. //
  982. // LLTransferPacket implementation
  983. //
  984. LLTransferPacket::LLTransferPacket(const S32 packet_id, const LLTSCode status, const U8 *datap, const S32 size) :
  985. mPacketID(packet_id),
  986. mStatus(status),
  987. mDatap(NULL),
  988. mSize(size)
  989. {
  990. if (size == 0)
  991. {
  992. return;
  993. }
  994. mDatap = new U8[size];
  995. if (mDatap != NULL)
  996. {
  997. memcpy(mDatap, datap, size); /*Flawfinder: ignore*/
  998. }
  999. }
  1000. LLTransferPacket::~LLTransferPacket()
  1001. {
  1002. delete[] mDatap;
  1003. }
  1004. //
  1005. // LLTransferTarget implementation
  1006. //
  1007. LLTransferTarget::LLTransferTarget(
  1008. LLTransferTargetType type,
  1009. const LLUUID& transfer_id,
  1010. LLTransferSourceType source_type) :
  1011. mType(type),
  1012. mSourceType(source_type),
  1013. mID(transfer_id),
  1014. mChannelp(NULL),
  1015. mGotInfo(FALSE),
  1016. mSize(0),
  1017. mLastPacketID(-1)
  1018. {
  1019. }
  1020. LLTransferTarget::~LLTransferTarget()
  1021. {
  1022. // No actual cleanup of the transfer is done here, this is purely for
  1023. // memory cleanup. The completionCallback is guaranteed to get called
  1024. // before this happens.
  1025. tpm_iter iter;
  1026. for (iter = mDelayedPacketMap.begin(); iter != mDelayedPacketMap.end(); iter++)
  1027. {
  1028. delete iter->second;
  1029. }
  1030. mDelayedPacketMap.clear();
  1031. }
  1032. // This should never be called directly, the transfer manager is responsible for
  1033. // aborting the transfer from the channel. I might want to rethink this in the
  1034. // future, though.
  1035. void LLTransferTarget::abortTransfer()
  1036. {
  1037. // Send a message up, call the completion callback
  1038. llinfos << "LLTransferTarget::Aborting transfer " << getID() << " from " << mChannelp->getHost() << llendl;
  1039. gMessageSystem->newMessage("TransferAbort");
  1040. gMessageSystem->nextBlock("TransferInfo");
  1041. gMessageSystem->addUUID("TransferID", getID());
  1042. gMessageSystem->addS32("ChannelType", mChannelp->getChannelType());
  1043. gMessageSystem->sendReliable(mChannelp->getHost());
  1044. completionCallback(LLTS_ABORT);
  1045. }
  1046. bool LLTransferTarget::addDelayedPacket(
  1047. const S32 packet_id,
  1048. const LLTSCode status,
  1049. U8* datap,
  1050. const S32 size)
  1051. {
  1052. const transfer_packet_map::size_type LL_MAX_DELAYED_PACKETS = 100;
  1053. if(mDelayedPacketMap.size() > LL_MAX_DELAYED_PACKETS)
  1054. {
  1055. // too many delayed packets
  1056. return false;
  1057. }
  1058. LLTransferPacket* tpp = new LLTransferPacket(
  1059. packet_id,
  1060. status,
  1061. datap,
  1062. size);
  1063. #ifdef _DEBUG
  1064. if (mDelayedPacketMap.find(packet_id) != mDelayedPacketMap.end())
  1065. {
  1066. llerrs << "Packet ALREADY in delayed packet map!" << llendl;
  1067. }
  1068. #endif
  1069. mDelayedPacketMap[packet_id] = tpp;
  1070. return true;
  1071. }
  1072. LLTransferTarget* LLTransferTarget::createTarget(
  1073. LLTransferTargetType type,
  1074. const LLUUID& id,
  1075. LLTransferSourceType source_type)
  1076. {
  1077. switch (type)
  1078. {
  1079. case LLTTT_FILE:
  1080. return new LLTransferTargetFile(id, source_type);
  1081. case LLTTT_VFILE:
  1082. return new LLTransferTargetVFile(id, source_type);
  1083. default:
  1084. llwarns << "Unknown transfer target type: " << type << llendl;
  1085. return NULL;
  1086. }
  1087. }
  1088. LLTransferSourceParamsInvItem::LLTransferSourceParamsInvItem() : LLTransferSourceParams(LLTST_SIM_INV_ITEM), mAssetType(LLAssetType::AT_NONE)
  1089. {
  1090. }
  1091. void LLTransferSourceParamsInvItem::setAgentSession(const LLUUID &agent_id, const LLUUID &session_id)
  1092. {
  1093. mAgentID = agent_id;
  1094. mSessionID = session_id;
  1095. }
  1096. void LLTransferSourceParamsInvItem::setInvItem(const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id)
  1097. {
  1098. mOwnerID = owner_id;
  1099. mTaskID = task_id;
  1100. mItemID = item_id;
  1101. }
  1102. void LLTransferSourceParamsInvItem::setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type)
  1103. {
  1104. mAssetID = asset_id;
  1105. mAssetType = asset_type;
  1106. }
  1107. void LLTransferSourceParamsInvItem::packParams(LLDataPacker &dp) const
  1108. {
  1109. lldebugs << "LLTransferSourceParamsInvItem::packParams()" << llendl;
  1110. dp.packUUID(mAgentID, "AgentID");
  1111. dp.packUUID(mSessionID, "SessionID");
  1112. dp.packUUID(mOwnerID, "OwnerID");
  1113. dp.packUUID(mTaskID, "TaskID");
  1114. dp.packUUID(mItemID, "ItemID");
  1115. dp.packUUID(mAssetID, "AssetID");
  1116. dp.packS32(mAssetType, "AssetType");
  1117. }
  1118. BOOL LLTransferSourceParamsInvItem::unpackParams(LLDataPacker &dp)
  1119. {
  1120. S32 tmp_at;
  1121. dp.unpackUUID(mAgentID, "AgentID");
  1122. dp.unpackUUID(mSessionID, "SessionID");
  1123. dp.unpackUUID(mOwnerID, "OwnerID");
  1124. dp.unpackUUID(mTaskID, "TaskID");
  1125. dp.unpackUUID(mItemID, "ItemID");
  1126. dp.unpackUUID(mAssetID, "AssetID");
  1127. dp.unpackS32(tmp_at, "AssetType");
  1128. mAssetType = (LLAssetType::EType)tmp_at;
  1129. return TRUE;
  1130. }
  1131. LLTransferSourceParamsEstate::LLTransferSourceParamsEstate() :
  1132. LLTransferSourceParams(LLTST_SIM_ESTATE),
  1133. mEstateAssetType(ET_NONE),
  1134. mAssetType(LLAssetType::AT_NONE)
  1135. {
  1136. }
  1137. void LLTransferSourceParamsEstate::setAgentSession(const LLUUID &agent_id, const LLUUID &session_id)
  1138. {
  1139. mAgentID = agent_id;
  1140. mSessionID = session_id;
  1141. }
  1142. void LLTransferSourceParamsEstate::setEstateAssetType(const EstateAssetType etype)
  1143. {
  1144. mEstateAssetType = etype;
  1145. }
  1146. void LLTransferSourceParamsEstate::setAsset(const LLUUID &asset_id, const LLAssetType::EType asset_type)
  1147. {
  1148. mAssetID = asset_id;
  1149. mAssetType = asset_type;
  1150. }
  1151. void LLTransferSourceParamsEstate::packParams(LLDataPacker &dp) const
  1152. {
  1153. dp.packUUID(mAgentID, "AgentID");
  1154. // *NOTE: We do not want to pass the session id from the server to
  1155. // the client, but I am not sure if anyone expects this value to
  1156. // be set on the client.
  1157. dp.packUUID(mSessionID, "SessionID");
  1158. dp.packS32(mEstateAssetType, "EstateAssetType");
  1159. }
  1160. BOOL LLTransferSourceParamsEstate::unpackParams(LLDataPacker &dp)
  1161. {
  1162. S32 tmp_et;
  1163. dp.unpackUUID(mAgentID, "AgentID");
  1164. dp.unpackUUID(mSessionID, "SessionID");
  1165. dp.unpackS32(tmp_et, "EstateAssetType");
  1166. mEstateAssetType = (EstateAssetType)tmp_et;
  1167. return TRUE;
  1168. }