message.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_MESSAGE_H
00033 #define LL_MESSAGE_H
00034 
00035 #include <cstring>
00036 #include <set>
00037 
00038 #if LL_LINUX
00039 #include <endian.h>
00040 #include <netinet/in.h>
00041 #endif
00042 
00043 #if LL_SOLARIS
00044 #include <netinet/in.h>
00045 #endif
00046 
00047 #if LL_WINDOWS
00048 #include "winsock2.h" // htons etc.
00049 #endif
00050 
00051 #include "llerror.h"
00052 #include "net.h"
00053 #include "string_table.h"
00054 #include "llcircuit.h"
00055 #include "lltimer.h"
00056 #include "llpacketring.h"
00057 #include "llhost.h"
00058 #include "llhttpclient.h"
00059 #include "llhttpnode.h"
00060 #include "llpacketack.h"
00061 #include "message_prehash.h"
00062 #include "llstl.h"
00063 #include "llmsgvariabletype.h"
00064 #include "llmsgvariabletype.h"
00065 
00066 const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
00067 const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
00068 
00069 const S32 MESSAGE_MAX_PER_FRAME = 400;
00070 
00071 class LLMessageStringTable : public LLSingleton<LLMessageStringTable>
00072 {
00073 public:
00074         LLMessageStringTable();
00075         ~LLMessageStringTable();
00076 
00077         char *getString(const char *str);
00078 
00079         U32      mUsed;
00080         BOOL mEmpty[MESSAGE_NUMBER_OF_HASH_BUCKETS];
00081         char mString[MESSAGE_NUMBER_OF_HASH_BUCKETS][MESSAGE_MAX_STRINGS_LENGTH];       /* Flawfinder: ignore */
00082 };
00083 
00084 
00085 // Individual Messages are described with the following format
00086 // Note that to ease parsing, keywords are used
00087 //
00088 //      // Comment                                      (Comment like a C++ single line comment)
00089 //                                                      Comments can only be placed between Messages
00090 // {
00091 // MessageName                                  (same naming restrictions as C variable)
00092 // Frequency                                    ("High", "Medium", or "Low" - determines whether message ID is 8, 16, or 32-bits -- 
00093 //                                                               there can 254 messages in the first 2 groups, 32K in the last group)
00094 //                                                              (A message can be made up only of the Name if it is only a signal)
00095 // Trust                                                ("Trusted", "NotTrusted" - determines if a message will be accepted
00096 //                                                               on a circuit.  "Trusted" messages are not accepted from NotTrusted circuits
00097 //                                                               while NotTrusted messages are accepted on any circuit.  An example of a
00098 //                                                               NotTrusted circuit is any circuit from the viewer.)
00099 // Encoding                                             ("Zerocoded", "Unencoded" - zerocoded messages attempt to compress sequences of 
00100 //                                                               zeros, but if there is no space win, it discards the compression and goes unencoded)
00101 //              {
00102 //              Block Name                              (same naming restrictions as C variable)
00103 //              Block Type                              ("Single", "Multiple", or "Variable" - determines if the block is coded once, 
00104 //                                                               a known number of times, or has a 8 bit argument encoded to tell the decoder 
00105 //                                                               how many times the group is repeated)
00106 //              Block Repeat Number             (Optional - used only with the "Multiple" type - tells how many times the field is repeated
00107 //                      {
00108 //                      Variable 1 Name         (same naming restrictions as C variable)
00109 //                      Variable Type           ("Fixed" or "Variable" - determines if the variable is of fixed size or needs to 
00110 //                                                               encode an argument describing the size in bytes)
00111 //                      Variable Size           (In bytes, either of the "Fixed" variable itself or of the size argument)
00112 //
00113 //                      repeat variables
00114 //
00115 //                      }
00116 //
00117 //                      Repeat for number of variables in block         
00118 //              }
00119 //
00120 //              Repeat for number of blocks in message
00121 // }
00122 // Repeat for number of messages in file
00123 //
00124 
00125 // Constants
00126 const S32 MAX_MESSAGE_INTERNAL_NAME_SIZE = 255;
00127 const S32 MAX_BUFFER_SIZE = NET_BUFFER_SIZE;
00128 const S32 MAX_BLOCKS = 255;
00129 
00130 const U8 LL_ZERO_CODE_FLAG = 0x80;
00131 const U8 LL_RELIABLE_FLAG = 0x40;
00132 const U8 LL_RESENT_FLAG = 0x20;
00133 const U8 LL_ACK_FLAG = 0x10;
00134 
00135 // 1 byte flags, 4 bytes sequence, 1 byte offset + 1 byte message name (high)
00136 const S32 LL_MINIMUM_VALID_PACKET_SIZE = LL_PACKET_ID_SIZE + 1;
00137 enum EPacketHeaderLayout
00138 {
00139         PHL_FLAGS = 0,
00140         PHL_PACKET_ID = 1,
00141         PHL_OFFSET = 5,
00142         PHL_NAME = 6
00143 };
00144 
00145 
00146 const S32 LL_DEFAULT_RELIABLE_RETRIES = 3;
00147 const F32 LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS = 1.f;
00148 const F32 LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS = 1.f;
00149 const F32 LL_PING_BASED_TIMEOUT_DUMMY = 0.0f;
00150 
00151 // *NOTE: Maybe these factors shouldn't include the msec to sec conversion
00152 // implicitly.
00153 // However, all units should be MKS.
00154 const F32 LL_SEMIRELIABLE_TIMEOUT_FACTOR        = 5.f / 1000.f;         // factor * averaged ping
00155 const F32 LL_RELIABLE_TIMEOUT_FACTOR            = 5.f / 1000.f;      // factor * averaged ping
00156 const F32 LL_FILE_XFER_TIMEOUT_FACTOR           = 5.f / 1000.f;      // factor * averaged ping
00157 const F32 LL_LOST_TIMEOUT_FACTOR                        = 16.f / 1000.f;     // factor * averaged ping for marking packets "Lost"
00158 const F32 LL_MAX_LOST_TIMEOUT                           = 5.f;                          // Maximum amount of time before considering something "lost"
00159 
00160 const S32 MAX_MESSAGE_COUNT_NUM = 1024;
00161 
00162 // Forward declarations
00163 class LLCircuit;
00164 class LLVector3;
00165 class LLVector4;
00166 class LLVector3d;
00167 class LLQuaternion;
00168 class LLSD;
00169 class LLUUID;
00170 class LLMessageSystem;
00171 class LLPumpIO;
00172 
00173 // message system exceptional condition handlers.
00174 enum EMessageException
00175 {
00176         MX_UNREGISTERED_MESSAGE, // message number not part of template
00177         MX_PACKET_TOO_SHORT, // invalid packet, shorter than minimum packet size
00178         MX_RAN_OFF_END_OF_PACKET, // ran off the end of the packet during decode
00179         MX_WROTE_PAST_BUFFER_SIZE // wrote past buffer size in zero code expand
00180 };
00181 typedef void (*msg_exception_callback)(LLMessageSystem*,void*,EMessageException);
00182 
00183 
00184 // message data pieces are used to collect the data called for by the message template
00185 class LLMsgData;
00186 class LLMsgBlkData;
00187 class LLMessageTemplate;
00188 
00189 class LLMessagePollInfo;
00190 class LLMessageBuilder;
00191 class LLTemplateMessageBuilder;
00192 class LLSDMessageBuilder;
00193 class LLMessageReader;
00194 class LLTemplateMessageReader;
00195 class LLSDMessageReader;
00196 
00197 
00198 
00199 class LLUseCircuitCodeResponder
00200 {
00201         LOG_CLASS(LLMessageSystem);
00202         
00203 public:
00204         virtual ~LLUseCircuitCodeResponder();
00205         virtual void complete(const LLHost& host, const LLUUID& agent) const = 0;
00206 };
00207 
00208 class LLMessageSystem
00209 {
00210  private:
00211         U8                                      mSendBuffer[MAX_BUFFER_SIZE];
00212         S32                                     mSendSize;
00213 
00214  public:
00215         LLPacketRing                            mPacketRing;
00216         LLReliablePacketParams                  mReliablePacketParams;
00217 
00218         // Set this flag to TRUE when you want *very* verbose logs.
00219         BOOL mVerboseLog;
00220 
00221         F32                                     mMessageFileVersionNumber;
00222 
00223         typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t;
00224         typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
00225 
00226 private:
00227         message_template_name_map_t             mMessageTemplates;
00228         message_template_number_map_t           mMessageNumbers;
00229 
00230 public:
00231         S32                                     mSystemVersionMajor;
00232         S32                                     mSystemVersionMinor;
00233         S32                                     mSystemVersionPatch;
00234         S32                                     mSystemVersionServer;
00235         U32                                     mVersionFlags;
00236 
00237         BOOL                                    mbProtected;
00238 
00239         U32                                     mNumberHighFreqMessages;
00240         U32                                     mNumberMediumFreqMessages;
00241         U32                                     mNumberLowFreqMessages;
00242         S32                                     mPort;
00243         S32                                     mSocket;
00244 
00245         U32                                     mPacketsIn;                 // total packets in, including compressed and uncompressed
00246         U32                                     mPacketsOut;                // total packets out, including compressed and uncompressed
00247 
00248         U64                                     mBytesIn;                   // total bytes in, including compressed and uncompressed
00249         U64                                     mBytesOut;                  // total bytes out, including compressed and uncompressed
00250         
00251         U32                                     mCompressedPacketsIn;       // total compressed packets in
00252         U32                                     mCompressedPacketsOut;      // total compressed packets out
00253 
00254         U32                                     mReliablePacketsIn;         // total reliable packets in
00255         U32                                     mReliablePacketsOut;        // total reliable packets out
00256 
00257         U32                                     mDroppedPackets;            // total dropped packets in
00258         U32                                     mResentPackets;             // total resent packets out
00259         U32                                     mFailedResendPackets;       // total resend failure packets out
00260         U32                                     mOffCircuitPackets;         // total # of off-circuit packets rejected
00261         U32                                     mInvalidOnCircuitPackets;   // total # of on-circuit but invalid packets rejected
00262 
00263         S64                                     mUncompressedBytesIn;       // total uncompressed size of compressed packets in
00264         S64                                     mUncompressedBytesOut;      // total uncompressed size of compressed packets out
00265         S64                                     mCompressedBytesIn;         // total compressed size of compressed packets in
00266         S64                                     mCompressedBytesOut;        // total compressed size of compressed packets out
00267         S64                                     mTotalBytesIn;              // total size of all uncompressed packets in
00268         S64                                     mTotalBytesOut;             // total size of all uncompressed packets out
00269 
00270         BOOL                                    mSendReliable;              // does the outgoing message require a pos ack?
00271 
00272         LLCircuit                               mCircuitInfo;
00273         F64                                     mCircuitPrintTime;          // used to print circuit debug info every couple minutes
00274         F32                                     mCircuitPrintFreq;          // seconds
00275 
00276         std::map<U64, U32>                      mIPPortToCircuitCode;
00277         std::map<U32, U64>                      mCircuitCodeToIPPort;
00278         U32                                     mOurCircuitCode;
00279         S32                                     mSendPacketFailureCount;
00280         S32                                     mUnackedListDepth;
00281         S32                                     mUnackedListSize;
00282         S32                                     mDSMaxListDepth;
00283 
00284 public:
00285         // Read file and build message templates
00286         LLMessageSystem(const char *filename, U32 port, S32 version_major,
00287                 S32 version_minor, S32 version_patch);
00288 
00289         ~LLMessageSystem();
00290 
00291         BOOL isOK() const { return !mbError; }
00292         S32 getErrorCode() const { return mErrorCode; }
00293 
00294         // Read file and build message templates filename must point to a
00295         // valid string which specifies the path of a valid linden
00296         // template.
00297         void loadTemplateFile(const char* filename);
00298 
00299 
00300         // methods for building, sending, receiving, and handling messages
00301         void    setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL);
00302         void    setHandlerFunc(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL)
00303         {
00304                 setHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data);
00305         }
00306 
00307         // Set a callback function for a message system exception.
00308         void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL);
00309         // Call the specified exception func, and return TRUE if a
00310         // function was found and called. Otherwise return FALSE.
00311         BOOL callExceptionFunc(EMessageException exception);
00312 
00313         // Set a function that will be called once per packet processed with the 
00314         // hashed message name and the time spent in the processing handler function
00315         // measured in seconds.  JC
00316         typedef void (*msg_timing_callback)(const char* hashed_name, F32 time, void* data);
00317         void setTimingFunc(msg_timing_callback func, void* data = NULL);
00318         msg_timing_callback getTimingCallback() 
00319         { 
00320                 return mTimingCallback; 
00321         }
00322         void* getTimingCallbackData() 
00323         {
00324                 return mTimingCallbackData;
00325         }
00326 
00327         // This method returns true if the code is in the circuit codes map.
00328         BOOL isCircuitCodeKnown(U32 code) const;
00329 
00330         // usually called in response to an AddCircuitCode message, but
00331         // may also be called by the login process.
00332         bool addCircuitCode(U32 code, const LLUUID& session_id);
00333 
00334         BOOL    poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received
00335         BOOL    checkMessages( S64 frame_count = 0 );
00336         void    processAcks();
00337 
00338         BOOL    isMessageFast(const char *msg);
00339         BOOL    isMessage(const char *msg)
00340         {
00341                 return isMessageFast(LLMessageStringTable::getInstance()->getString(msg));
00342         }
00343 
00344         void dumpPacketToLog();
00345 
00346         char    *getMessageName();
00347 
00348         const LLHost& getSender() const;
00349         U32             getSenderIP() const;                    // getSender() is preferred
00350         U32             getSenderPort() const;          // getSender() is preferred
00351 
00352         // This method returns the uuid associated with the sender. The
00353         // UUID will be null if it is not yet known or is a server
00354         // circuit.
00355         const LLUUID& getSenderID() const;
00356 
00357         // This method returns the session id associated with the last
00358         // sender.
00359         const LLUUID& getSenderSessionID() const;
00360 
00361         // set & get the session id (useful for viewers for now.)
00362         void setMySessionID(const LLUUID& session_id) { mSessionID = session_id; }
00363         const LLUUID& getMySessionID() { return mSessionID; }
00364 
00365         void newMessageFast(const char *name);
00366         void newMessage(const char *name);
00367 
00368         void    copyMessageRtoS();
00369         void    clearMessage();
00370 
00371         void nextBlockFast(const char *blockname);
00372         void    nextBlock(const char *blockname)
00373         {
00374                 nextBlockFast(LLMessageStringTable::getInstance()->getString(blockname));
00375         }
00376 
00377 public:
00378         void addBinaryDataFast(const char *varname, const void *data, S32 size);
00379         void addBinaryData(const char *varname, const void *data, S32 size);
00380 
00381         void    addBOOLFast( const char* varname, BOOL b);                                              // typed, checks storage space
00382         void    addBOOL( const char* varname, BOOL b);                                          // typed, checks storage space
00383         void    addS8Fast(      const char *varname, S8 s);                                                     // typed, checks storage space
00384         void    addS8(  const char *varname, S8 s);                                                     // typed, checks storage space
00385         void    addU8Fast(      const char *varname, U8 u);                                                     // typed, checks storage space
00386         void    addU8(  const char *varname, U8 u);                                                     // typed, checks storage space
00387         void    addS16Fast(     const char *varname, S16 i);                                            // typed, checks storage space
00388         void    addS16( const char *varname, S16 i);                                            // typed, checks storage space
00389         void    addU16Fast(     const char *varname, U16 i);                                            // typed, checks storage space
00390         void    addU16( const char *varname, U16 i);                                            // typed, checks storage space
00391         void    addF32Fast(     const char *varname, F32 f);                                            // typed, checks storage space
00392         void    addF32( const char *varname, F32 f);                                            // typed, checks storage space
00393         void    addS32Fast(     const char *varname, S32 s);                                            // typed, checks storage space
00394         void    addS32( const char *varname, S32 s);                                            // typed, checks storage space
00395         void addU32Fast(        const char *varname, U32 u);                                            // typed, checks storage space
00396         void    addU32( const char *varname, U32 u);                                            // typed, checks storage space
00397         void    addU64Fast(     const char *varname, U64 lu);                                           // typed, checks storage space
00398         void    addU64( const char *varname, U64 lu);                                           // typed, checks storage space
00399         void    addF64Fast(     const char *varname, F64 d);                                            // typed, checks storage space
00400         void    addF64( const char *varname, F64 d);                                            // typed, checks storage space
00401         void    addVector3Fast( const char *varname, const LLVector3& vec);             // typed, checks storage space
00402         void    addVector3(     const char *varname, const LLVector3& vec);             // typed, checks storage space
00403         void    addVector4Fast( const char *varname, const LLVector4& vec);             // typed, checks storage space
00404         void    addVector4(     const char *varname, const LLVector4& vec);             // typed, checks storage space
00405         void    addVector3dFast( const char *varname, const LLVector3d& vec);   // typed, checks storage space
00406         void    addVector3d( const char *varname, const LLVector3d& vec);       // typed, checks storage space
00407         void    addQuatFast( const char *varname, const LLQuaternion& quat);    // typed, checks storage space
00408         void    addQuat( const char *varname, const LLQuaternion& quat);        // typed, checks storage space
00409         void addUUIDFast( const char *varname, const LLUUID& uuid);                     // typed, checks storage space
00410         void    addUUID( const char *varname, const LLUUID& uuid);                      // typed, checks storage space
00411         void    addIPAddrFast( const char *varname, const U32 ip);                      // typed, checks storage space
00412         void    addIPAddr( const char *varname, const U32 ip);                  // typed, checks storage space
00413         void    addIPPortFast( const char *varname, const U16 port);                    // typed, checks storage space
00414         void    addIPPort( const char *varname, const U16 port);                        // typed, checks storage space
00415         void    addStringFast( const char* varname, const char* s);                             // typed, checks storage space
00416         void    addString( const char* varname, const char* s);                         // typed, checks storage space
00417         void    addStringFast( const char* varname, const std::string& s);                              // typed, checks storage space
00418         void    addString( const char* varname, const std::string& s);                          // typed, checks storage space
00419 
00420         S32 getCurrentSendTotal() const;
00421         TPACKETID getCurrentRecvPacketID() { return mCurrentRecvPacketID; }
00422 
00423         // This method checks for current send total and returns true if
00424         // you need to go to the next block type or need to start a new
00425         // message. Specify the current blockname to check block counts,
00426         // otherwise the method only checks against MTU.
00427         BOOL isSendFull(const char* blockname = NULL);
00428         BOOL isSendFullFast(const char* blockname = NULL);
00429 
00430         BOOL removeLastBlock();
00431 
00432         //void  buildMessage();
00433 
00434         S32     zeroCode(U8 **data, S32 *data_size);
00435         S32             zeroCodeExpand(U8 **data, S32 *data_size);
00436         S32             zeroCodeAdjustCurrentSendTotal();
00437 
00438         // Uses ping-based retry
00439         S32 sendReliable(const LLHost &host);
00440 
00441         // Uses ping-based retry
00442         S32     sendReliable(const U32 circuit)                 { return sendReliable(findHost(circuit)); }
00443 
00444         // Use this one if you DON'T want automatic ping-based retry.
00445         S32     sendReliable(   const LLHost &host, 
00446                                                         S32 retries, 
00447                                                         BOOL ping_based_retries,
00448                                                         F32 timeout, 
00449                                                         void (*callback)(void **,S32), 
00450                                                         void ** callback_data);
00451 
00452         S32 sendSemiReliable(   const LLHost &host, 
00453                                                         void (*callback)(void **,S32), void ** callback_data);
00454 
00455         // flush sends a message only if data's been pushed on it.
00456         S32             flushSemiReliable(      const LLHost &host, 
00457                                                                 void (*callback)(void **,S32), void ** callback_data);
00458 
00459         S32             flushReliable(  const LLHost &host );
00460 
00461         void    forwardMessage(const LLHost &host);
00462         void    forwardReliable(const LLHost &host);
00463         void    forwardReliable(const U32 circuit_code);
00464         S32 forwardReliable(
00465                 const LLHost &host, 
00466                 S32 retries, 
00467                 BOOL ping_based_timeout,
00468                 F32 timeout, 
00469                 void (*callback)(void **,S32), 
00470                 void ** callback_data);
00471 
00472         LLHTTPClient::ResponderPtr createResponder(const std::string& name);
00473         S32             sendMessage(const LLHost &host);
00474         S32             sendMessage(const U32 circuit);
00475         S32             sendMessage(const LLHost &host, const char* name,
00476                                                 const LLSD& message);
00477 
00478         // BOOL decodeData(const U8 *buffer, const LLHost &host);
00479 
00480         void    getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
00481         void    getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
00482         void    getBOOLFast(    const char *block, const char *var, BOOL &data, S32 blocknum = 0);
00483         void    getBOOL(        const char *block, const char *var, BOOL &data, S32 blocknum = 0);
00484         void    getS8Fast(              const char *block, const char *var, S8 &data, S32 blocknum = 0);
00485         void    getS8(          const char *block, const char *var, S8 &data, S32 blocknum = 0);
00486         void    getU8Fast(              const char *block, const char *var, U8 &data, S32 blocknum = 0);
00487         void    getU8(          const char *block, const char *var, U8 &data, S32 blocknum = 0);
00488         void    getS16Fast(             const char *block, const char *var, S16 &data, S32 blocknum = 0);
00489         void    getS16(         const char *block, const char *var, S16 &data, S32 blocknum = 0);
00490         void    getU16Fast(             const char *block, const char *var, U16 &data, S32 blocknum = 0);
00491         void    getU16(         const char *block, const char *var, U16 &data, S32 blocknum = 0);
00492         void    getS32Fast(             const char *block, const char *var, S32 &data, S32 blocknum = 0);
00493         void    getS32(         const char *block, const char *var, S32 &data, S32 blocknum = 0);
00494         void    getF32Fast(             const char *block, const char *var, F32 &data, S32 blocknum = 0);
00495         void    getF32(         const char *block, const char *var, F32 &data, S32 blocknum = 0);
00496         void getU32Fast(                const char *block, const char *var, U32 &data, S32 blocknum = 0);
00497         void    getU32(         const char *block, const char *var, U32 &data, S32 blocknum = 0);
00498         void getU64Fast(                const char *block, const char *var, U64 &data, S32 blocknum = 0);
00499         void    getU64(         const char *block, const char *var, U64 &data, S32 blocknum = 0);
00500         void    getF64Fast(             const char *block, const char *var, F64 &data, S32 blocknum = 0);
00501         void    getF64(         const char *block, const char *var, F64 &data, S32 blocknum = 0);
00502         void    getVector3Fast( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0);
00503         void    getVector3(     const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0);
00504         void    getVector4Fast( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0);
00505         void    getVector4(     const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0);
00506         void    getVector3dFast(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
00507         void    getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
00508         void    getQuatFast(    const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
00509         void    getQuat(        const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
00510         void getUUIDFast(       const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
00511         void    getUUID(        const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
00512         void getIPAddrFast(     const char *block, const char *var, U32 &ip, S32 blocknum = 0);
00513         void    getIPAddr(      const char *block, const char *var, U32 &ip, S32 blocknum = 0);
00514         void getIPPortFast(     const char *block, const char *var, U16 &port, S32 blocknum = 0);
00515         void    getIPPort(      const char *block, const char *var, U16 &port, S32 blocknum = 0);
00516         void getStringFast(     const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
00517         void    getString(      const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
00518 
00519 
00520         // Utility functions to generate a replay-resistant digest check
00521         // against the shared secret. The window specifies how much of a
00522         // time window is allowed - 1 second is good for tight
00523         // connections, but multi-process windows might want to be upwards
00524         // of 5 seconds. For generateDigest, you want to pass in a
00525         // character array of at least MD5HEX_STR_SIZE so that the hex
00526         // digest and null termination will fit.
00527         bool generateDigestForNumberAndUUIDs(char* digest, const U32 number, const LLUUID &id1, const LLUUID &id2) const;
00528         bool generateDigestForWindowAndUUIDs(char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const;
00529         bool isMatchingDigestForWindowAndUUIDs(const char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const;
00530 
00531         bool generateDigestForNumber(char* digest, const U32 number) const;
00532         bool generateDigestForWindow(char* digest, const S32 window) const;
00533         bool isMatchingDigestForWindow(const char* digest, const S32 window) const;
00534 
00535         void    showCircuitInfo();
00536         void getCircuitInfo(LLSD& info) const;
00537 
00538         U32 getOurCircuitCode();
00539         
00540         void    enableCircuit(const LLHost &host, BOOL trusted);
00541         void    disableCircuit(const LLHost &host);
00542         
00543         // Use this to establish trust on startup and in response to
00544         // DenyTrustedCircuit.
00545         void sendCreateTrustedCircuit(const LLHost& host, const LLUUID & id1, const LLUUID & id2);
00546 
00547         // Use this to inform a peer that they aren't currently trusted...
00548         // This now enqueues the request so that we can ensure that we only send
00549         // one deny per circuit per message loop so that this doesn't become a DoS.
00550         // The actual sending is done by reallySendDenyTrustedCircuit()
00551         void    sendDenyTrustedCircuit(const LLHost &host);
00552 
00554         bool isTrustedSender(const LLHost& host) const;
00555 
00557         bool isTrustedMessage(const std::string& name) const;
00558 
00560         bool isUntrustedMessage(const std::string& name) const;
00561 
00562 private:
00563         // A list of the circuits that need to be sent DenyTrustedCircuit messages.
00564         typedef std::set<LLHost> host_set_t;
00565         host_set_t mDenyTrustedCircuitSet;
00566 
00567         // Really sends the DenyTrustedCircuit message to a given host
00568         // related to sendDenyTrustedCircuit()
00569         void    reallySendDenyTrustedCircuit(const LLHost &host);
00570 
00571 public:
00572         // Use this to establish trust to and from a host.  This blocks
00573         // until trust has been established, and probably should only be
00574         // used on startup.
00575         void    establishBidirectionalTrust(const LLHost &host, S64 frame_count = 0);
00576 
00577         // returns whether the given host is on a trusted circuit
00578         BOOL    getCircuitTrust(const LLHost &host);
00579         
00580         void    setCircuitAllowTimeout(const LLHost &host, BOOL allow);
00581         void    setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost &host, void *user_data), void *user_data);
00582 
00583         BOOL    checkCircuitBlocked(const U32 circuit);
00584         BOOL    checkCircuitAlive(const U32 circuit);
00585         BOOL    checkCircuitAlive(const LLHost &host);
00586         void    setCircuitProtection(BOOL b_protect);
00587         U32             findCircuitCode(const LLHost &host);
00588         LLHost  findHost(const U32 circuit_code);
00589         void    sanityCheck();
00590 
00591         S32             getNumberOfBlocksFast(const char *blockname);
00592         S32             getNumberOfBlocks(const char *blockname);
00593         S32             getSizeFast(const char *blockname, const char *varname);
00594         S32             getSize(const char *blockname, const char *varname);
00595         S32             getSizeFast(const char *blockname, S32 blocknum, 
00596                                                 const char *varname); // size in bytes of data
00597         S32             getSize(const char *blockname, S32 blocknum, const char *varname);
00598 
00599         void    resetReceiveCounts();                           // resets receive counts for all message types to 0
00600         void    dumpReceiveCounts();                            // dumps receive count for each message type to llinfos
00601         void    dumpCircuitInfo();                                      // Circuit information to llinfos
00602 
00603         BOOL    isClear() const;                                        // returns mbSClear;
00604         S32     flush(const LLHost &host);
00605 
00606         U32             getListenPort( void ) const;
00607 
00608         void startLogging();                                    // start verbose  logging
00609         void stopLogging();                                             // flush and close file
00610         void summarizeLogs(std::ostream& str);  // log statistics
00611 
00612         S32             getReceiveSize() const;
00613         S32             getReceiveCompressedSize() const { return mIncomingCompressedSize; }
00614         S32             getReceiveBytes() const;
00615 
00616         S32             getUnackedListSize() const                      { return mUnackedListSize; }
00617 
00618         //const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
00619         //const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
00620 
00621         // friends
00622         friend std::ostream&    operator<<(std::ostream& s, LLMessageSystem &msg);
00623 
00624         void setMaxMessageTime(const F32 seconds);      // Max time to process messages before warning and dumping (neg to disable)
00625         void setMaxMessageCounts(const S32 num);        // Max number of messages before dumping (neg to disable)
00626         
00627         static U64 getMessageTimeUsecs(const BOOL update = FALSE);      // Get the current message system time in microseconds
00628         static F64 getMessageTimeSeconds(const BOOL update = FALSE); // Get the current message system time in seconds
00629 
00630         static void setTimeDecodes(BOOL b);
00631         static void setTimeDecodesSpamThreshold(F32 seconds); 
00632 
00633         // message handlers internal to the message systesm
00634         //static void processAssignCircuitCode(LLMessageSystem* msg, void**);
00635         static void processAddCircuitCode(LLMessageSystem* msg, void**);
00636         static void processUseCircuitCode(LLMessageSystem* msg, void**);
00637         static void processError(LLMessageSystem* msg, void**);
00638 
00639         // dispatch llsd message to http node tree
00640         static void dispatch(const std::string& msg_name,
00641                                                  const LLSD& message);
00642         static void dispatch(const std::string& msg_name,
00643                                                  const LLSD& message,
00644                                                  LLHTTPNode::ResponsePtr responsep);
00645 
00646         void setMessageBans(const LLSD& trusted, const LLSD& untrusted);
00647 
00661         S32 sendError(
00662                 const LLHost& host,
00663                 const LLUUID& agent_id,
00664                 S32 code,
00665                 const std::string& token,
00666                 const LLUUID& id,
00667                 const std::string& system,
00668                 const std::string& message,
00669                 const LLSD& data);
00670 
00671         // Check UDP messages and pump http_pump to receive HTTP messages.
00672         bool checkAllMessages(S64 frame_count, LLPumpIO* http_pump);
00673         
00674 private:
00675 
00676         // The mCircuitCodes is a map from circuit codes to session
00677         // ids. This allows us to verify sessions on connect.
00678         typedef std::map<U32, LLUUID> code_session_map_t;
00679         code_session_map_t mCircuitCodes;
00680 
00681         // Viewers need to track a process session in order to make sure
00682         // that no one gives them a bad circuit code.
00683         LLUUID mSessionID;
00684         
00685         void    addTemplate(LLMessageTemplate *templatep);
00686         void            clearReceiveState();
00687         BOOL            decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );
00688 
00689         void            logMsgFromInvalidCircuit( const LLHost& sender, BOOL recv_reliable );
00690         void            logTrustedMsgFromUntrustedCircuit( const LLHost& sender );
00691         void            logValidMsg(LLCircuitData *cdp, const LLHost& sender, BOOL recv_reliable, BOOL recv_resent, BOOL recv_acks );
00692         void            logRanOffEndOfPacket( const LLHost& sender );
00693 
00694         class LLMessageCountInfo
00695         {
00696         public:
00697                 U32 mMessageNum;
00698                 U32 mMessageBytes;
00699                 BOOL mInvalid;
00700         };
00701 
00702         LLMessagePollInfo                                               *mPollInfop;
00703 
00704         U8      mEncodedRecvBuffer[MAX_BUFFER_SIZE];
00705         U8      mTrueReceiveBuffer[MAX_BUFFER_SIZE];
00706         S32     mTrueReceiveSize;
00707 
00708         // Must be valid during decode
00709         
00710         BOOL    mbError;
00711         S32     mErrorCode;
00712 
00713         F64                                                                             mResendDumpTime; // The last time we dumped resends
00714 
00715         LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM];
00716         S32 mNumMessageCounts;
00717         F32 mReceiveTime;
00718         F32 mMaxMessageTime; // Max number of seconds for processing messages
00719         S32 mMaxMessageCounts; // Max number of messages to process before dumping.
00720         F64 mMessageCountTime;
00721 
00722         F64 mCurrentMessageTimeSeconds; // The current "message system time" (updated the first call to checkMessages after a resetReceiveCount
00723 
00724         // message system exceptions
00725         typedef std::pair<msg_exception_callback, void*> exception_t;
00726         typedef std::map<EMessageException, exception_t> callbacks_t;
00727         callbacks_t mExceptionCallbacks;
00728 
00729         // stuff for logging
00730         LLTimer mMessageSystemTimer;
00731 
00732         static F32 mTimeDecodesSpamThreshold;  // If mTimeDecodes is on, all this many seconds for each msg decode before spamming
00733         static BOOL mTimeDecodes;  // Measure time for all message decodes if TRUE;
00734 
00735         msg_timing_callback mTimingCallback;
00736         void* mTimingCallbackData;
00737 
00738         void init(); // ctor shared initialisation.
00739 
00740         LLHost mLastSender;
00741         S32 mIncomingCompressedSize;            // original size of compressed msg (0 if uncomp.)
00742         TPACKETID mCurrentRecvPacketID;       // packet ID of current receive packet (for reporting)
00743 
00744         LLMessageBuilder* mMessageBuilder;
00745         LLTemplateMessageBuilder* mTemplateMessageBuilder;
00746         LLSDMessageBuilder* mLLSDMessageBuilder;
00747         LLMessageReader* mMessageReader;
00748         LLTemplateMessageReader* mTemplateMessageReader;
00749         LLSDMessageReader* mLLSDMessageReader;
00750 
00751         friend class LLMessageHandlerBridge;
00752         
00753         bool callHandler(const char *name, bool trustedSource,
00754                                          LLMessageSystem* msg);
00755 
00756 
00758         LLCircuitData* findCircuit(const LLHost& host, bool resetPacketId);
00759 };
00760 
00761 
00762 // external hook into messaging system
00763 extern LLMessageSystem  *gMessageSystem;
00764 
00765 // Must specific overall system version, which is used to determine
00766 // if a patch is available in the message template checksum verification.
00767 // Return TRUE if able to initialize system.
00768 BOOL start_messaging_system(
00769         const std::string& template_name,
00770         U32 port, 
00771         S32 version_major,
00772         S32 version_minor,
00773         S32 version_patch,
00774         BOOL b_dump_prehash_file,
00775         const std::string& secret,
00776         const LLUseCircuitCodeResponder* responder = NULL);
00777 
00778 void end_messaging_system();
00779 
00780 void null_message_callback(LLMessageSystem *msg, void **data);
00781 
00782 //
00783 // Inlines
00784 //
00785 
00786 #if !defined( LL_BIG_ENDIAN ) && !defined( LL_LITTLE_ENDIAN )
00787 #error Unknown endianness for htonmemcpy. Did you miss a common include?
00788 #endif
00789 
00790 static inline void *htonmemcpy(void *vs, const void *vct, EMsgVariableType type, size_t n)
00791 {
00792         char *s = (char *)vs;
00793         const char *ct = (const char *)vct;
00794 #ifdef LL_BIG_ENDIAN
00795         S32 i, length;
00796 #endif
00797         switch(type)
00798         {
00799         case MVT_FIXED:
00800         case MVT_VARIABLE:
00801         case MVT_U8:
00802         case MVT_S8:
00803         case MVT_BOOL:
00804         case MVT_LLUUID:
00805         case MVT_IP_ADDR:       // these two are swizzled in the getters and setters
00806         case MVT_IP_PORT:       // these two are swizzled in the getters and setters
00807                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00808 
00809         case MVT_U16:
00810         case MVT_S16:
00811                 if (n != 2)
00812                 {
00813                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00814                 }
00815 #ifdef LL_BIG_ENDIAN
00816                 *(s + 1) = *(ct);
00817                 *(s) = *(ct + 1);
00818                 return(vs);
00819 #else
00820                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00821 #endif
00822 
00823         case MVT_U32:
00824         case MVT_S32:
00825         case MVT_F32:
00826                 if (n != 4)
00827                 {
00828                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00829                 }
00830 #ifdef LL_BIG_ENDIAN
00831                 *(s + 3) = *(ct);
00832                 *(s + 2) = *(ct + 1);
00833                 *(s + 1) = *(ct + 2);
00834                 *(s) = *(ct + 3);
00835                 return(vs);
00836 #else
00837                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00838 #endif
00839 
00840         case MVT_U64:
00841         case MVT_S64:
00842         case MVT_F64:
00843                 if (n != 8)
00844                 {
00845                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00846                 }
00847 #ifdef LL_BIG_ENDIAN
00848                 *(s + 7) = *(ct);
00849                 *(s + 6) = *(ct + 1);
00850                 *(s + 5) = *(ct + 2);
00851                 *(s + 4) = *(ct + 3);
00852                 *(s + 3) = *(ct + 4);
00853                 *(s + 2) = *(ct + 5);
00854                 *(s + 1) = *(ct + 6);
00855                 *(s) = *(ct + 7);
00856                 return(vs);
00857 #else
00858                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00859 #endif
00860 
00861         case MVT_LLVector3:
00862         case MVT_LLQuaternion:  // We only send x, y, z and infer w (we set x, y, z to ensure that w >= 0)
00863                 if (n != 12)
00864                 {
00865                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00866                 }
00867 #ifdef LL_BIG_ENDIAN
00868                 htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
00869                 htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
00870                 return(htonmemcpy(s, ct, MVT_F32, 4));
00871 #else
00872                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00873 #endif
00874 
00875         case MVT_LLVector3d:
00876                 if (n != 24)
00877                 {
00878                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00879                 }
00880 #ifdef LL_BIG_ENDIAN
00881                 htonmemcpy(s + 16, ct + 16, MVT_F64, 8);
00882                 htonmemcpy(s + 8, ct + 8, MVT_F64, 8);
00883                 return(htonmemcpy(s, ct, MVT_F64, 8));
00884 #else
00885                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00886 #endif
00887 
00888         case MVT_LLVector4:
00889                 if (n != 16)
00890                 {
00891                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00892                 }
00893 #ifdef LL_BIG_ENDIAN
00894                 htonmemcpy(s + 12, ct + 12, MVT_F32, 4);
00895                 htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
00896                 htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
00897                 return(htonmemcpy(s, ct, MVT_F32, 4));
00898 #else
00899                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00900 #endif
00901 
00902         case MVT_U16Vec3:
00903                 if (n != 6)
00904                 {
00905                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00906                 }
00907 #ifdef LL_BIG_ENDIAN
00908                 htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
00909                 htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
00910                 return(htonmemcpy(s, ct, MVT_U16, 2));
00911 #else
00912                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00913 #endif
00914 
00915         case MVT_U16Quat:
00916                 if (n != 8)
00917                 {
00918                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00919                 }
00920 #ifdef LL_BIG_ENDIAN
00921                 htonmemcpy(s + 6, ct + 6, MVT_U16, 2);
00922                 htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
00923                 htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
00924                 return(htonmemcpy(s, ct, MVT_U16, 2));
00925 #else
00926                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00927 #endif
00928 
00929         case MVT_S16Array:
00930                 if (n % 2)
00931                 {
00932                         llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
00933                 }
00934 #ifdef LL_BIG_ENDIAN
00935                 length = n % 2;
00936                 for (i = 1; i < length; i++)
00937                 {
00938                         htonmemcpy(s + i*2, ct + i*2, MVT_S16, 2);
00939                 }
00940                 return(htonmemcpy(s, ct, MVT_S16, 2));
00941 #else
00942                 return(memcpy(s,ct,n));
00943 #endif
00944 
00945         default:
00946                 return(memcpy(s,ct,n)); /* Flawfinder: ignore */ 
00947         }
00948 }
00949 
00950 inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n)
00951 {
00952         return(htonmemcpy(s,ct,type, n));
00953 }
00954 
00955 
00956 inline const LLHost& LLMessageSystem::getSender() const {return mLastSender;}
00957 
00958 inline U32 LLMessageSystem::getSenderIP() const 
00959 {
00960         return mLastSender.getAddress();
00961 }
00962 
00963 inline U32 LLMessageSystem::getSenderPort() const
00964 {
00965         return mLastSender.getPort();
00966 }
00967 
00968 //-----------------------------------------------------------------------------
00969 // Transmission aliases
00970 //-----------------------------------------------------------------------------
00971 
00972 inline S32 LLMessageSystem::sendMessage(const U32 circuit)
00973 {
00974         return sendMessage(findHost(circuit));
00975 }
00976 
00977 #endif

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