diff options
Diffstat (limited to 'indra/llmessage/llcircuit.h')
| -rw-r--r-- | indra/llmessage/llcircuit.h | 315 | 
1 files changed, 315 insertions, 0 deletions
| diff --git a/indra/llmessage/llcircuit.h b/indra/llmessage/llcircuit.h new file mode 100644 index 0000000000..003734df29 --- /dev/null +++ b/indra/llmessage/llcircuit.h @@ -0,0 +1,315 @@ +/**  + * @file llcircuit.h + * @brief Provides a method for tracking network circuit information + * for the UDP message system + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_LLCIRCUIT_H +#define LL_LLCIRCUIT_H + +#include <map> +#include <vector> + +#include "llerror.h" +#include "linked_lists.h" + +#include "lltimer.h" +#include "timing.h" +#include "net.h" +#include "llhost.h" +#include "llpacketack.h" +#include "lluuid.h" +#include "llthrottle.h" + +// +// Constants +// +const F32 PING_INTERVAL_MAX = 100.f; +const F32 PING_INTERVAL_ALARM = 50.f; + + +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; +const U8 LL_PACKET_ID_SIZE = 4; + +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; + +// +// Classes +// + + +class LLCircuitData +{ +public: +	LLCircuitData(const LLHost &host, TPACKETID in_id); +	~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; } + +	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); +	const char* getInfoString() 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 +}; + + +// Actually a singleton class -- the global messagesystem +// has a single LLCircuit member. +class LLCircuit +{ +public: +	// CREATORS +	LLCircuit(); +	~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); +	const char* getInfoString() 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; +}; +#endif | 
