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

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llcircuit.cpp
  3.  * @brief Class to track UDP endpoints for the message system.
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-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.  
  34. #if LL_WINDOWS
  35. #include <process.h>
  36. #else
  37. #if LL_LINUX
  38. #include <dlfcn.h> // RTLD_LAZY
  39. #endif
  40. #include <sys/types.h>
  41. #include <sys/socket.h>
  42. #include <netinet/in.h>
  43. #endif
  44. #if !defined(USE_CIRCUIT_LIST)
  45. #include <algorithm>
  46. #endif
  47. #include <sstream>
  48. #include <iterator>
  49. #include <stack>
  50. #include "llcircuit.h"
  51. #include "message.h"
  52. #include "llrand.h"
  53. #include "llstl.h"
  54. #include "lltransfermanager.h"
  55. #include "llmodularmath.h"
  56. const S32 PING_START_BLOCK = 3; // How many pings behind we have to be to consider ourself blocked.
  57. const S32 PING_RELEASE_BLOCK = 2; // How many pings behind we have to be to consider ourself unblocked.
  58. const F32 TARGET_PERIOD_LENGTH = 5.f; // seconds
  59. const F32 LL_DUPLICATE_SUPPRESSION_TIMEOUT = 60.f; //seconds - this can be long, as time-based cleanup is
  60. // only done when wrapping packetids, now...
  61. LLCircuitData::LLCircuitData(const LLHost &host, TPACKETID in_id, 
  62.  const F32 circuit_heartbeat_interval, const F32 circuit_timeout)
  63. : mHost (host),
  64. mWrapID(0),
  65. mPacketsOutID(0), 
  66. mPacketsInID(in_id),
  67. mHighestPacketID(in_id),
  68. mTimeoutCallback(NULL),
  69. mTimeoutUserData(NULL),
  70. mTrusted(FALSE),
  71. mbAllowTimeout(TRUE),
  72. mbAlive(TRUE),
  73. mBlocked(FALSE),
  74. mPingTime(0.0),
  75. mLastPingSendTime(0.0),
  76. mLastPingReceivedTime(0.0),
  77. mNextPingSendTime(0.0),
  78. mPingsInTransit(0),
  79. mLastPingID(0),
  80. mPingDelay(INITIAL_PING_VALUE_MSEC), 
  81. mPingDelayAveraged((F32)INITIAL_PING_VALUE_MSEC), 
  82. mUnackedPacketCount(0),
  83. mUnackedPacketBytes(0),
  84. mLocalEndPointID(),
  85. mPacketsOut(0),
  86. mPacketsIn(0), 
  87. mPacketsLost(0),
  88. mBytesIn(0),
  89. mBytesOut(0),
  90. mLastPeriodLength(-1.f),
  91. mBytesInLastPeriod(0),
  92. mBytesOutLastPeriod(0),
  93. mBytesInThisPeriod(0),
  94. mBytesOutThisPeriod(0),
  95. mPeakBPSIn(0.f),
  96. mPeakBPSOut(0.f),
  97. mPeriodTime(0.0),
  98. mExistenceTimer(),
  99. mCurrentResendCount(0),
  100. mLastPacketGap(0),
  101. mHeartbeatInterval(circuit_heartbeat_interval), 
  102. mHeartbeatTimeout(circuit_timeout)
  103. {
  104. // Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been
  105. //  running a message system loop.
  106. F64 mt_sec = LLMessageSystem::getMessageTimeSeconds(TRUE);
  107. F32 distribution_offset = ll_frand();
  108. mPingTime = mt_sec;
  109. mLastPingSendTime = mt_sec + mHeartbeatInterval * distribution_offset;
  110. mLastPingReceivedTime = mt_sec;
  111. mNextPingSendTime = mLastPingSendTime + 0.95*mHeartbeatInterval + ll_frand(0.1f*mHeartbeatInterval);
  112. mPeriodTime = mt_sec;
  113. mLocalEndPointID.generate();
  114. }
  115. LLCircuitData::~LLCircuitData()
  116. {
  117. LLReliablePacket *packetp = NULL;
  118. // Clean up all pending transfers.
  119. gTransferManager.cleanupConnection(mHost);
  120. // remove all pending reliable messages on this circuit
  121. std::vector<TPACKETID> doomed;
  122. reliable_iter iter;
  123. reliable_iter end = mUnackedPackets.end();
  124. for(iter = mUnackedPackets.begin(); iter != end; ++iter)
  125. {
  126. packetp = iter->second;
  127. gMessageSystem->mFailedResendPackets++;
  128. if(gMessageSystem->mVerboseLog)
  129. {
  130. doomed.push_back(packetp->mPacketID);
  131. }
  132. if (packetp->mCallback)
  133. {
  134. packetp->mCallback(packetp->mCallbackData,LL_ERR_CIRCUIT_GONE);
  135. }
  136. // Update stats
  137. mUnackedPacketCount--;
  138. mUnackedPacketBytes -= packetp->mBufferLength;
  139. delete packetp;
  140. }
  141. // remove all pending final retry reliable messages on this circuit
  142. end = mFinalRetryPackets.end();
  143. for(iter = mFinalRetryPackets.begin(); iter != end; ++iter)
  144. {
  145. packetp = iter->second;
  146. gMessageSystem->mFailedResendPackets++;
  147. if(gMessageSystem->mVerboseLog)
  148. {
  149. doomed.push_back(packetp->mPacketID);
  150. }
  151. if (packetp->mCallback)
  152. {
  153. packetp->mCallback(packetp->mCallbackData,LL_ERR_CIRCUIT_GONE);
  154. }
  155. // Update stats
  156. mUnackedPacketCount--;
  157. mUnackedPacketBytes -= packetp->mBufferLength;
  158. delete packetp;
  159. }
  160. // log aborted reliable packets for this circuit.
  161. if(gMessageSystem->mVerboseLog && !doomed.empty())
  162. {
  163. std::ostringstream str;
  164. std::ostream_iterator<TPACKETID> append(str, " ");
  165. str << "MSG: -> " << mHost << "tABORTING RELIABLE:t";
  166. std::copy(doomed.begin(), doomed.end(), append);
  167. llinfos << str.str() << llendl;
  168. }
  169. }
  170. void LLCircuitData::ackReliablePacket(TPACKETID packet_num)
  171. {
  172. reliable_iter iter;
  173. LLReliablePacket *packetp;
  174. iter = mUnackedPackets.find(packet_num);
  175. if (iter != mUnackedPackets.end())
  176. {
  177. packetp = iter->second;
  178. if(gMessageSystem->mVerboseLog)
  179. {
  180. std::ostringstream str;
  181. str << "MSG: <- " << packetp->mHost << "tRELIABLE ACKED:t"
  182. << packetp->mPacketID;
  183. llinfos << str.str() << llendl;
  184. }
  185. if (packetp->mCallback)
  186. {
  187. if (packetp->mTimeout < 0.f)   // negative timeout will always return timeout even for successful ack, for debugging
  188. {
  189. packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT);
  190. }
  191. else
  192. {
  193. packetp->mCallback(packetp->mCallbackData,LL_ERR_NOERR);
  194. }
  195. }
  196. // Update stats
  197. mUnackedPacketCount--;
  198. mUnackedPacketBytes -= packetp->mBufferLength;
  199. // Cleanup
  200. delete packetp;
  201. mUnackedPackets.erase(iter);
  202. return;
  203. }
  204. iter = mFinalRetryPackets.find(packet_num);
  205. if (iter != mFinalRetryPackets.end())
  206. {
  207. packetp = iter->second;
  208. // llinfos << "Packet " << packet_num << " removed from the pending list" << llendl;
  209. if(gMessageSystem->mVerboseLog)
  210. {
  211. std::ostringstream str;
  212. str << "MSG: <- " << packetp->mHost << "tRELIABLE ACKED:t"
  213. << packetp->mPacketID;
  214. llinfos << str.str() << llendl;
  215. }
  216. if (packetp->mCallback)
  217. {
  218. if (packetp->mTimeout < 0.f)   // negative timeout will always return timeout even for successful ack, for debugging
  219. {
  220. packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT);
  221. }
  222. else
  223. {
  224. packetp->mCallback(packetp->mCallbackData,LL_ERR_NOERR);
  225. }
  226. }
  227. // Update stats
  228. mUnackedPacketCount--;
  229. mUnackedPacketBytes -= packetp->mBufferLength;
  230. // Cleanup
  231. delete packetp;
  232. mFinalRetryPackets.erase(iter);
  233. }
  234. else
  235. {
  236. // Couldn't find this packet on either of the unacked lists.
  237. // maybe it's a duplicate ack?
  238. }
  239. }
  240. S32 LLCircuitData::resendUnackedPackets(const F64 now)
  241. {
  242. S32 resent_packets = 0;
  243. LLReliablePacket *packetp;
  244. //
  245. // Theoretically we should search through the list for the packet with the oldest
  246. // packet ID, as otherwise when we WRAP we will resend reliable packets out of order.
  247. // Since resends are ALREADY out of order, and wrapping is highly rare (16+million packets),
  248. // I'm not going to worry about this for now - djs
  249. //
  250. reliable_iter iter;
  251. BOOL have_resend_overflow = FALSE;
  252. for (iter = mUnackedPackets.begin(); iter != mUnackedPackets.end();)
  253. {
  254. packetp = iter->second;
  255. // Only check overflow if we haven't had one yet.
  256. if (!have_resend_overflow)
  257. {
  258. have_resend_overflow = mThrottles.checkOverflow(TC_RESEND, 0);
  259. }
  260. if (have_resend_overflow)
  261. {
  262. // We've exceeded our bandwidth for resends.
  263. // Time to stop trying to send them.
  264. // If we have too many unacked packets, we need to start dropping expired ones.
  265. if (mUnackedPacketBytes > 512000)
  266. {
  267. if (now > packetp->mExpirationTime)
  268. {
  269. // This circuit has overflowed.  Do not retry.  Do not pass go.
  270. packetp->mRetries = 0;
  271. // Remove it from this list and add it to the final list.
  272. mUnackedPackets.erase(iter++);
  273. mFinalRetryPackets[packetp->mPacketID] = packetp;
  274. }
  275. else
  276. {
  277. ++iter;
  278. }
  279. // Move on to the next unacked packet.
  280. continue;
  281. }
  282. if (mUnackedPacketBytes > 256000 && !(getPacketsOut() % 1024))
  283. {
  284. // Warn if we've got a lot of resends waiting.
  285. llwarns << mHost << " has " << mUnackedPacketBytes 
  286. << " bytes of reliable messages waiting" << llendl;
  287. }
  288. // Stop resending.  There are less than 512000 unacked packets.
  289. break;
  290. }
  291. if (now > packetp->mExpirationTime)
  292. {
  293. packetp->mRetries--;
  294. // retry
  295. mCurrentResendCount++;
  296. gMessageSystem->mResentPackets++;
  297. if(gMessageSystem->mVerboseLog)
  298. {
  299. std::ostringstream str;
  300. str << "MSG: -> " << packetp->mHost
  301. << "tRESENDING RELIABLE:t" << packetp->mPacketID;
  302. llinfos << str.str() << llendl;
  303. }
  304. packetp->mBuffer[0] |= LL_RESENT_FLAG;  // tag packet id as being a resend
  305. gMessageSystem->mPacketRing.sendPacket(packetp->mSocket, 
  306.    (char *)packetp->mBuffer, packetp->mBufferLength, 
  307.    packetp->mHost);
  308. mThrottles.throttleOverflow(TC_RESEND, packetp->mBufferLength * 8.f);
  309. // The new method, retry time based on ping
  310. if (packetp->mPingBasedRetry)
  311. {
  312. packetp->mExpirationTime = now + llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, (LL_RELIABLE_TIMEOUT_FACTOR * getPingDelayAveraged()));
  313. }
  314. else
  315. {
  316. // custom, constant retry time
  317. packetp->mExpirationTime = now + packetp->mTimeout;
  318. }
  319. if (!packetp->mRetries)
  320. {
  321. // Last resend, remove it from this list and add it to the final list.
  322. mUnackedPackets.erase(iter++);
  323. mFinalRetryPackets[packetp->mPacketID] = packetp;
  324. }
  325. else
  326. {
  327. // Don't remove it yet, it still gets to try to resend at least once.
  328. ++iter;
  329. }
  330. resent_packets++;
  331. }
  332. else
  333. {
  334. // Don't need to do anything with this packet, keep iterating.
  335. ++iter;
  336. }
  337. }
  338. for (iter = mFinalRetryPackets.begin(); iter != mFinalRetryPackets.end();)
  339. {
  340. packetp = iter->second;
  341. if (now > packetp->mExpirationTime)
  342. {
  343. // fail (too many retries)
  344. //llinfos << "Packet " << packetp->mPacketID << " removed from the pending list: exceeded retry limit" << llendl;
  345. //if (packetp->mMessageName)
  346. //{
  347. // llinfos << "Packet name " << packetp->mMessageName << llendl;
  348. //}
  349. gMessageSystem->mFailedResendPackets++;
  350. if(gMessageSystem->mVerboseLog)
  351. {
  352. std::ostringstream str;
  353. str << "MSG: -> " << packetp->mHost << "tABORTING RELIABLE:t"
  354. << packetp->mPacketID;
  355. llinfos << str.str() << llendl;
  356. }
  357. if (packetp->mCallback)
  358. {
  359. packetp->mCallback(packetp->mCallbackData,LL_ERR_TCP_TIMEOUT);
  360. }
  361. // Update stats
  362. mUnackedPacketCount--;
  363. mUnackedPacketBytes -= packetp->mBufferLength;
  364. mFinalRetryPackets.erase(iter++);
  365. delete packetp;
  366. }
  367. else
  368. {
  369. ++iter;
  370. }
  371. }
  372. return mUnackedPacketCount;
  373. }
  374. LLCircuit::LLCircuit(const F32 circuit_heartbeat_interval, const F32 circuit_timeout) : mLastCircuit(NULL),  
  375. mHeartbeatInterval(circuit_heartbeat_interval), mHeartbeatTimeout(circuit_timeout)
  376. {
  377. }
  378. LLCircuit::~LLCircuit()
  379. {
  380. // delete pointers in the map.
  381. std::for_each(mCircuitData.begin(),
  382.   mCircuitData.end(),
  383.   llcompose1(
  384.   DeletePointerFunctor<LLCircuitData>(),
  385.   llselect2nd<circuit_data_map::value_type>()));
  386. }
  387. LLCircuitData *LLCircuit::addCircuitData(const LLHost &host, TPACKETID in_id)
  388. {
  389. // This should really validate if one already exists
  390. llinfos << "LLCircuit::addCircuitData for " << host << llendl;
  391. LLCircuitData *tempp = new LLCircuitData(host, in_id, mHeartbeatInterval, mHeartbeatTimeout);
  392. mCircuitData.insert(circuit_data_map::value_type(host, tempp));
  393. mPingSet.insert(tempp);
  394. mLastCircuit = tempp;
  395. return tempp;
  396. }
  397. void LLCircuit::removeCircuitData(const LLHost &host)
  398. {
  399. llinfos << "LLCircuit::removeCircuitData for " << host << llendl;
  400. mLastCircuit = NULL;
  401. circuit_data_map::iterator it = mCircuitData.find(host);
  402. if(it != mCircuitData.end())
  403. {
  404. LLCircuitData *cdp = it->second;
  405. mCircuitData.erase(it);
  406. LLCircuit::ping_set_t::iterator psit = mPingSet.find(cdp);
  407. if (psit != mPingSet.end())
  408.         {
  409.     mPingSet.erase(psit);
  410. }
  411. else
  412. {
  413. llwarns << "Couldn't find entry for next ping in ping set!" << llendl;
  414. }
  415. // Clean up from optimization maps
  416. mUnackedCircuitMap.erase(host);
  417. mSendAckMap.erase(host);
  418. delete cdp;
  419. }
  420. // This also has to happen AFTER we nuke the circuit, because various
  421. // callbacks for the circuit may result in messages being sent to
  422. // this circuit, and the setting of mLastCircuit.  We don't check
  423. // if the host matches, but we don't really care because mLastCircuit
  424. // is an optimization, and this happens VERY rarely.
  425. mLastCircuit = NULL;
  426. }
  427. void LLCircuitData::setAlive(BOOL b_alive)
  428. {
  429. if (mbAlive != b_alive)
  430. {
  431. mPacketsOutID = 0;
  432. mPacketsInID = 0;
  433. mbAlive = b_alive;
  434. }
  435. if (b_alive)
  436. {
  437. mLastPingReceivedTime = LLMessageSystem::getMessageTimeSeconds();
  438. mPingsInTransit = 0;
  439. mBlocked = FALSE;
  440. }
  441. }
  442. void LLCircuitData::setAllowTimeout(BOOL allow)
  443. {
  444. mbAllowTimeout = allow;
  445. if (allow)
  446. {
  447. // resuming circuit
  448. // make sure it's alive
  449. setAlive(TRUE);
  450. }
  451. }
  452. // Reset per-period counters if necessary.
  453. void LLCircuitData::checkPeriodTime()
  454. {
  455. F64 mt_sec = LLMessageSystem::getMessageTimeSeconds();
  456. F64 period_length = mt_sec - mPeriodTime;
  457. if ( period_length > TARGET_PERIOD_LENGTH)
  458. {
  459. F32 bps_in = (F32)(mBytesInThisPeriod * 8.f / period_length);
  460. if (bps_in > mPeakBPSIn)
  461. {
  462. mPeakBPSIn = bps_in;
  463. }
  464. F32 bps_out = (F32)(mBytesOutThisPeriod * 8.f / period_length);
  465. if (bps_out > mPeakBPSOut)
  466. {
  467. mPeakBPSOut = bps_out;
  468. }
  469. mBytesInLastPeriod = mBytesInThisPeriod;
  470. mBytesOutLastPeriod = mBytesOutThisPeriod;
  471. mBytesInThisPeriod = 0;
  472. mBytesOutThisPeriod = 0;
  473. mLastPeriodLength = (F32)period_length;
  474. mPeriodTime = mt_sec;
  475. }
  476. }
  477. void LLCircuitData::addBytesIn(S32 bytes)
  478. {
  479. mBytesIn += bytes;
  480. mBytesInThisPeriod += bytes;
  481. }
  482. void LLCircuitData::addBytesOut(S32 bytes)
  483. {
  484. mBytesOut += bytes;
  485. mBytesOutThisPeriod += bytes;
  486. }
  487. void LLCircuitData::addReliablePacket(S32 mSocket, U8 *buf_ptr, S32 buf_len, LLReliablePacketParams *params)
  488. {
  489. LLReliablePacket *packet_info;
  490. packet_info = new LLReliablePacket(mSocket, buf_ptr, buf_len, params);
  491. mUnackedPacketCount++;
  492. mUnackedPacketBytes += packet_info->mBufferLength;
  493. if (params && params->mRetries)
  494. {
  495. mUnackedPackets[packet_info->mPacketID] = packet_info;
  496. }
  497. else
  498. {
  499. mFinalRetryPackets[packet_info->mPacketID] = packet_info;
  500. }
  501. }
  502. void LLCircuit::resendUnackedPackets(S32& unacked_list_length, S32& unacked_list_size)
  503. {
  504. F64 now = LLMessageSystem::getMessageTimeSeconds();
  505. unacked_list_length = 0;
  506. unacked_list_size = 0;
  507. LLCircuitData* circ;
  508. circuit_data_map::iterator end = mUnackedCircuitMap.end();
  509. for(circuit_data_map::iterator it = mUnackedCircuitMap.begin(); it != end; ++it)
  510. {
  511. circ = (*it).second;
  512. unacked_list_length += circ->resendUnackedPackets(now);
  513. unacked_list_size += circ->getUnackedPacketBytes();
  514. }
  515. }
  516. BOOL LLCircuitData::isDuplicateResend(TPACKETID packetnum)
  517. {
  518. return (mRecentlyReceivedReliablePackets.find(packetnum) != mRecentlyReceivedReliablePackets.end());
  519. }
  520. void LLCircuit::dumpResends()
  521. {
  522. circuit_data_map::iterator end = mCircuitData.end();
  523. for(circuit_data_map::iterator it = mCircuitData.begin(); it != end; ++it)
  524. {
  525. (*it).second->dumpResendCountAndReset();
  526. }
  527. }
  528. LLCircuitData* LLCircuit::findCircuit(const LLHost& host) const
  529. {
  530. // An optimization on finding the previously found circuit.
  531. if (mLastCircuit && (mLastCircuit->mHost == host))
  532. {
  533. return mLastCircuit;
  534. }
  535. circuit_data_map::const_iterator it = mCircuitData.find(host);
  536. if(it == mCircuitData.end())
  537. {
  538. return NULL;
  539. }
  540. mLastCircuit = it->second;
  541. return mLastCircuit;
  542. }
  543. BOOL LLCircuit::isCircuitAlive(const LLHost& host) const
  544. {
  545. LLCircuitData *cdp = findCircuit(host);
  546. if(cdp)
  547. {
  548. return cdp->mbAlive;
  549. }
  550. return FALSE;
  551. }
  552. void LLCircuitData::setTimeoutCallback(void (*callback_func)(const LLHost &host, void *user_data), void *user_data)
  553. {
  554. mTimeoutCallback = callback_func;
  555. mTimeoutUserData = user_data; 
  556. }
  557. void LLCircuitData::checkPacketInID(TPACKETID id, BOOL receive_resent)
  558. {
  559. // Done as floats so we don't have to worry about running out of room
  560. // with U32 getting poked into an S32.
  561. F32 delta = (F32)mHighestPacketID - (F32)id;
  562. if (delta > (0.5f*LL_MAX_OUT_PACKET_ID))
  563. {
  564. // We've almost definitely wrapped, reset the mLastPacketID to be low again.
  565. mHighestPacketID = id;
  566. }
  567. else if (delta < (-0.5f*LL_MAX_OUT_PACKET_ID))
  568. {
  569. // This is almost definitely an old packet coming in after a wrap, ignore it.
  570. }
  571. else
  572. {
  573. mHighestPacketID = llmax(mHighestPacketID, id);
  574. }
  575. // Have we received anything on this circuit yet?
  576. if (0 == mPacketsIn)
  577. {
  578. // Must be first packet from unclosed circuit.
  579. mPacketsIn++;
  580. setPacketInID((id + 1) % LL_MAX_OUT_PACKET_ID);
  581.         mLastPacketGap = 0;
  582.         mOutOfOrderRate.count(0);
  583. return;
  584. }
  585. mPacketsIn++;
  586. // now, check to see if we've got a gap
  587.     U32 gap = 0;
  588. if ((mPacketsInID == id))
  589. {
  590. // nope! bump and wrap the counter, then return
  591. mPacketsInID++;
  592. mPacketsInID = (mPacketsInID) % LL_MAX_OUT_PACKET_ID;
  593. }
  594. else if (id < mWrapID)
  595. {
  596. // id < mWrapID will happen if the first few packets are out of order. . . 
  597. // at that point we haven't marked anything "potentially lost" and 
  598. // the out-of-order packet will cause a full wrap marking all the IDs "potentially lost"
  599. // do nothing
  600. }
  601. else
  602. {
  603. // we have a gap!  if that id is in the map, remove it from the map, leave mCurrentCircuit->mPacketsInID
  604. // alone
  605. // otherwise, walk from mCurrentCircuit->mPacketsInID to id with wrapping, adding the values to the map
  606. // and setting mPacketsInID to id + 1 % LL_MAX_OUT_PACKET_ID
  607.         // babbage: all operands in expression are unsigned, so modular 
  608. // arithmetic will always find correct gap, regardless of wrap arounds.
  609. const U8 width = 24;
  610. gap = LLModularMath::subtract<width>(mPacketsInID, id);
  611. if (mPotentialLostPackets.find(id) != mPotentialLostPackets.end())
  612. {
  613. if(gMessageSystem->mVerboseLog)
  614. {
  615. std::ostringstream str;
  616. str << "MSG: <- " << mHost << "tRECOVERING LOST:t" << id;
  617. llinfos << str.str() << llendl;
  618. }
  619. // llinfos << "removing potential lost: " << id << llendl;
  620. mPotentialLostPackets.erase(id);
  621. }
  622. else if (!receive_resent) // don't freak out over out-of-order reliable resends
  623. {
  624. U64 time = LLMessageSystem::getMessageTimeUsecs();
  625. TPACKETID index = mPacketsInID;
  626. S32 gap_count = 0;
  627. if ((index < id) && ((id - index) < 16))
  628. {
  629. while (index != id)
  630. {
  631. if(gMessageSystem->mVerboseLog)
  632. {
  633. std::ostringstream str;
  634. str << "MSG: <- " << mHost << "tPACKET GAP:t"
  635. << index;
  636. llinfos << str.str() << llendl;
  637. }
  638. // llinfos << "adding potential lost: " << index << llendl;
  639. mPotentialLostPackets[index] = time;
  640. index++;
  641. index = index % LL_MAX_OUT_PACKET_ID;
  642. gap_count++;
  643. }
  644. }
  645. else
  646. {
  647. llinfos << "packet_out_of_order - got packet " << id << " expecting " << index << " from " << mHost << llendl;
  648. if(gMessageSystem->mVerboseLog)
  649. {
  650. std::ostringstream str;
  651. str << "MSG: <- " << mHost << "tPACKET GAP:t"
  652. << id << " expected " << index;
  653. llinfos << str.str() << llendl;
  654. }
  655. }
  656. mPacketsInID = id + 1;
  657. mPacketsInID = (mPacketsInID) % LL_MAX_OUT_PACKET_ID;
  658. if (gap_count > 128)
  659. {
  660. llwarns << "Packet loss gap filler running amok!" << llendl;
  661. }
  662. else if (gap_count > 16)
  663. {
  664. llwarns << "Sustaining large amounts of packet loss!" << llendl;
  665. }
  666. }
  667. }
  668.     mOutOfOrderRate.count(gap);
  669.     mLastPacketGap = gap;
  670. }
  671. void LLCircuit::updateWatchDogTimers(LLMessageSystem *msgsys)
  672. {
  673. F64 cur_time = LLMessageSystem::getMessageTimeSeconds();
  674. S32 count = mPingSet.size();
  675. S32 cur = 0;
  676. // Only process each circuit once at most, stop processing if no circuits
  677. while((cur < count) && !mPingSet.empty())
  678. {
  679. cur++;
  680. LLCircuit::ping_set_t::iterator psit = mPingSet.begin();
  681. LLCircuitData *cdp = *psit;
  682. if (!cdp->mbAlive)
  683. {
  684. // We suspect that this case should never happen, given how
  685. // the alive status is set.
  686. // Skip over dead circuits, just add the ping interval and push it to the back
  687. // Always remember to remove it from the set before changing the sorting
  688. // key (mNextPingSendTime)
  689. mPingSet.erase(psit);
  690. cdp->mNextPingSendTime = cur_time + mHeartbeatInterval;
  691. mPingSet.insert(cdp);
  692. continue;
  693. }
  694. else
  695. {
  696. // Check to see if this needs a ping
  697. if (cur_time < cdp->mNextPingSendTime)
  698. {
  699. // This circuit doesn't need a ping, break out because
  700. // we have a sorted list, thus no more circuits need pings
  701. break;
  702. }
  703. // Update watchdog timers
  704. if (cdp->updateWatchDogTimers(msgsys))
  705.             {
  706. // Randomize our pings a bit by doing some up to 5% early or late
  707. F64 dt = 0.95f*mHeartbeatInterval + ll_frand(0.1f*mHeartbeatInterval);
  708. // Remove it, and reinsert it with the new next ping time.
  709. // Always remove before changing the sorting key.
  710. mPingSet.erase(psit);
  711. cdp->mNextPingSendTime = cur_time + dt;
  712. mPingSet.insert(cdp);
  713.     
  714.     // Update our throttles
  715.     cdp->mThrottles.dynamicAdjust();
  716.     
  717.     // Update some stats, this is not terribly important
  718.     cdp->checkPeriodTime();
  719. }
  720. else
  721. {
  722. // This mPingSet.erase isn't necessary, because removing the circuit will
  723. // remove the ping set.
  724. //mPingSet.erase(psit);
  725. removeCircuitData(cdp->mHost);
  726. }
  727. }
  728. }
  729. }
  730. BOOL LLCircuitData::updateWatchDogTimers(LLMessageSystem *msgsys)
  731. {
  732. F64 cur_time = LLMessageSystem::getMessageTimeSeconds();
  733. mLastPingSendTime = cur_time;
  734. if (!checkCircuitTimeout())
  735. {
  736. // Pass this back to the calling LLCircuit, this circuit needs to be cleaned up.
  737. return FALSE;
  738. }
  739. // WARNING!
  740. // Duplicate suppression can FAIL if packets are delivered out of
  741. // order, although it's EXTREMELY unlikely.  It would require
  742. // that the ping get delivered out of order enough that the ACK
  743. // for the packet that it was out of order with was received BEFORE
  744. // the ping was sent.
  745. // Find the current oldest reliable packetID
  746. // This is to handle the case if we actually manage to wrap our
  747. // packet IDs - the oldest will actually have a higher packet ID
  748. // than the current.
  749. BOOL wrapped = FALSE;
  750. reliable_iter iter;
  751. iter = mUnackedPackets.upper_bound(getPacketOutID());
  752. if (iter == mUnackedPackets.end())
  753. {
  754. // Nothing AFTER this one, so we want the lowest packet ID
  755. // then.
  756. iter = mUnackedPackets.begin();
  757. wrapped = TRUE;
  758. }
  759. TPACKETID packet_id = 0;
  760. // Check against the "final" packets
  761. BOOL wrapped_final = FALSE;
  762. reliable_iter iter_final;
  763. iter_final = mFinalRetryPackets.upper_bound(getPacketOutID());
  764. if (iter_final == mFinalRetryPackets.end())
  765. {
  766. iter_final = mFinalRetryPackets.begin();
  767. wrapped_final = TRUE;
  768. }
  769. //llinfos << mHost << " - unacked count " << mUnackedPackets.size() << llendl;
  770. //llinfos << mHost << " - final count " << mFinalRetryPackets.size() << llendl;
  771. if (wrapped != wrapped_final)
  772. {
  773. // One of the "unacked" or "final" lists hasn't wrapped.  Whichever one
  774. // hasn't has the oldest packet.
  775. if (!wrapped)
  776. {
  777. // Hasn't wrapped, so the one on the
  778. // unacked packet list is older
  779. packet_id = iter->first;
  780. //llinfos << mHost << ": nowrapped unacked" << llendl;
  781. }
  782. else
  783. {
  784. packet_id = iter_final->first;
  785. //llinfos << mHost << ": nowrapped final" << llendl;
  786. }
  787. }
  788. else
  789. {
  790. // They both wrapped, we can just use the minimum of the two.
  791. if ((iter == mUnackedPackets.end()) && (iter_final == mFinalRetryPackets.end()))
  792. {
  793. // Wow!  No unacked packets at all!
  794. // Send the ID of the last packet we sent out.
  795. // This will flush all of the destination's
  796. // unacked packets, theoretically.
  797. //llinfos << mHost << ": No unacked!" << llendl;
  798. packet_id = getPacketOutID();
  799. }
  800. else
  801. {
  802. BOOL had_unacked = FALSE;
  803. if (iter != mUnackedPackets.end())
  804. {
  805. // Unacked list has the lowest so far
  806. packet_id = iter->first;
  807. had_unacked = TRUE;
  808. //llinfos << mHost << ": Unacked" << llendl;
  809. }
  810. if (iter_final != mFinalRetryPackets.end())
  811. {
  812. // Use the lowest of the unacked list and the final list
  813. if (had_unacked)
  814. {
  815. // Both had a packet, use the lowest.
  816. packet_id = llmin(packet_id, iter_final->first);
  817. //llinfos << mHost << ": Min of unacked/final" << llendl;
  818. }
  819. else
  820. {
  821. // Only the final had a packet, use it.
  822. packet_id = iter_final->first;
  823. //llinfos << mHost << ": Final!" << llendl;
  824. }
  825. }
  826. }
  827. }
  828. // Send off the another ping.
  829. pingTimerStart();
  830. msgsys->newMessageFast(_PREHASH_StartPingCheck);
  831. msgsys->nextBlock(_PREHASH_PingID);
  832. msgsys->addU8Fast(_PREHASH_PingID, nextPingID());
  833. msgsys->addU32Fast(_PREHASH_OldestUnacked, packet_id);
  834. msgsys->sendMessage(mHost);
  835. // Also do lost packet accounting.
  836. // Check to see if anything on our lost list is old enough to
  837. // be considered lost
  838. LLCircuitData::packet_time_map::iterator it;
  839. U64 timeout = (U64)(1000000.0*llmin(LL_MAX_LOST_TIMEOUT, getPingDelayAveraged() * LL_LOST_TIMEOUT_FACTOR));
  840. U64 mt_usec = LLMessageSystem::getMessageTimeUsecs();
  841. for (it = mPotentialLostPackets.begin(); it != mPotentialLostPackets.end(); )
  842. {
  843. U64 delta_t_usec = mt_usec - (*it).second;
  844. if (delta_t_usec > timeout)
  845. {
  846. // let's call this one a loss!
  847. mPacketsLost++;
  848. gMessageSystem->mDroppedPackets++;
  849. if(gMessageSystem->mVerboseLog)
  850. {
  851. std::ostringstream str;
  852. str << "MSG: <- " << mHost << "tLOST PACKET:t"
  853. << (*it).first;
  854. llinfos << str.str() << llendl;
  855. }
  856. mPotentialLostPackets.erase(it++);
  857. }
  858. else
  859. {
  860. ++it;
  861. }
  862. }
  863. return TRUE;
  864. }
  865. void LLCircuitData::clearDuplicateList(TPACKETID oldest_id)
  866. {
  867. // purge old data from the duplicate suppression queue
  868. // we want to KEEP all x where oldest_id <= x <= last incoming packet, and delete everything else.
  869. //llinfos << mHost << ": clearing before oldest " << oldest_id << llendl;
  870. //llinfos << "Recent list before: " << mRecentlyReceivedReliablePackets.size() << llendl;
  871. if (oldest_id < mHighestPacketID)
  872. {
  873. // Clean up everything with a packet ID less than oldest_id.
  874. packet_time_map::iterator pit_start;
  875. packet_time_map::iterator pit_end;
  876. pit_start = mRecentlyReceivedReliablePackets.begin();
  877. pit_end = mRecentlyReceivedReliablePackets.lower_bound(oldest_id);
  878. mRecentlyReceivedReliablePackets.erase(pit_start, pit_end);
  879. }
  880. // Do timeout checks on everything with an ID > mHighestPacketID.
  881. // This should be empty except for wrapping IDs.  Thus, this should be
  882. // highly rare.
  883. U64 mt_usec = LLMessageSystem::getMessageTimeUsecs();
  884. packet_time_map::iterator pit;
  885. for(pit = mRecentlyReceivedReliablePackets.upper_bound(mHighestPacketID);
  886. pit != mRecentlyReceivedReliablePackets.end(); )
  887. {
  888. // Validate that the packet ID seems far enough away
  889. if ((pit->first - mHighestPacketID) < 100)
  890. {
  891. llwarns << "Probably incorrectly timing out non-wrapped packets!" << llendl;
  892. }
  893. U64 delta_t_usec = mt_usec - (*pit).second;
  894. F64 delta_t_sec = delta_t_usec * SEC_PER_USEC;
  895. if (delta_t_sec > LL_DUPLICATE_SUPPRESSION_TIMEOUT)
  896. {
  897. // enough time has elapsed we're not likely to get a duplicate on this one
  898. llinfos << "Clearing " << pit->first << " from recent list" << llendl;
  899. mRecentlyReceivedReliablePackets.erase(pit++);
  900. }
  901. else
  902. {
  903. ++pit;
  904. }
  905. }
  906. //llinfos << "Recent list after: " << mRecentlyReceivedReliablePackets.size() << llendl;
  907. }
  908. BOOL LLCircuitData::checkCircuitTimeout()
  909. {
  910. F64 time_since_last_ping = LLMessageSystem::getMessageTimeSeconds() - mLastPingReceivedTime;
  911. // Nota Bene: This needs to be turned off if you are debugging multiple simulators
  912. if (time_since_last_ping > mHeartbeatTimeout)
  913. {
  914. llwarns << "LLCircuitData::checkCircuitTimeout for " << mHost << " last ping " << time_since_last_ping << " seconds ago." <<llendl;
  915. setAlive(FALSE);
  916. if (mTimeoutCallback)
  917. {
  918. llwarns << "LLCircuitData::checkCircuitTimeout for " << mHost << " calling callback." << llendl;
  919. mTimeoutCallback(mHost, mTimeoutUserData);
  920. }
  921. if (!isAlive())
  922. {
  923. // The callback didn't try and resurrect the circuit.  We should kill it.
  924. llwarns << "LLCircuitData::checkCircuitTimeout for " << mHost << " still dead, dropping." << llendl;
  925. return FALSE;
  926. }
  927. }
  928. return TRUE;
  929. }
  930. // Call this method when a reliable message comes in - this will
  931. // correctly place the packet in the correct list to be acked later.
  932. BOOL LLCircuitData::collectRAck(TPACKETID packet_num)
  933. {
  934. if (mAcks.empty())
  935. {
  936. // First extra ack, we need to add ourselves to the list of circuits that need to send acks
  937. gMessageSystem->mCircuitInfo.mSendAckMap[mHost] = this;
  938. }
  939. mAcks.push_back(packet_num);
  940. return TRUE;
  941. }
  942. // this method is called during the message system processAcks() to
  943. // send out any acks that did not get sent already.
  944. void LLCircuit::sendAcks()
  945. {
  946. LLCircuitData* cd;
  947. circuit_data_map::iterator end = mSendAckMap.end();
  948. for(circuit_data_map::iterator it = mSendAckMap.begin(); it != end; ++it)
  949. {
  950. cd = (*it).second;
  951. S32 count = (S32)cd->mAcks.size();
  952. if(count > 0)
  953. {
  954. // send the packet acks
  955. S32 acks_this_packet = 0;
  956. for(S32 i = 0; i < count; ++i)
  957. {
  958. if(acks_this_packet == 0)
  959. {
  960. gMessageSystem->newMessageFast(_PREHASH_PacketAck);
  961. }
  962. gMessageSystem->nextBlockFast(_PREHASH_Packets);
  963. gMessageSystem->addU32Fast(_PREHASH_ID, cd->mAcks[i]);
  964. ++acks_this_packet;
  965. if(acks_this_packet > 250)
  966. {
  967. gMessageSystem->sendMessage(cd->mHost);
  968. acks_this_packet = 0;
  969. }
  970. }
  971. if(acks_this_packet > 0)
  972. {
  973. gMessageSystem->sendMessage(cd->mHost);
  974. }
  975. if(gMessageSystem->mVerboseLog)
  976. {
  977. std::ostringstream str;
  978. str << "MSG: -> " << cd->mHost << "tPACKET ACKS:t";
  979. std::ostream_iterator<TPACKETID> append(str, " ");
  980. std::copy(cd->mAcks.begin(), cd->mAcks.end(), append);
  981. llinfos << str.str() << llendl;
  982. }
  983. // empty out the acks list
  984. cd->mAcks.clear();
  985. }
  986. }
  987. // All acks have been sent, clear the map
  988. mSendAckMap.clear();
  989. }
  990. std::ostream& operator<<(std::ostream& s, LLCircuitData& circuit)
  991. {
  992. F32 age = circuit.mExistenceTimer.getElapsedTimeF32();
  993. using namespace std;
  994. s << "Circuit " << circuit.mHost << " ";
  995. s << circuit.mRemoteID << " ";
  996. s << (circuit.mbAlive ? "Alive" : "Not Alive") << " ";
  997. s << (circuit.mbAllowTimeout ? "Timeout Allowed" : "Timeout Not Allowed");
  998. s << endl;
  999. s << " Packets Lost: " << circuit.mPacketsLost;
  1000. s << " Measured Ping: " << circuit.mPingDelay;
  1001. s << " Averaged Ping: " << circuit.mPingDelayAveraged;
  1002. s << endl;
  1003. s << "Global In/Out " << S32(age) << " sec";
  1004. s << " KBytes: " << circuit.mBytesIn / 1024 << "/" << circuit.mBytesOut / 1024;
  1005. s << " Kbps: ";
  1006. s << S32(circuit.mBytesIn * 8.f / circuit.mExistenceTimer.getElapsedTimeF32() / 1024.f);
  1007. s << "/";
  1008. s << S32(circuit.mBytesOut * 8.f / circuit.mExistenceTimer.getElapsedTimeF32() / 1024.f);
  1009. s << " Packets: " << circuit.mPacketsIn << "/" << circuit.mPacketsOut;
  1010. s << endl;
  1011. s << "Recent In/Out   " << S32(circuit.mLastPeriodLength) << " sec";
  1012. s << " KBytes: ";
  1013. s << circuit.mBytesInLastPeriod / 1024;
  1014. s << "/";
  1015. s << circuit.mBytesOutLastPeriod / 1024;
  1016. s << " Kbps: ";
  1017. s << S32(circuit.mBytesInLastPeriod * 8.f / circuit.mLastPeriodLength / 1024.f);
  1018. s << "/";
  1019. s << S32(circuit.mBytesOutLastPeriod * 8.f / circuit.mLastPeriodLength / 1024.f);
  1020. s << " Peak kbps: ";
  1021. s << S32(circuit.mPeakBPSIn / 1024.f);
  1022. s << "/";
  1023. s << S32(circuit.mPeakBPSOut / 1024.f);
  1024. s << endl;
  1025. return s;
  1026. }
  1027. void LLCircuitData::getInfo(LLSD& info) const
  1028. {
  1029. info["Host"] = mHost.getIPandPort();
  1030. info["Alive"] = mbAlive;
  1031. info["Age"] = mExistenceTimer.getElapsedTimeF32();
  1032. }
  1033. void LLCircuitData::dumpResendCountAndReset()
  1034. {
  1035. if (mCurrentResendCount)
  1036. {
  1037. llinfos << "Circuit: " << mHost << " resent " << mCurrentResendCount << " packets" << llendl;
  1038. mCurrentResendCount = 0;
  1039. }
  1040. }
  1041. std::ostream& operator<<(std::ostream& s, LLCircuit &circuit)
  1042. {
  1043. s << "Circuit Info:" << std::endl;
  1044. LLCircuit::circuit_data_map::iterator end = circuit.mCircuitData.end();
  1045. LLCircuit::circuit_data_map::iterator it;
  1046. for(it = circuit.mCircuitData.begin(); it != end; ++it)
  1047. {
  1048. s << *((*it).second) << std::endl;
  1049. }
  1050. return s;
  1051. }
  1052. void LLCircuit::getInfo(LLSD& info) const
  1053. {
  1054. LLCircuit::circuit_data_map::const_iterator end = mCircuitData.end();
  1055. LLCircuit::circuit_data_map::const_iterator it;
  1056. LLSD circuit_info;
  1057. for(it = mCircuitData.begin(); it != end; ++it)
  1058. {
  1059. (*it).second->getInfo(circuit_info);
  1060. info["Circuits"].append(circuit_info);
  1061. }
  1062. }
  1063. void LLCircuit::getCircuitRange(
  1064. const LLHost& key,
  1065. LLCircuit::circuit_data_map::iterator& first,
  1066. LLCircuit::circuit_data_map::iterator& end)
  1067. {
  1068. end = mCircuitData.end();
  1069. first = mCircuitData.upper_bound(key);
  1070. }
  1071. TPACKETID LLCircuitData::nextPacketOutID()
  1072. {
  1073. mPacketsOut++;
  1074. TPACKETID id; 
  1075. id = (mPacketsOutID + 1) % LL_MAX_OUT_PACKET_ID;
  1076. if (id < mPacketsOutID)
  1077. {
  1078. // we just wrapped on a circuit, reset the wrap ID to zero
  1079. mWrapID = 0;
  1080. }
  1081. mPacketsOutID = id;
  1082. return id;
  1083. }
  1084. void LLCircuitData::setPacketInID(TPACKETID id)
  1085. {
  1086. id = id % LL_MAX_OUT_PACKET_ID;
  1087. mPacketsInID = id;
  1088. mRecentlyReceivedReliablePackets.clear();
  1089. mWrapID = id;
  1090. }
  1091. void LLCircuitData::pingTimerStop(const U8 ping_id)
  1092. {
  1093. F64 mt_secs = LLMessageSystem::getMessageTimeSeconds();
  1094. // Nota Bene: no averaging of ping times until we get a feel for how this works
  1095. F64 time = mt_secs - mPingTime;
  1096. if (time == 0.0)
  1097. {
  1098. // Ack, we got our ping response on the same frame! Sigh, let's get a real time otherwise
  1099. // all of our ping calculations will be skewed.
  1100. mt_secs = LLMessageSystem::getMessageTimeSeconds(TRUE);
  1101. }
  1102. mLastPingReceivedTime = mt_secs;
  1103. // If ping is longer than 1 second, we'll get sequence deltas in the ping.
  1104. // Approximate by assuming each ping counts for 1 second (slightly low, probably)
  1105. S32 delta_ping = (S32)mLastPingID - (S32) ping_id;
  1106. if (delta_ping < 0)
  1107. {
  1108. delta_ping += 256;
  1109. }
  1110. U32 msec = (U32) ((delta_ping*mHeartbeatInterval  + time) * 1000.f);
  1111. setPingDelay(msec);
  1112. mPingsInTransit = delta_ping;
  1113. if (mBlocked && (mPingsInTransit <= PING_RELEASE_BLOCK))
  1114. {
  1115. mBlocked = FALSE;
  1116. }
  1117. }
  1118. void LLCircuitData::pingTimerStart()
  1119. {
  1120. mPingTime = LLMessageSystem::getMessageTimeSeconds();
  1121. mPingsInTransit++;
  1122. if (!mBlocked && (mPingsInTransit > PING_START_BLOCK))
  1123. {
  1124. mBlocked = TRUE;
  1125. }
  1126. }
  1127. U32 LLCircuitData::getPacketsIn() const
  1128. {
  1129. return mPacketsIn;
  1130. }
  1131. S32 LLCircuitData::getBytesIn() const
  1132. {
  1133. return mBytesIn;
  1134. }
  1135. S32 LLCircuitData::getBytesOut() const
  1136. {
  1137. return mBytesOut;
  1138. }
  1139. U32 LLCircuitData::getPacketsOut() const
  1140. {
  1141. return mPacketsOut;
  1142. }
  1143. TPACKETID LLCircuitData::getPacketOutID() const
  1144. {
  1145. return mPacketsOutID;
  1146. }
  1147. U32 LLCircuitData::getPacketsLost() const
  1148. {
  1149. return mPacketsLost;
  1150. }
  1151. BOOL LLCircuitData::isAlive() const
  1152. {
  1153. return mbAlive;
  1154. }
  1155. BOOL LLCircuitData::isBlocked() const
  1156. {
  1157. return mBlocked;
  1158. }
  1159. BOOL LLCircuitData::getAllowTimeout() const
  1160. {
  1161. return mbAllowTimeout;
  1162. }
  1163. U32 LLCircuitData::getPingDelay() const
  1164. {
  1165. return mPingDelay;
  1166. }
  1167. F32 LLCircuitData::getPingInTransitTime()
  1168. {
  1169. // This may be inaccurate in the case of a circuit that was "dead" and then revived,
  1170. // but only until the first round trip ping is sent - djs
  1171. F32 time_since_ping_was_sent = 0;
  1172. if (mPingsInTransit)
  1173. {
  1174. time_since_ping_was_sent =  (F32)((mPingsInTransit*mHeartbeatInterval - 1) 
  1175. + (LLMessageSystem::getMessageTimeSeconds() - mPingTime))*1000.f;
  1176. }
  1177. return time_since_ping_was_sent;
  1178. }
  1179. void LLCircuitData::setPingDelay(U32 ping)
  1180. {
  1181. mPingDelay = ping;
  1182. mPingDelayAveraged = llmax((F32)ping, getPingDelayAveraged());
  1183. mPingDelayAveraged = ((1.f - LL_AVERAGED_PING_ALPHA) * mPingDelayAveraged) 
  1184.   + (LL_AVERAGED_PING_ALPHA * (F32) ping);
  1185. mPingDelayAveraged = llclamp(mPingDelayAveraged, 
  1186.  LL_AVERAGED_PING_MIN,
  1187.  LL_AVERAGED_PING_MAX);
  1188. }
  1189. F32 LLCircuitData::getPingDelayAveraged()
  1190. {
  1191. return llmin(llmax(getPingInTransitTime(), mPingDelayAveraged), LL_AVERAGED_PING_MAX);
  1192. }
  1193. BOOL LLCircuitData::getTrusted() const
  1194. {
  1195. return mTrusted;
  1196. }
  1197. void LLCircuitData::setTrusted(BOOL t)
  1198. {
  1199. mTrusted = t;
  1200. }
  1201. F32 LLCircuitData::getAgeInSeconds() const
  1202. {
  1203. return mExistenceTimer.getElapsedTimeF32();
  1204. }