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

Generated on Thu Jul 1 06:09:55 2010 for Second Life Viewer by  doxygen 1.4.7