llcircuit.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:11k
- /**
- * @file llcircuit.h
- * @brief Provides a method for tracking network circuit information
- * for the UDP message system
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #ifndef LL_LLCIRCUIT_H
- #define LL_LLCIRCUIT_H
- #include <map>
- #include <vector>
- #include "llerror.h"
- #include "lltimer.h"
- #include "timing.h"
- #include "net.h"
- #include "llhost.h"
- #include "llpacketack.h"
- #include "lluuid.h"
- #include "llthrottle.h"
- #include "llstat.h"
- //
- // Constants
- //
- const F32 LL_AVERAGED_PING_ALPHA = 0.2f; // relaxation constant on ping running average
- const F32 LL_AVERAGED_PING_MAX = 2000; // msec
- const F32 LL_AVERAGED_PING_MIN = 100; // msec // IW: increased to avoid retransmits when a process is slow
- const U32 INITIAL_PING_VALUE_MSEC = 1000; // initial value for the ping delay, or for ping delay for an unknown circuit
- const TPACKETID LL_MAX_OUT_PACKET_ID = 0x01000000;
- // 0 - flags
- // [1,4] - packetid
- // 5 - data offset (after message name)
- const U8 LL_PACKET_ID_SIZE = 6;
- const S32 LL_MAX_RESENT_PACKETS_PER_FRAME = 100;
- const S32 LL_MAX_ACKED_PACKETS_PER_FRAME = 200;
- //
- // Prototypes and Predefines
- //
- class LLMessageSystem;
- class LLEncodedDatagramService;
- class LLSD;
- //
- // Classes
- //
- class LLCircuitData
- {
- public:
- LLCircuitData(const LLHost &host, TPACKETID in_id,
- const F32 circuit_heartbeat_interval, const F32 circuit_timeout);
- ~LLCircuitData();
- S32 resendUnackedPackets(const F64 now);
- void clearDuplicateList(TPACKETID oldest_id);
- void dumpResendCountAndReset(); // Used for tracking how many resends are being done on a circuit.
- // Public because stupid message system callbacks uses it.
- void pingTimerStart();
- void pingTimerStop(const U8 ping_id);
- void ackReliablePacket(TPACKETID packet_num);
- // remote computer information
- const LLUUID& getRemoteID() const { return mRemoteID; }
- const LLUUID& getRemoteSessionID() const { return mRemoteSessionID; }
- void setRemoteID(const LLUUID& id) { mRemoteID = id; }
- void setRemoteSessionID(const LLUUID& id) { mRemoteSessionID = id; }
- void setTrusted(BOOL t);
- // The local end point ID is used when establishing a trusted circuit.
- // no matching set function for getLocalEndPointID()
- // mLocalEndPointID should only ever be setup in the LLCircuitData constructor
- const LLUUID& getLocalEndPointID() const { return mLocalEndPointID; }
- U32 getPingDelay() const;
- S32 getPingsInTransit() const { return mPingsInTransit; }
- // ACCESSORS
- BOOL isAlive() const;
- BOOL isBlocked() const;
- BOOL getAllowTimeout() const;
- F32 getPingDelayAveraged();
- F32 getPingInTransitTime();
- U32 getPacketsIn() const;
- S32 getBytesIn() const;
- S32 getBytesOut() const;
- U32 getPacketsOut() const;
- U32 getPacketsLost() const;
- TPACKETID getPacketOutID() const;
- BOOL getTrusted() const;
- F32 getAgeInSeconds() const;
- S32 getUnackedPacketCount() const { return mUnackedPacketCount; }
- S32 getUnackedPacketBytes() const { return mUnackedPacketBytes; }
- F64 getNextPingSendTime() const { return mNextPingSendTime; }
- F32 getOutOfOrderRate(LLStatAccum::TimeScale scale = LLStatAccum::SCALE_MINUTE)
- { return mOutOfOrderRate.meanValue(scale); }
- U32 getLastPacketGap() const { return mLastPacketGap; }
- LLHost getHost() const { return mHost; }
- LLThrottleGroup &getThrottleGroup() { return mThrottles; }
- class less
- {
- public:
- bool operator()(const LLCircuitData* lhs, const LLCircuitData* rhs) const
- {
- if (lhs->getNextPingSendTime() < rhs->getNextPingSendTime())
- {
- return true;
- }
- else if (lhs->getNextPingSendTime() > rhs->getNextPingSendTime())
- {
- return false;
- }
- else return lhs > rhs;
- }
- };
- //
- // Debugging stuff (not necessary for operation)
- //
- void checkPeriodTime(); // Reset per-period counters if necessary.
- friend std::ostream& operator<<(std::ostream& s, LLCircuitData &circuit);
- void getInfo(LLSD& info) const;
- friend class LLCircuit;
- friend class LLMessageSystem;
- friend class LLEncodedDatagramService;
- 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.
- protected:
- TPACKETID nextPacketOutID();
- void setPacketInID(TPACKETID id);
- void checkPacketInID(TPACKETID id, BOOL receive_resent);
- void setPingDelay(U32 ping);
- BOOL checkCircuitTimeout(); // Return FALSE if the circuit is dead and should be cleaned up
- void addBytesIn(S32 bytes);
- void addBytesOut(S32 bytes);
- U8 nextPingID() { mLastPingID++; return mLastPingID; }
- BOOL updateWatchDogTimers(LLMessageSystem *msgsys); // Return FALSE if the circuit is dead and should be cleaned up
- void addReliablePacket(S32 mSocket, U8 *buf_ptr, S32 buf_len, LLReliablePacketParams *params);
- BOOL isDuplicateResend(TPACKETID packetnum);
- // Call this method when a reliable message comes in - this will
- // correctly place the packet in the correct list to be acked
- // later. RAack = requested ack
- BOOL collectRAck(TPACKETID packet_num);
- void setTimeoutCallback(void (*callback_func)(const LLHost &host, void *user_data), void *user_data);
- void setAlive(BOOL b_alive);
- void setAllowTimeout(BOOL allow);
- protected:
- // Identification for this circuit.
- LLHost mHost;
- LLUUID mRemoteID;
- LLUUID mRemoteSessionID;
- LLThrottleGroup mThrottles;
- TPACKETID mWrapID;
- // Current packet IDs of incoming/outgoing packets
- // Used for packet sequencing/packet loss detection.
- TPACKETID mPacketsOutID;
- TPACKETID mPacketsInID;
- TPACKETID mHighestPacketID;
- // Callback and data to run in the case of a circuit timeout.
- // Used primarily to try and reconnect to servers if they crash/die.
- void (*mTimeoutCallback)(const LLHost &host, void *user_data);
- void *mTimeoutUserData;
- BOOL mTrusted; // Is this circuit trusted?
- BOOL mbAllowTimeout; // Machines can "pause" circuits, forcing them not to be dropped
- BOOL mbAlive; // Indicates whether a circuit is "alive", i.e. responded to pings
- BOOL mBlocked; // Blocked is true if the circuit is hosed, i.e. far behind on pings
- // Not sure what the difference between this and mLastPingSendTime is
- F64 mPingTime; // Time at which a ping was sent.
- F64 mLastPingSendTime; // Time we last sent a ping
- F64 mLastPingReceivedTime; // Time we last received a ping
- F64 mNextPingSendTime; // Time to try and send the next ping
- S32 mPingsInTransit; // Number of pings in transit
- U8 mLastPingID; // ID of the last ping that we sent out
- // Used for determining the resend time for reliable resends.
- U32 mPingDelay; // raw ping delay
- F32 mPingDelayAveraged; // averaged ping delay (fast attack/slow decay)
- typedef std::map<TPACKETID, U64> packet_time_map;
- packet_time_map mPotentialLostPackets;
- packet_time_map mRecentlyReceivedReliablePackets;
- std::vector<TPACKETID> mAcks;
- typedef std::map<TPACKETID, LLReliablePacket *> reliable_map;
- typedef reliable_map::iterator reliable_iter;
- reliable_map mUnackedPackets;
- reliable_map mFinalRetryPackets;
- S32 mUnackedPacketCount;
- S32 mUnackedPacketBytes;
- LLUUID mLocalEndPointID;
- //
- // These variables are being used for statistical and debugging purpose ONLY,
- // as far as I can tell.
- //
- U32 mPacketsOut;
- U32 mPacketsIn;
- S32 mPacketsLost;
- S32 mBytesIn;
- S32 mBytesOut;
- F32 mLastPeriodLength; // seconds
- S32 mBytesInLastPeriod;
- S32 mBytesOutLastPeriod;
- S32 mBytesInThisPeriod;
- S32 mBytesOutThisPeriod;
- F32 mPeakBPSIn; // bits per second, max of all period bps
- F32 mPeakBPSOut; // bits per second, max of all period bps
- F64 mPeriodTime;
- LLTimer mExistenceTimer; // initialized when circuit created, used to track bandwidth numbers
- S32 mCurrentResendCount; // Number of resent packets since last spam
- LLStatRate mOutOfOrderRate; // Rate of out of order packets coming in.
- U32 mLastPacketGap; // Gap in sequence number of last packet.
- const F32 mHeartbeatInterval;
- const F32 mHeartbeatTimeout;
- };
- // Actually a singleton class -- the global messagesystem
- // has a single LLCircuit member.
- class LLCircuit
- {
- public:
- // CREATORS
- LLCircuit(const F32 circuit_heartbeat_interval, const F32 circuit_timeout);
- ~LLCircuit();
- // ACCESSORS
- LLCircuitData* findCircuit(const LLHost& host) const;
- BOOL isCircuitAlive(const LLHost& host) const;
-
- // MANIPULATORS
- LLCircuitData *addCircuitData(const LLHost &host, TPACKETID in_id);
- void removeCircuitData(const LLHost &host);
- void updateWatchDogTimers(LLMessageSystem *msgsys);
- void resendUnackedPackets(S32& unacked_list_length, S32& unacked_list_size);
- // this method is called during the message system processAcks()
- // to send out any acks that did not get sent already.
- void sendAcks();
- friend std::ostream& operator<<(std::ostream& s, LLCircuit &circuit);
- void getInfo(LLSD& info) const;
- void dumpResends();
- typedef std::map<LLHost, LLCircuitData*> circuit_data_map;
- /**
- * @brief This method gets an iterator range starting after key in
- * the circuit data map.
- *
- * @param key The the host before first.
- * @param first[out] The first matching value after key. This
- * value will equal end if there are no entries.
- * @param end[out] The end of the iteration sequence.
- */
- void getCircuitRange(
- const LLHost& key,
- circuit_data_map::iterator& first,
- circuit_data_map::iterator& end);
- // Lists that optimize how many circuits we need to traverse a frame
- // HACK - this should become protected eventually, but stupid !@$@# message system/circuit classes are jumbling things up.
- circuit_data_map mUnackedCircuitMap; // Map of circuits with unacked data
- circuit_data_map mSendAckMap; // Map of circuits which need to send acks
- protected:
- circuit_data_map mCircuitData;
- typedef std::set<LLCircuitData *, LLCircuitData::less> ping_set_t; // Circuits sorted by next ping time
- ping_set_t mPingSet;
- // This variable points to the last circuit data we found to
- // optimize the many, many times we call findCircuit. This may be
- // set in otherwise const methods, so it is declared mutable.
- mutable LLCircuitData* mLastCircuit;
- private:
- const F32 mHeartbeatInterval;
- const F32 mHeartbeatTimeout;
- };
- #endif