PageRenderTime 19ms CodeModel.GetById 3ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llmessage/llcircuit.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 350 lines | 192 code | 76 blank | 82 comment | 4 complexity | 6f121f39bc1ff5102b7d9c012ba03f1d MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llcircuit.h
  3. * @brief Provides a method for tracking network circuit information
  4. * for the UDP message system
  5. *
  6. * $LicenseInfo:firstyear=2001&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. #ifndef LL_LLCIRCUIT_H
  28. #define LL_LLCIRCUIT_H
  29. #include <map>
  30. #include <vector>
  31. #include "llerror.h"
  32. #include "lltimer.h"
  33. #include "timing.h"
  34. #include "net.h"
  35. #include "llhost.h"
  36. #include "llpacketack.h"
  37. #include "lluuid.h"
  38. #include "llthrottle.h"
  39. #include "llstat.h"
  40. //
  41. // Constants
  42. //
  43. const F32 LL_AVERAGED_PING_ALPHA = 0.2f; // relaxation constant on ping running average
  44. const F32 LL_AVERAGED_PING_MAX = 2000; // msec
  45. const F32 LL_AVERAGED_PING_MIN = 100; // msec // IW: increased to avoid retransmits when a process is slow
  46. const U32 INITIAL_PING_VALUE_MSEC = 1000; // initial value for the ping delay, or for ping delay for an unknown circuit
  47. const TPACKETID LL_MAX_OUT_PACKET_ID = 0x01000000;
  48. // 0 - flags
  49. // [1,4] - packetid
  50. // 5 - data offset (after message name)
  51. const U8 LL_PACKET_ID_SIZE = 6;
  52. const S32 LL_MAX_RESENT_PACKETS_PER_FRAME = 100;
  53. const S32 LL_MAX_ACKED_PACKETS_PER_FRAME = 200;
  54. //
  55. // Prototypes and Predefines
  56. //
  57. class LLMessageSystem;
  58. class LLEncodedDatagramService;
  59. class LLSD;
  60. //
  61. // Classes
  62. //
  63. class LLCircuitData
  64. {
  65. public:
  66. LLCircuitData(const LLHost &host, TPACKETID in_id,
  67. const F32 circuit_heartbeat_interval, const F32 circuit_timeout);
  68. ~LLCircuitData();
  69. S32 resendUnackedPackets(const F64 now);
  70. void clearDuplicateList(TPACKETID oldest_id);
  71. void dumpResendCountAndReset(); // Used for tracking how many resends are being done on a circuit.
  72. // Public because stupid message system callbacks uses it.
  73. void pingTimerStart();
  74. void pingTimerStop(const U8 ping_id);
  75. void ackReliablePacket(TPACKETID packet_num);
  76. // remote computer information
  77. const LLUUID& getRemoteID() const { return mRemoteID; }
  78. const LLUUID& getRemoteSessionID() const { return mRemoteSessionID; }
  79. void setRemoteID(const LLUUID& id) { mRemoteID = id; }
  80. void setRemoteSessionID(const LLUUID& id) { mRemoteSessionID = id; }
  81. void setTrusted(BOOL t);
  82. // The local end point ID is used when establishing a trusted circuit.
  83. // no matching set function for getLocalEndPointID()
  84. // mLocalEndPointID should only ever be setup in the LLCircuitData constructor
  85. const LLUUID& getLocalEndPointID() const { return mLocalEndPointID; }
  86. U32 getPingDelay() const;
  87. S32 getPingsInTransit() const { return mPingsInTransit; }
  88. // ACCESSORS
  89. BOOL isAlive() const;
  90. BOOL isBlocked() const;
  91. BOOL getAllowTimeout() const;
  92. F32 getPingDelayAveraged();
  93. F32 getPingInTransitTime();
  94. U32 getPacketsIn() const;
  95. S32 getBytesIn() const;
  96. S32 getBytesOut() const;
  97. U32 getPacketsOut() const;
  98. U32 getPacketsLost() const;
  99. TPACKETID getPacketOutID() const;
  100. BOOL getTrusted() const;
  101. F32 getAgeInSeconds() const;
  102. S32 getUnackedPacketCount() const { return mUnackedPacketCount; }
  103. S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; }
  104. F64 getNextPingSendTime() const { return mNextPingSendTime; }
  105. F32 getOutOfOrderRate(LLStatAccum::TimeScale scale = LLStatAccum::SCALE_MINUTE)
  106. { return mOutOfOrderRate.meanValue(scale); }
  107. U32 getLastPacketGap() const { return mLastPacketGap; }
  108. LLHost getHost() const { return mHost; }
  109. F64 getLastPacketInTime() const { return mLastPacketInTime; }
  110. LLThrottleGroup &getThrottleGroup() { return mThrottles; }
  111. class less
  112. {
  113. public:
  114. bool operator()(const LLCircuitData* lhs, const LLCircuitData* rhs) const
  115. {
  116. if (lhs->getNextPingSendTime() < rhs->getNextPingSendTime())
  117. {
  118. return true;
  119. }
  120. else if (lhs->getNextPingSendTime() > rhs->getNextPingSendTime())
  121. {
  122. return false;
  123. }
  124. else return lhs > rhs;
  125. }
  126. };
  127. //
  128. // Debugging stuff (not necessary for operation)
  129. //
  130. void checkPeriodTime(); // Reset per-period counters if necessary.
  131. friend std::ostream& operator<<(std::ostream& s, LLCircuitData &circuit);
  132. void getInfo(LLSD& info) const;
  133. friend class LLCircuit;
  134. friend class LLMessageSystem;
  135. friend class LLEncodedDatagramService;
  136. friend void crash_on_spaceserver_timeout (const LLHost &host, void *); // HACK, so it has access to setAlive() so it can send a final shutdown message.
  137. protected:
  138. TPACKETID nextPacketOutID();
  139. void setPacketInID(TPACKETID id);
  140. void checkPacketInID(TPACKETID id, BOOL receive_resent);
  141. void setPingDelay(U32 ping);
  142. BOOL checkCircuitTimeout(); // Return FALSE if the circuit is dead and should be cleaned up
  143. void addBytesIn(S32 bytes);
  144. void addBytesOut(S32 bytes);
  145. U8 nextPingID() { mLastPingID++; return mLastPingID; }
  146. BOOL updateWatchDogTimers(LLMessageSystem *msgsys); // Return FALSE if the circuit is dead and should be cleaned up
  147. void addReliablePacket(S32 mSocket, U8 *buf_ptr, S32 buf_len, LLReliablePacketParams *params);
  148. BOOL isDuplicateResend(TPACKETID packetnum);
  149. // Call this method when a reliable message comes in - this will
  150. // correctly place the packet in the correct list to be acked
  151. // later. RAack = requested ack
  152. BOOL collectRAck(TPACKETID packet_num);
  153. void setTimeoutCallback(void (*callback_func)(const LLHost &host, void *user_data), void *user_data);
  154. void setAlive(BOOL b_alive);
  155. void setAllowTimeout(BOOL allow);
  156. protected:
  157. // Identification for this circuit.
  158. LLHost mHost;
  159. LLUUID mRemoteID;
  160. LLUUID mRemoteSessionID;
  161. LLThrottleGroup mThrottles;
  162. TPACKETID mWrapID;
  163. // Current packet IDs of incoming/outgoing packets
  164. // Used for packet sequencing/packet loss detection.
  165. TPACKETID mPacketsOutID;
  166. TPACKETID mPacketsInID;
  167. TPACKETID mHighestPacketID;
  168. // Callback and data to run in the case of a circuit timeout.
  169. // Used primarily to try and reconnect to servers if they crash/die.
  170. void (*mTimeoutCallback)(const LLHost &host, void *user_data);
  171. void *mTimeoutUserData;
  172. BOOL mTrusted; // Is this circuit trusted?
  173. BOOL mbAllowTimeout; // Machines can "pause" circuits, forcing them not to be dropped
  174. BOOL mbAlive; // Indicates whether a circuit is "alive", i.e. responded to pings
  175. BOOL mBlocked; // Blocked is true if the circuit is hosed, i.e. far behind on pings
  176. // Not sure what the difference between this and mLastPingSendTime is
  177. F64 mPingTime; // Time at which a ping was sent.
  178. F64 mLastPingSendTime; // Time we last sent a ping
  179. F64 mLastPingReceivedTime; // Time we last received a ping
  180. F64 mNextPingSendTime; // Time to try and send the next ping
  181. S32 mPingsInTransit; // Number of pings in transit
  182. U8 mLastPingID; // ID of the last ping that we sent out
  183. // Used for determining the resend time for reliable resends.
  184. U32 mPingDelay; // raw ping delay
  185. F32 mPingDelayAveraged; // averaged ping delay (fast attack/slow decay)
  186. typedef std::map<TPACKETID, U64> packet_time_map;
  187. packet_time_map mPotentialLostPackets;
  188. packet_time_map mRecentlyReceivedReliablePackets;
  189. std::vector<TPACKETID> mAcks;
  190. typedef std::map<TPACKETID, LLReliablePacket *> reliable_map;
  191. typedef reliable_map::iterator reliable_iter;
  192. reliable_map mUnackedPackets;
  193. reliable_map mFinalRetryPackets;
  194. S32 mUnackedPacketCount;
  195. S32 mUnackedPacketBytes;
  196. F64 mLastPacketInTime; // Time of last packet arrival
  197. LLUUID mLocalEndPointID;
  198. //
  199. // These variables are being used for statistical and debugging purpose ONLY,
  200. // as far as I can tell.
  201. //
  202. U32 mPacketsOut;
  203. U32 mPacketsIn;
  204. S32 mPacketsLost;
  205. S32 mBytesIn;
  206. S32 mBytesOut;
  207. F32 mLastPeriodLength; // seconds
  208. S32 mBytesInLastPeriod;
  209. S32 mBytesOutLastPeriod;
  210. S32 mBytesInThisPeriod;
  211. S32 mBytesOutThisPeriod;
  212. F32 mPeakBPSIn; // bits per second, max of all period bps
  213. F32 mPeakBPSOut; // bits per second, max of all period bps
  214. F64 mPeriodTime;
  215. LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers
  216. S32 mCurrentResendCount; // Number of resent packets since last spam
  217. LLStatRate mOutOfOrderRate; // Rate of out of order packets coming in.
  218. U32 mLastPacketGap; // Gap in sequence number of last packet.
  219. const F32 mHeartbeatInterval;
  220. const F32 mHeartbeatTimeout;
  221. };
  222. // Actually a singleton class -- the global messagesystem
  223. // has a single LLCircuit member.
  224. class LLCircuit
  225. {
  226. public:
  227. // CREATORS
  228. LLCircuit(const F32 circuit_heartbeat_interval, const F32 circuit_timeout);
  229. ~LLCircuit();
  230. // ACCESSORS
  231. LLCircuitData* findCircuit(const LLHost& host) const;
  232. BOOL isCircuitAlive(const LLHost& host) const;
  233. // MANIPULATORS
  234. LLCircuitData *addCircuitData(const LLHost &host, TPACKETID in_id);
  235. void removeCircuitData(const LLHost &host);
  236. void updateWatchDogTimers(LLMessageSystem *msgsys);
  237. void resendUnackedPackets(S32& unacked_list_length, S32& unacked_list_size);
  238. // this method is called during the message system processAcks()
  239. // to send out any acks that did not get sent already.
  240. void sendAcks();
  241. friend std::ostream& operator<<(std::ostream& s, LLCircuit &circuit);
  242. void getInfo(LLSD& info) const;
  243. void dumpResends();
  244. typedef std::map<LLHost, LLCircuitData*> circuit_data_map;
  245. /**
  246. * @brief This method gets an iterator range starting after key in
  247. * the circuit data map.
  248. *
  249. * @param key The the host before first.
  250. * @param first[out] The first matching value after key. This
  251. * value will equal end if there are no entries.
  252. * @param end[out] The end of the iteration sequence.
  253. */
  254. void getCircuitRange(
  255. const LLHost& key,
  256. circuit_data_map::iterator& first,
  257. circuit_data_map::iterator& end);
  258. // Lists that optimize how many circuits we need to traverse a frame
  259. // HACK - this should become protected eventually, but stupid !@$@# message system/circuit classes are jumbling things up.
  260. circuit_data_map mUnackedCircuitMap; // Map of circuits with unacked data
  261. circuit_data_map mSendAckMap; // Map of circuits which need to send acks
  262. protected:
  263. circuit_data_map mCircuitData;
  264. typedef std::set<LLCircuitData *, LLCircuitData::less> ping_set_t; // Circuits sorted by next ping time
  265. ping_set_t mPingSet;
  266. // This variable points to the last circuit data we found to
  267. // optimize the many, many times we call findCircuit. This may be
  268. // set in otherwise const methods, so it is declared mutable.
  269. mutable LLCircuitData* mLastCircuit;
  270. private:
  271. const F32 mHeartbeatInterval;
  272. const F32 mHeartbeatTimeout;
  273. };
  274. #endif