llcircuit.h

Go to the documentation of this file.
00001 
00033 #ifndef LL_LLCIRCUIT_H
00034 #define LL_LLCIRCUIT_H
00035 
00036 #include <map>
00037 #include <vector>
00038 
00039 #include "llerror.h"
00040 
00041 #include "lltimer.h"
00042 #include "timing.h"
00043 #include "net.h"
00044 #include "llhost.h"
00045 #include "llpacketack.h"
00046 #include "lluuid.h"
00047 #include "llthrottle.h"
00048 
00049 //
00050 // Constants
00051 //
00052 const F32 PING_INTERVAL_MAX = 100.f;
00053 const F32 PING_INTERVAL_ALARM = 50.f;
00054 
00055 
00056 const F32 LL_AVERAGED_PING_ALPHA = 0.2f;  // relaxation constant on ping running average
00057 const F32 LL_AVERAGED_PING_MAX = 2000;    // msec
00058 const F32 LL_AVERAGED_PING_MIN =  100;    // msec  // IW: increased to avoid retransmits when a process is slow
00059 
00060 const U32 INITIAL_PING_VALUE_MSEC = 1000; // initial value for the ping delay, or for ping delay for an unknown circuit
00061 
00062 const TPACKETID LL_MAX_OUT_PACKET_ID = 0x01000000;
00063 
00064 // 0 - flags
00065 // [1,4] - packetid
00066 // 5 - data offset (after message name)
00067 const U8 LL_PACKET_ID_SIZE = 6;
00068 
00069 const S32 LL_MAX_RESENT_PACKETS_PER_FRAME = 100;
00070 const S32 LL_MAX_ACKED_PACKETS_PER_FRAME = 200;
00071 
00072 //
00073 // Prototypes and Predefines
00074 //
00075 class LLMessageSystem;
00076 class LLEncodedDatagramService;
00077 class LLSD;
00078 
00079 //
00080 // Classes
00081 //
00082 
00083 
00084 class LLCircuitData
00085 {
00086 public:
00087         LLCircuitData(const LLHost &host, TPACKETID in_id);
00088         ~LLCircuitData();
00089 
00090         S32             resendUnackedPackets(const F64 now);
00091         void    clearDuplicateList(TPACKETID oldest_id);
00092 
00093 
00094         void    dumpResendCountAndReset(); // Used for tracking how many resends are being done on a circuit.
00095 
00096 
00097 
00098         // Public because stupid message system callbacks uses it.
00099         void            pingTimerStart();
00100         void            pingTimerStop(const U8 ping_id);
00101         void                    ackReliablePacket(TPACKETID packet_num);
00102 
00103         // remote computer information
00104         const LLUUID& getRemoteID() const { return mRemoteID; }
00105         const LLUUID& getRemoteSessionID() const { return mRemoteSessionID; }
00106         void setRemoteID(const LLUUID& id) { mRemoteID = id; }
00107         void setRemoteSessionID(const LLUUID& id) { mRemoteSessionID = id; }
00108 
00109         void            setTrusted(BOOL t);
00110 
00111         // The local end point ID is used when establishing a trusted circuit.
00112         // no matching set function for getLocalEndPointID()
00113         // mLocalEndPointID should only ever be setup in the LLCircuitData constructor
00114         const           LLUUID& getLocalEndPointID() const { return mLocalEndPointID; }
00115 
00116         U32             getPingDelay() const;
00117         S32                             getPingsInTransit() const                       { return mPingsInTransit; }
00118 
00119         // ACCESSORS
00120         BOOL            isAlive() const;
00121         BOOL            isBlocked() const;
00122         BOOL            getAllowTimeout() const;
00123         F32                     getPingDelayAveraged();
00124         F32                     getPingInTransitTime();
00125         U32                     getPacketsIn() const;
00126         S32                     getBytesIn() const;
00127         S32                     getBytesOut() const;
00128         U32                     getPacketsOut() const;
00129         U32                     getPacketsLost() const;
00130         TPACKETID       getPacketOutID() const;
00131         BOOL            getTrusted() const;
00132         F32 getAgeInSeconds() const;
00133         S32                     getUnackedPacketCount() const   { return mUnackedPacketCount; }
00134         S32                     getUnackedPacketBytes() const   { return mUnackedPacketBytes; }
00135         F64         getNextPingSendTime() const { return mNextPingSendTime; }
00136 
00137         LLThrottleGroup &getThrottleGroup()             {       return mThrottles; }
00138 
00139         class less
00140         {
00141         public:
00142                 bool operator()(const LLCircuitData* lhs, const LLCircuitData* rhs) const
00143                 {
00144                         if (lhs->getNextPingSendTime() < rhs->getNextPingSendTime())
00145                         {
00146                                 return true;
00147                         }
00148                         else if (lhs->getNextPingSendTime() > rhs->getNextPingSendTime())
00149                         {
00150                                 return false;
00151                         }
00152                         else return lhs > rhs;
00153                 }
00154         };
00155 
00156         //
00157         // Debugging stuff (not necessary for operation)
00158         //
00159         void                                    checkPeriodTime();              // Reset per-period counters if necessary.
00160         friend std::ostream&    operator<<(std::ostream& s, LLCircuitData &circuit);
00161         void getInfo(LLSD& info) const;
00162 
00163         friend class LLCircuit;
00164         friend class LLMessageSystem;
00165         friend class LLEncodedDatagramService;
00166         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.
00167 protected:
00168         TPACKETID               nextPacketOutID();
00169         void                            setPacketInID(TPACKETID id);
00170         void                                    checkPacketInID(TPACKETID id, BOOL receive_resent);
00171         void                    setPingDelay(U32 ping);
00172         BOOL                    checkCircuitTimeout();  // Return FALSE if the circuit is dead and should be cleaned up
00173 
00174         void                    addBytesIn(S32 bytes);
00175         void                    addBytesOut(S32 bytes);
00176 
00177         U8                              nextPingID()                    { mLastPingID++; return mLastPingID; }
00178 
00179         BOOL                    updateWatchDogTimers(LLMessageSystem *msgsys);  // Return FALSE if the circuit is dead and should be cleaned up
00180 
00181         void                    addReliablePacket(S32 mSocket, U8 *buf_ptr, S32 buf_len, LLReliablePacketParams *params);
00182         BOOL                    isDuplicateResend(TPACKETID packetnum);
00183         // Call this method when a reliable message comes in - this will
00184         // correctly place the packet in the correct list to be acked
00185         // later. RAack = requested ack
00186         BOOL collectRAck(TPACKETID packet_num);
00187 
00188 
00189         void                    setTimeoutCallback(void (*callback_func)(const LLHost &host, void *user_data), void *user_data);
00190 
00191 
00192 
00193         void                    setAlive(BOOL b_alive);
00194         void                    setAllowTimeout(BOOL allow);
00195 
00196 protected:
00197         // Identification for this circuit.
00198         LLHost mHost;
00199         LLUUID mRemoteID;
00200         LLUUID mRemoteSessionID;
00201 
00202         LLThrottleGroup mThrottles;
00203 
00204         TPACKETID               mWrapID;
00205 
00206         // Current packet IDs of incoming/outgoing packets
00207         // Used for packet sequencing/packet loss detection.
00208         TPACKETID               mPacketsOutID;
00209         TPACKETID               mPacketsInID;
00210         TPACKETID               mHighestPacketID;
00211 
00212 
00213         // Callback and data to run in the case of a circuit timeout.
00214         // Used primarily to try and reconnect to servers if they crash/die.
00215         void    (*mTimeoutCallback)(const LLHost &host, void *user_data);
00216         void    *mTimeoutUserData;
00217 
00218         BOOL    mTrusted;                                       // Is this circuit trusted?
00219         BOOL    mbAllowTimeout;                         // Machines can "pause" circuits, forcing them not to be dropped
00220 
00221         BOOL    mbAlive;                                        // Indicates whether a circuit is "alive", i.e. responded to pings
00222 
00223         BOOL    mBlocked;                                       // Blocked is true if the circuit is hosed, i.e. far behind on pings
00224 
00225         // Not sure what the difference between this and mLastPingSendTime is
00226         F64             mPingTime;                                      // Time at which a ping was sent.
00227 
00228         F64             mLastPingSendTime;                      // Time we last sent a ping
00229         F64             mLastPingReceivedTime;          // Time we last received a ping
00230         F64     mNextPingSendTime;          // Time to try and send the next ping
00231         S32             mPingsInTransit;                        // Number of pings in transit
00232         U8              mLastPingID;                            // ID of the last ping that we sent out
00233 
00234 
00235         // Used for determining the resend time for reliable resends.
00236         U32             mPingDelay;             // raw ping delay
00237         F32             mPingDelayAveraged;     // averaged ping delay (fast attack/slow decay)
00238 
00239         typedef std::map<TPACKETID, U64> packet_time_map;
00240 
00241         packet_time_map                                                 mPotentialLostPackets;
00242         packet_time_map                                                 mRecentlyReceivedReliablePackets;
00243         std::vector<TPACKETID> mAcks;
00244 
00245         typedef std::map<TPACKETID, LLReliablePacket *> reliable_map;
00246         typedef reliable_map::iterator                                  reliable_iter;
00247 
00248         reliable_map                                                    mUnackedPackets;
00249         reliable_map                                                    mFinalRetryPackets;
00250 
00251         S32                                                                             mUnackedPacketCount;
00252         S32                                                                             mUnackedPacketBytes;
00253 
00254 
00255         LLUUID                                                                  mLocalEndPointID;
00256 
00257         //
00258         // These variables are being used for statistical and debugging purpose ONLY,
00259         // as far as I can tell.
00260         //
00261 
00262         U32             mPacketsOut;
00263         U32             mPacketsIn;
00264         S32             mPacketsLost;
00265         S32             mBytesIn;
00266         S32             mBytesOut;
00267 
00268         F32             mLastPeriodLength;              // seconds
00269         S32             mBytesInLastPeriod;
00270         S32             mBytesOutLastPeriod;
00271         S32             mBytesInThisPeriod;
00272         S32             mBytesOutThisPeriod;
00273         F32             mPeakBPSIn;                             // bits per second, max of all period bps
00274         F32             mPeakBPSOut;                    // bits per second, max of all period bps
00275         F64             mPeriodTime;
00276         LLTimer mExistenceTimer;            // initialized when circuit created, used to track bandwidth numbers
00277 
00278         S32             mCurrentResendCount;    // Number of resent packets since last spam
00279 };
00280 
00281 
00282 // Actually a singleton class -- the global messagesystem
00283 // has a single LLCircuit member.
00284 class LLCircuit
00285 {
00286 public:
00287         // CREATORS
00288         LLCircuit();
00289         ~LLCircuit();
00290 
00291         // ACCESSORS
00292         LLCircuitData* findCircuit(const LLHost& host) const;
00293         BOOL isCircuitAlive(const LLHost& host) const;
00294         
00295         // MANIPULATORS
00296         LLCircuitData   *addCircuitData(const LLHost &host, TPACKETID in_id);
00297         void                    removeCircuitData(const LLHost &host);
00298 
00299         void                updateWatchDogTimers(LLMessageSystem *msgsys);
00300         void                    resendUnackedPackets(S32& unacked_list_length, S32& unacked_list_size);
00301 
00302         // this method is called during the message system processAcks()
00303         // to send out any acks that did not get sent already. 
00304         void sendAcks();
00305 
00306         friend std::ostream& operator<<(std::ostream& s, LLCircuit &circuit);
00307         void getInfo(LLSD& info) const;
00308 
00309         void                    dumpResends();
00310 
00311         typedef std::map<LLHost, LLCircuitData*> circuit_data_map;
00312 
00322         void getCircuitRange(
00323                 const LLHost& key,
00324                 circuit_data_map::iterator& first,
00325                 circuit_data_map::iterator& end);
00326 
00327         // Lists that optimize how many circuits we need to traverse a frame
00328         // HACK - this should become protected eventually, but stupid !@$@# message system/circuit classes are jumbling things up.
00329         circuit_data_map mUnackedCircuitMap; // Map of circuits with unacked data
00330         circuit_data_map mSendAckMap; // Map of circuits which need to send acks
00331 protected:
00332         circuit_data_map mCircuitData;
00333 
00334         typedef std::set<LLCircuitData *, LLCircuitData::less> ping_set_t; // Circuits sorted by next ping time
00335         ping_set_t mPingSet;
00336 
00337         // This variable points to the last circuit data we found to
00338         // optimize the many, many times we call findCircuit. This may be
00339         // set in otherwise const methods, so it is declared mutable.
00340         mutable LLCircuitData* mLastCircuit;
00341 };
00342 #endif

Generated on Fri May 16 08:32:23 2008 for SecondLife by  doxygen 1.5.5