message.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:39k
- /**
- * @file message.h
- * @brief LLMessageSystem class header file
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #ifndef LL_MESSAGE_H
- #define LL_MESSAGE_H
- #include <cstring>
- #include <set>
- #if LL_LINUX
- #include <endian.h>
- #include <netinet/in.h>
- #endif
- #if LL_SOLARIS
- #include <netinet/in.h>
- #endif
- #if LL_WINDOWS
- #include "winsock2.h" // htons etc.
- #endif
- #include "llerror.h"
- #include "net.h"
- #include "string_table.h"
- #include "llcircuit.h"
- #include "lltimer.h"
- #include "llpacketring.h"
- #include "llhost.h"
- #include "llhttpclient.h"
- #include "llhttpnode.h"
- #include "llpacketack.h"
- #include "llsingleton.h"
- #include "message_prehash.h"
- #include "llstl.h"
- #include "llmsgvariabletype.h"
- #include "llmessagesenderinterface.h"
- #include "llstoredmessage.h"
- const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
- const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
- const S32 MESSAGE_MAX_PER_FRAME = 400;
- class LLMessageStringTable : public LLSingleton<LLMessageStringTable>
- {
- public:
- LLMessageStringTable();
- ~LLMessageStringTable();
- char *getString(const char *str);
- U32 mUsed;
- BOOL mEmpty[MESSAGE_NUMBER_OF_HASH_BUCKETS];
- char mString[MESSAGE_NUMBER_OF_HASH_BUCKETS][MESSAGE_MAX_STRINGS_LENGTH]; /* Flawfinder: ignore */
- };
- // Individual Messages are described with the following format
- // Note that to ease parsing, keywords are used
- //
- // // Comment (Comment like a C++ single line comment)
- // Comments can only be placed between Messages
- // {
- // MessageName (same naming restrictions as C variable)
- // Frequency ("High", "Medium", or "Low" - determines whether message ID is 8, 16, or 32-bits --
- // there can 254 messages in the first 2 groups, 32K in the last group)
- // (A message can be made up only of the Name if it is only a signal)
- // Trust ("Trusted", "NotTrusted" - determines if a message will be accepted
- // on a circuit. "Trusted" messages are not accepted from NotTrusted circuits
- // while NotTrusted messages are accepted on any circuit. An example of a
- // NotTrusted circuit is any circuit from the viewer.)
- // Encoding ("Zerocoded", "Unencoded" - zerocoded messages attempt to compress sequences of
- // zeros, but if there is no space win, it discards the compression and goes unencoded)
- // {
- // Block Name (same naming restrictions as C variable)
- // Block Type ("Single", "Multiple", or "Variable" - determines if the block is coded once,
- // a known number of times, or has a 8 bit argument encoded to tell the decoder
- // how many times the group is repeated)
- // Block Repeat Number (Optional - used only with the "Multiple" type - tells how many times the field is repeated
- // {
- // Variable 1 Name (same naming restrictions as C variable)
- // Variable Type ("Fixed" or "Variable" - determines if the variable is of fixed size or needs to
- // encode an argument describing the size in bytes)
- // Variable Size (In bytes, either of the "Fixed" variable itself or of the size argument)
- //
- // repeat variables
- //
- // }
- //
- // Repeat for number of variables in block
- // }
- //
- // Repeat for number of blocks in message
- // }
- // Repeat for number of messages in file
- //
- // Constants
- const S32 MAX_MESSAGE_INTERNAL_NAME_SIZE = 255;
- const S32 MAX_BUFFER_SIZE = NET_BUFFER_SIZE;
- const S32 MAX_BLOCKS = 255;
- const U8 LL_ZERO_CODE_FLAG = 0x80;
- const U8 LL_RELIABLE_FLAG = 0x40;
- const U8 LL_RESENT_FLAG = 0x20;
- const U8 LL_ACK_FLAG = 0x10;
- // 1 byte flags, 4 bytes sequence, 1 byte offset + 1 byte message name (high)
- const S32 LL_MINIMUM_VALID_PACKET_SIZE = LL_PACKET_ID_SIZE + 1;
- enum EPacketHeaderLayout
- {
- PHL_FLAGS = 0,
- PHL_PACKET_ID = 1,
- PHL_OFFSET = 5,
- PHL_NAME = 6
- };
- const S32 LL_DEFAULT_RELIABLE_RETRIES = 3;
- const F32 LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS = 1.f;
- const F32 LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS = 1.f;
- const F32 LL_PING_BASED_TIMEOUT_DUMMY = 0.0f;
- // *NOTE: Maybe these factors shouldn't include the msec to sec conversion
- // implicitly.
- // However, all units should be MKS.
- const F32 LL_SEMIRELIABLE_TIMEOUT_FACTOR = 5.f / 1000.f; // factor * averaged ping
- const F32 LL_RELIABLE_TIMEOUT_FACTOR = 5.f / 1000.f; // factor * averaged ping
- const F32 LL_FILE_XFER_TIMEOUT_FACTOR = 5.f / 1000.f; // factor * averaged ping
- const F32 LL_LOST_TIMEOUT_FACTOR = 16.f / 1000.f; // factor * averaged ping for marking packets "Lost"
- const F32 LL_MAX_LOST_TIMEOUT = 5.f; // Maximum amount of time before considering something "lost"
- const S32 MAX_MESSAGE_COUNT_NUM = 1024;
- // Forward declarations
- class LLCircuit;
- class LLVector3;
- class LLVector4;
- class LLVector3d;
- class LLQuaternion;
- class LLSD;
- class LLUUID;
- class LLMessageSystem;
- class LLPumpIO;
- // message system exceptional condition handlers.
- enum EMessageException
- {
- MX_UNREGISTERED_MESSAGE, // message number not part of template
- MX_PACKET_TOO_SHORT, // invalid packet, shorter than minimum packet size
- MX_RAN_OFF_END_OF_PACKET, // ran off the end of the packet during decode
- MX_WROTE_PAST_BUFFER_SIZE // wrote past buffer size in zero code expand
- };
- typedef void (*msg_exception_callback)(LLMessageSystem*,void*,EMessageException);
- // message data pieces are used to collect the data called for by the message template
- class LLMsgData;
- class LLMsgBlkData;
- class LLMessageTemplate;
- class LLMessagePollInfo;
- class LLMessageBuilder;
- class LLTemplateMessageBuilder;
- class LLSDMessageBuilder;
- class LLMessageReader;
- class LLTemplateMessageReader;
- class LLSDMessageReader;
- class LLUseCircuitCodeResponder
- {
- LOG_CLASS(LLMessageSystem);
-
- public:
- virtual ~LLUseCircuitCodeResponder();
- virtual void complete(const LLHost& host, const LLUUID& agent) const = 0;
- };
- class LLMessageSystem : public LLMessageSenderInterface
- {
- private:
- U8 mSendBuffer[MAX_BUFFER_SIZE];
- S32 mSendSize;
- bool mBlockUntrustedInterface;
- LLHost mUntrustedInterface;
- public:
- LLPacketRing mPacketRing;
- LLReliablePacketParams mReliablePacketParams;
- // Set this flag to TRUE when you want *very* verbose logs.
- BOOL mVerboseLog;
- F32 mMessageFileVersionNumber;
- typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t;
- typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
- private:
- message_template_name_map_t mMessageTemplates;
- message_template_number_map_t mMessageNumbers;
- public:
- S32 mSystemVersionMajor;
- S32 mSystemVersionMinor;
- S32 mSystemVersionPatch;
- S32 mSystemVersionServer;
- U32 mVersionFlags;
- BOOL mbProtected;
- U32 mNumberHighFreqMessages;
- U32 mNumberMediumFreqMessages;
- U32 mNumberLowFreqMessages;
- S32 mPort;
- S32 mSocket;
- U32 mPacketsIn; // total packets in, including compressed and uncompressed
- U32 mPacketsOut; // total packets out, including compressed and uncompressed
- U64 mBytesIn; // total bytes in, including compressed and uncompressed
- U64 mBytesOut; // total bytes out, including compressed and uncompressed
-
- U32 mCompressedPacketsIn; // total compressed packets in
- U32 mCompressedPacketsOut; // total compressed packets out
- U32 mReliablePacketsIn; // total reliable packets in
- U32 mReliablePacketsOut; // total reliable packets out
- U32 mDroppedPackets; // total dropped packets in
- U32 mResentPackets; // total resent packets out
- U32 mFailedResendPackets; // total resend failure packets out
- U32 mOffCircuitPackets; // total # of off-circuit packets rejected
- U32 mInvalidOnCircuitPackets; // total # of on-circuit but invalid packets rejected
- S64 mUncompressedBytesIn; // total uncompressed size of compressed packets in
- S64 mUncompressedBytesOut; // total uncompressed size of compressed packets out
- S64 mCompressedBytesIn; // total compressed size of compressed packets in
- S64 mCompressedBytesOut; // total compressed size of compressed packets out
- S64 mTotalBytesIn; // total size of all uncompressed packets in
- S64 mTotalBytesOut; // total size of all uncompressed packets out
- BOOL mSendReliable; // does the outgoing message require a pos ack?
- LLCircuit mCircuitInfo;
- F64 mCircuitPrintTime; // used to print circuit debug info every couple minutes
- F32 mCircuitPrintFreq; // seconds
- std::map<U64, U32> mIPPortToCircuitCode;
- std::map<U32, U64> mCircuitCodeToIPPort;
- U32 mOurCircuitCode;
- S32 mSendPacketFailureCount;
- S32 mUnackedListDepth;
- S32 mUnackedListSize;
- S32 mDSMaxListDepth;
- public:
- // Read file and build message templates
- LLMessageSystem(const std::string& filename, U32 port, S32 version_major,
- S32 version_minor, S32 version_patch,
- bool failure_is_fatal,
- const F32 circuit_heartbeat_interval, const F32 circuit_timeout);
- ~LLMessageSystem();
- BOOL isOK() const { return !mbError; }
- S32 getErrorCode() const { return mErrorCode; }
- // Read file and build message templates filename must point to a
- // valid string which specifies the path of a valid linden
- // template.
- void loadTemplateFile(const std::string& filename, bool failure_is_fatal);
- // methods for building, sending, receiving, and handling messages
- void setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL);
- void setHandlerFunc(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL)
- {
- setHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data);
- }
- // Set a callback function for a message system exception.
- void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL);
- // Call the specified exception func, and return TRUE if a
- // function was found and called. Otherwise return FALSE.
- BOOL callExceptionFunc(EMessageException exception);
- // Set a function that will be called once per packet processed with the
- // hashed message name and the time spent in the processing handler function
- // measured in seconds. JC
- typedef void (*msg_timing_callback)(const char* hashed_name, F32 time, void* data);
- void setTimingFunc(msg_timing_callback func, void* data = NULL);
- msg_timing_callback getTimingCallback()
- {
- return mTimingCallback;
- }
- void* getTimingCallbackData()
- {
- return mTimingCallbackData;
- }
- // This method returns true if the code is in the circuit codes map.
- BOOL isCircuitCodeKnown(U32 code) const;
- // usually called in response to an AddCircuitCode message, but
- // may also be called by the login process.
- bool addCircuitCode(U32 code, const LLUUID& session_id);
- BOOL poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received
- BOOL checkMessages( S64 frame_count = 0 );
- void processAcks();
- BOOL isMessageFast(const char *msg);
- BOOL isMessage(const char *msg)
- {
- return isMessageFast(LLMessageStringTable::getInstance()->getString(msg));
- }
- void dumpPacketToLog();
- char *getMessageName();
- const LLHost& getSender() const;
- U32 getSenderIP() const; // getSender() is preferred
- U32 getSenderPort() const; // getSender() is preferred
- const LLHost& getReceivingInterface() const;
- // This method returns the uuid associated with the sender. The
- // UUID will be null if it is not yet known or is a server
- // circuit.
- const LLUUID& getSenderID() const;
- // This method returns the session id associated with the last
- // sender.
- const LLUUID& getSenderSessionID() const;
- // set & get the session id (useful for viewers for now.)
- void setMySessionID(const LLUUID& session_id) { mSessionID = session_id; }
- const LLUUID& getMySessionID() { return mSessionID; }
- void newMessageFast(const char *name);
- void newMessage(const char *name);
- public:
- LLStoredMessagePtr getReceivedMessage() const;
- LLStoredMessagePtr getBuiltMessage() const;
- S32 sendMessage(const LLHost &host, LLStoredMessagePtr message);
- private:
- LLSD getReceivedMessageLLSD() const;
- LLSD getBuiltMessageLLSD() const;
- // NOTE: babbage: Only use to support legacy misuse of the
- // LLMessageSystem API where values are dangerously written
- // as one type and read as another. LLSD does not support
- // dangerous conversions and so converting the message to an
- // LLSD would result in the reads failing. All code which
- // misuses the message system in this way should be made safe
- // but while the unsafe code is run in old processes, this
- // method should be used to forward unsafe messages.
- LLSD wrapReceivedTemplateData() const;
- LLSD wrapBuiltTemplateData() const;
- public:
- void copyMessageReceivedToSend();
- void clearMessage();
- void nextBlockFast(const char *blockname);
- void nextBlock(const char *blockname);
- public:
- void addBinaryDataFast(const char *varname, const void *data, S32 size);
- void addBinaryData(const char *varname, const void *data, S32 size);
- void addBOOLFast( const char* varname, BOOL b); // typed, checks storage space
- void addBOOL( const char* varname, BOOL b); // typed, checks storage space
- void addS8Fast( const char *varname, S8 s); // typed, checks storage space
- void addS8( const char *varname, S8 s); // typed, checks storage space
- void addU8Fast( const char *varname, U8 u); // typed, checks storage space
- void addU8( const char *varname, U8 u); // typed, checks storage space
- void addS16Fast( const char *varname, S16 i); // typed, checks storage space
- void addS16( const char *varname, S16 i); // typed, checks storage space
- void addU16Fast( const char *varname, U16 i); // typed, checks storage space
- void addU16( const char *varname, U16 i); // typed, checks storage space
- void addF32Fast( const char *varname, F32 f); // typed, checks storage space
- void addF32( const char *varname, F32 f); // typed, checks storage space
- void addS32Fast( const char *varname, S32 s); // typed, checks storage space
- void addS32( const char *varname, S32 s); // typed, checks storage space
- void addU32Fast( const char *varname, U32 u); // typed, checks storage space
- void addU32( const char *varname, U32 u); // typed, checks storage space
- void addU64Fast( const char *varname, U64 lu); // typed, checks storage space
- void addU64( const char *varname, U64 lu); // typed, checks storage space
- void addF64Fast( const char *varname, F64 d); // typed, checks storage space
- void addF64( const char *varname, F64 d); // typed, checks storage space
- void addVector3Fast( const char *varname, const LLVector3& vec); // typed, checks storage space
- void addVector3( const char *varname, const LLVector3& vec); // typed, checks storage space
- void addVector4Fast( const char *varname, const LLVector4& vec); // typed, checks storage space
- void addVector4( const char *varname, const LLVector4& vec); // typed, checks storage space
- void addVector3dFast( const char *varname, const LLVector3d& vec); // typed, checks storage space
- void addVector3d( const char *varname, const LLVector3d& vec); // typed, checks storage space
- void addQuatFast( const char *varname, const LLQuaternion& quat); // typed, checks storage space
- void addQuat( const char *varname, const LLQuaternion& quat); // typed, checks storage space
- void addUUIDFast( const char *varname, const LLUUID& uuid); // typed, checks storage space
- void addUUID( const char *varname, const LLUUID& uuid); // typed, checks storage space
- void addIPAddrFast( const char *varname, const U32 ip); // typed, checks storage space
- void addIPAddr( const char *varname, const U32 ip); // typed, checks storage space
- void addIPPortFast( const char *varname, const U16 port); // typed, checks storage space
- void addIPPort( const char *varname, const U16 port); // typed, checks storage space
- void addStringFast( const char* varname, const char* s); // typed, checks storage space
- void addString( const char* varname, const char* s); // typed, checks storage space
- void addStringFast( const char* varname, const std::string& s); // typed, checks storage space
- void addString( const char* varname, const std::string& s); // typed, checks storage space
- S32 getCurrentSendTotal() const;
- TPACKETID getCurrentRecvPacketID() { return mCurrentRecvPacketID; }
- // This method checks for current send total and returns true if
- // you need to go to the next block type or need to start a new
- // message. Specify the current blockname to check block counts,
- // otherwise the method only checks against MTU.
- BOOL isSendFull(const char* blockname = NULL);
- BOOL isSendFullFast(const char* blockname = NULL);
- BOOL removeLastBlock();
- //void buildMessage();
- S32 zeroCode(U8 **data, S32 *data_size);
- S32 zeroCodeExpand(U8 **data, S32 *data_size);
- S32 zeroCodeAdjustCurrentSendTotal();
- // Uses ping-based retry
- S32 sendReliable(const LLHost &host);
- // Uses ping-based retry
- S32 sendReliable(const U32 circuit) { return sendReliable(findHost(circuit)); }
- // Use this one if you DON'T want automatic ping-based retry.
- S32 sendReliable( const LLHost &host,
- S32 retries,
- BOOL ping_based_retries,
- F32 timeout,
- void (*callback)(void **,S32),
- void ** callback_data);
- S32 sendSemiReliable( const LLHost &host,
- void (*callback)(void **,S32), void ** callback_data);
- // flush sends a message only if data's been pushed on it.
- S32 flushSemiReliable( const LLHost &host,
- void (*callback)(void **,S32), void ** callback_data);
- S32 flushReliable( const LLHost &host );
- void forwardMessage(const LLHost &host);
- void forwardReliable(const LLHost &host);
- void forwardReliable(const U32 circuit_code);
- S32 forwardReliable(
- const LLHost &host,
- S32 retries,
- BOOL ping_based_timeout,
- F32 timeout,
- void (*callback)(void **,S32),
- void ** callback_data);
- LLHTTPClient::ResponderPtr createResponder(const std::string& name);
- S32 sendMessage(const LLHost &host);
- S32 sendMessage(const U32 circuit);
- private:
- S32 sendMessage(const LLHost &host, const char* name,
- const LLSD& message);
- public:
- // BOOL decodeData(const U8 *buffer, const LLHost &host);
- /**
- gets binary data from the current message.
-
- @param blockname the name of the block in the message (from the message template)
- @param varname
- @param datap
-
- @param size expected size - set to zero to get any amount of data up to max_size.
- Make sure max_size is set in that case!
- @param blocknum
- @param max_size the max number of bytes to read
- */
- void getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
- void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
- void getBOOLFast( const char *block, const char *var, BOOL &data, S32 blocknum = 0);
- void getBOOL( const char *block, const char *var, BOOL &data, S32 blocknum = 0);
- void getS8Fast( const char *block, const char *var, S8 &data, S32 blocknum = 0);
- void getS8( const char *block, const char *var, S8 &data, S32 blocknum = 0);
- void getU8Fast( const char *block, const char *var, U8 &data, S32 blocknum = 0);
- void getU8( const char *block, const char *var, U8 &data, S32 blocknum = 0);
- void getS16Fast( const char *block, const char *var, S16 &data, S32 blocknum = 0);
- void getS16( const char *block, const char *var, S16 &data, S32 blocknum = 0);
- void getU16Fast( const char *block, const char *var, U16 &data, S32 blocknum = 0);
- void getU16( const char *block, const char *var, U16 &data, S32 blocknum = 0);
- void getS32Fast( const char *block, const char *var, S32 &data, S32 blocknum = 0);
- void getS32( const char *block, const char *var, S32 &data, S32 blocknum = 0);
- void getF32Fast( const char *block, const char *var, F32 &data, S32 blocknum = 0);
- void getF32( const char *block, const char *var, F32 &data, S32 blocknum = 0);
- void getU32Fast( const char *block, const char *var, U32 &data, S32 blocknum = 0);
- void getU32( const char *block, const char *var, U32 &data, S32 blocknum = 0);
- void getU64Fast( const char *block, const char *var, U64 &data, S32 blocknum = 0);
- void getU64( const char *block, const char *var, U64 &data, S32 blocknum = 0);
- void getF64Fast( const char *block, const char *var, F64 &data, S32 blocknum = 0);
- void getF64( const char *block, const char *var, F64 &data, S32 blocknum = 0);
- void getVector3Fast( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0);
- void getVector3( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0);
- void getVector4Fast( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0);
- void getVector4( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0);
- void getVector3dFast(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
- void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
- void getQuatFast( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
- void getQuat( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
- void getUUIDFast( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
- void getUUID( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
- void getIPAddrFast( const char *block, const char *var, U32 &ip, S32 blocknum = 0);
- void getIPAddr( const char *block, const char *var, U32 &ip, S32 blocknum = 0);
- void getIPPortFast( const char *block, const char *var, U16 &port, S32 blocknum = 0);
- void getIPPort( const char *block, const char *var, U16 &port, S32 blocknum = 0);
- void getStringFast( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
- void getString( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
- void getStringFast( const char *block, const char *var, std::string& outstr, S32 blocknum = 0);
- void getString( const char *block, const char *var, std::string& outstr, S32 blocknum = 0);
- // Utility functions to generate a replay-resistant digest check
- // against the shared secret. The window specifies how much of a
- // time window is allowed - 1 second is good for tight
- // connections, but multi-process windows might want to be upwards
- // of 5 seconds. For generateDigest, you want to pass in a
- // character array of at least MD5HEX_STR_SIZE so that the hex
- // digest and null termination will fit.
- bool generateDigestForNumberAndUUIDs(char* digest, const U32 number, const LLUUID &id1, const LLUUID &id2) const;
- bool generateDigestForWindowAndUUIDs(char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const;
- bool isMatchingDigestForWindowAndUUIDs(const char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const;
- bool generateDigestForNumber(char* digest, const U32 number) const;
- bool generateDigestForWindow(char* digest, const S32 window) const;
- bool isMatchingDigestForWindow(const char* digest, const S32 window) const;
- void showCircuitInfo();
- void getCircuitInfo(LLSD& info) const;
- U32 getOurCircuitCode();
-
- void enableCircuit(const LLHost &host, BOOL trusted);
- void disableCircuit(const LLHost &host);
-
- // Use this to establish trust on startup and in response to
- // DenyTrustedCircuit.
- void sendCreateTrustedCircuit(const LLHost& host, const LLUUID & id1, const LLUUID & id2);
- // Use this to inform a peer that they aren't currently trusted...
- // This now enqueues the request so that we can ensure that we only send
- // one deny per circuit per message loop so that this doesn't become a DoS.
- // The actual sending is done by reallySendDenyTrustedCircuit()
- void sendDenyTrustedCircuit(const LLHost &host);
- /** Return false if host is unknown or untrusted */
- // Note:DaveH/Babbage some trusted messages can be received without a circuit
- bool isTrustedSender(const LLHost& host) const;
- /** Return true if current message is from trusted source */
- bool isTrustedSender() const;
- /** Return false true if name is unknown or untrusted */
- bool isTrustedMessage(const std::string& name) const;
- /** Return false true if name is unknown or trusted */
- bool isUntrustedMessage(const std::string& name) const;
- // Mark an interface ineligible for trust
- void setUntrustedInterface( const LLHost host ) { mUntrustedInterface = host; }
- LLHost getUntrustedInterface() const { return mUntrustedInterface; }
- void setBlockUntrustedInterface( bool block ) { mBlockUntrustedInterface = block; } // Throw a switch to allow, sending warnings only
- bool getBlockUntrustedInterface() const { return mBlockUntrustedInterface; }
- // Change this message to be UDP black listed.
- void banUdpMessage(const std::string& name);
- private:
- // A list of the circuits that need to be sent DenyTrustedCircuit messages.
- typedef std::set<LLHost> host_set_t;
- host_set_t mDenyTrustedCircuitSet;
- // Really sends the DenyTrustedCircuit message to a given host
- // related to sendDenyTrustedCircuit()
- void reallySendDenyTrustedCircuit(const LLHost &host);
- public:
- // Use this to establish trust to and from a host. This blocks
- // until trust has been established, and probably should only be
- // used on startup.
- void establishBidirectionalTrust(const LLHost &host, S64 frame_count = 0);
- // returns whether the given host is on a trusted circuit
- // Note:DaveH/Babbage some trusted messages can be received without a circuit
- BOOL getCircuitTrust(const LLHost &host);
-
- void setCircuitAllowTimeout(const LLHost &host, BOOL allow);
- void setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost &host, void *user_data), void *user_data);
- BOOL checkCircuitBlocked(const U32 circuit);
- BOOL checkCircuitAlive(const U32 circuit);
- BOOL checkCircuitAlive(const LLHost &host);
- void setCircuitProtection(BOOL b_protect);
- U32 findCircuitCode(const LLHost &host);
- LLHost findHost(const U32 circuit_code);
- void sanityCheck();
- BOOL has(const char *blockname) const;
- S32 getNumberOfBlocksFast(const char *blockname) const;
- S32 getNumberOfBlocks(const char *blockname) const;
- S32 getSizeFast(const char *blockname, const char *varname) const;
- S32 getSize(const char *blockname, const char *varname) const;
- S32 getSizeFast(const char *blockname, S32 blocknum,
- const char *varname) const; // size in bytes of data
- S32 getSize(const char *blockname, S32 blocknum, const char *varname) const;
- void resetReceiveCounts(); // resets receive counts for all message types to 0
- void dumpReceiveCounts(); // dumps receive count for each message type to llinfos
- void dumpCircuitInfo(); // Circuit information to llinfos
- BOOL isClear() const; // returns mbSClear;
- S32 flush(const LLHost &host);
- U32 getListenPort( void ) const;
- void startLogging(); // start verbose logging
- void stopLogging(); // flush and close file
- void summarizeLogs(std::ostream& str); // log statistics
- S32 getReceiveSize() const;
- S32 getReceiveCompressedSize() const { return mIncomingCompressedSize; }
- S32 getReceiveBytes() const;
- S32 getUnackedListSize() const { return mUnackedListSize; }
- //const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
- //const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
- // friends
- friend std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg);
- void setMaxMessageTime(const F32 seconds); // Max time to process messages before warning and dumping (neg to disable)
- void setMaxMessageCounts(const S32 num); // Max number of messages before dumping (neg to disable)
-
- static U64 getMessageTimeUsecs(const BOOL update = FALSE); // Get the current message system time in microseconds
- static F64 getMessageTimeSeconds(const BOOL update = FALSE); // Get the current message system time in seconds
- static void setTimeDecodes(BOOL b);
- static void setTimeDecodesSpamThreshold(F32 seconds);
- // message handlers internal to the message systesm
- //static void processAssignCircuitCode(LLMessageSystem* msg, void**);
- static void processAddCircuitCode(LLMessageSystem* msg, void**);
- static void processUseCircuitCode(LLMessageSystem* msg, void**);
- static void processError(LLMessageSystem* msg, void**);
- // dispatch llsd message to http node tree
- static void dispatch(const std::string& msg_name,
- const LLSD& message);
- static void dispatch(const std::string& msg_name,
- const LLSD& message,
- LLHTTPNode::ResponsePtr responsep);
- // this is added to support specific legacy messages and is
- // ***not intended for general use*** Si, Gabriel, 2009
- static void dispatchTemplate(const std::string& msg_name,
- const LLSD& message,
- LLHTTPNode::ResponsePtr responsep);
- void setMessageBans(const LLSD& trusted, const LLSD& untrusted);
- /**
- * @brief send an error message to the host. This is a helper method.
- *
- * @param host Destination host.
- * @param agent_id Destination agent id (may be null)
- * @param code An HTTP status compatible error code.
- * @param token A specific short string based message
- * @param id The transactionid/uniqueid/sessionid whatever.
- * @param system The hierarchical path to the system (255 bytes)
- * @param message Human readable message (1200 bytes)
- * @param data Extra info.
- * @return Returns value returned from sendReliable().
- */
- S32 sendError(
- const LLHost& host,
- const LLUUID& agent_id,
- S32 code,
- const std::string& token,
- const LLUUID& id,
- const std::string& system,
- const std::string& message,
- const LLSD& data);
- // Check UDP messages and pump http_pump to receive HTTP messages.
- bool checkAllMessages(S64 frame_count, LLPumpIO* http_pump);
- // Moved to allow access from LLTemplateMessageDispatcher
- void clearReceiveState();
- // This will cause all trust queries to return true until the next message
- // is read: use with caution!
- void receivedMessageFromTrustedSender();
-
- private:
- bool mLastMessageFromTrustedMessageService;
-
- // The mCircuitCodes is a map from circuit codes to session
- // ids. This allows us to verify sessions on connect.
- typedef std::map<U32, LLUUID> code_session_map_t;
- code_session_map_t mCircuitCodes;
- // Viewers need to track a process session in order to make sure
- // that no one gives them a bad circuit code.
- LLUUID mSessionID;
-
- void addTemplate(LLMessageTemplate *templatep);
- BOOL decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );
- void logMsgFromInvalidCircuit( const LLHost& sender, BOOL recv_reliable );
- void logTrustedMsgFromUntrustedCircuit( const LLHost& sender );
- void logValidMsg(LLCircuitData *cdp, const LLHost& sender, BOOL recv_reliable, BOOL recv_resent, BOOL recv_acks );
- void logRanOffEndOfPacket( const LLHost& sender );
- class LLMessageCountInfo
- {
- public:
- U32 mMessageNum;
- U32 mMessageBytes;
- BOOL mInvalid;
- };
- LLMessagePollInfo *mPollInfop;
- U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE];
- U8 mTrueReceiveBuffer[MAX_BUFFER_SIZE];
- S32 mTrueReceiveSize;
- // Must be valid during decode
-
- BOOL mbError;
- S32 mErrorCode;
- F64 mResendDumpTime; // The last time we dumped resends
- LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM];
- S32 mNumMessageCounts;
- F32 mReceiveTime;
- F32 mMaxMessageTime; // Max number of seconds for processing messages
- S32 mMaxMessageCounts; // Max number of messages to process before dumping.
- F64 mMessageCountTime;
- F64 mCurrentMessageTimeSeconds; // The current "message system time" (updated the first call to checkMessages after a resetReceiveCount
- // message system exceptions
- typedef std::pair<msg_exception_callback, void*> exception_t;
- typedef std::map<EMessageException, exception_t> callbacks_t;
- callbacks_t mExceptionCallbacks;
- // stuff for logging
- LLTimer mMessageSystemTimer;
- static F32 mTimeDecodesSpamThreshold; // If mTimeDecodes is on, all this many seconds for each msg decode before spamming
- static BOOL mTimeDecodes; // Measure time for all message decodes if TRUE;
- msg_timing_callback mTimingCallback;
- void* mTimingCallbackData;
- void init(); // ctor shared initialisation.
- LLHost mLastSender;
- LLHost mLastReceivingIF;
- S32 mIncomingCompressedSize; // original size of compressed msg (0 if uncomp.)
- TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting)
- LLMessageBuilder* mMessageBuilder;
- LLTemplateMessageBuilder* mTemplateMessageBuilder;
- LLSDMessageBuilder* mLLSDMessageBuilder;
- LLMessageReader* mMessageReader;
- LLTemplateMessageReader* mTemplateMessageReader;
- LLSDMessageReader* mLLSDMessageReader;
- friend class LLMessageHandlerBridge;
-
- bool callHandler(const char *name, bool trustedSource,
- LLMessageSystem* msg);
- /** Find, create or revive circuit for host as needed */
- LLCircuitData* findCircuit(const LLHost& host, bool resetPacketId);
- };
- // external hook into messaging system
- extern LLMessageSystem *gMessageSystem;
- // Must specific overall system version, which is used to determine
- // if a patch is available in the message template checksum verification.
- // Return true if able to initialize system.
- bool start_messaging_system(
- const std::string& template_name,
- U32 port,
- S32 version_major,
- S32 version_minor,
- S32 version_patch,
- bool b_dump_prehash_file,
- const std::string& secret,
- const LLUseCircuitCodeResponder* responder,
- bool failure_is_fatal,
- const F32 circuit_heartbeat_interval,
- const F32 circuit_timeout);
- void end_messaging_system(bool print_summary = true);
- void null_message_callback(LLMessageSystem *msg, void **data);
- //
- // Inlines
- //
- #if !defined( LL_BIG_ENDIAN ) && !defined( LL_LITTLE_ENDIAN )
- #error Unknown endianness for htonmemcpy. Did you miss a common include?
- #endif
- static inline void *htonmemcpy(void *vs, const void *vct, EMsgVariableType type, size_t n)
- {
- char *s = (char *)vs;
- const char *ct = (const char *)vct;
- #ifdef LL_BIG_ENDIAN
- S32 i, length;
- #endif
- switch(type)
- {
- case MVT_FIXED:
- case MVT_VARIABLE:
- case MVT_U8:
- case MVT_S8:
- case MVT_BOOL:
- case MVT_LLUUID:
- case MVT_IP_ADDR: // these two are swizzled in the getters and setters
- case MVT_IP_PORT: // these two are swizzled in the getters and setters
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- case MVT_U16:
- case MVT_S16:
- if (n != 2)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- *(s + 1) = *(ct);
- *(s) = *(ct + 1);
- return(vs);
- #else
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- #endif
- case MVT_U32:
- case MVT_S32:
- case MVT_F32:
- if (n != 4)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- *(s + 3) = *(ct);
- *(s + 2) = *(ct + 1);
- *(s + 1) = *(ct + 2);
- *(s) = *(ct + 3);
- return(vs);
- #else
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- #endif
- case MVT_U64:
- case MVT_S64:
- case MVT_F64:
- if (n != 8)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- *(s + 7) = *(ct);
- *(s + 6) = *(ct + 1);
- *(s + 5) = *(ct + 2);
- *(s + 4) = *(ct + 3);
- *(s + 3) = *(ct + 4);
- *(s + 2) = *(ct + 5);
- *(s + 1) = *(ct + 6);
- *(s) = *(ct + 7);
- return(vs);
- #else
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- #endif
- case MVT_LLVector3:
- case MVT_LLQuaternion: // We only send x, y, z and infer w (we set x, y, z to ensure that w >= 0)
- if (n != 12)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
- htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
- return(htonmemcpy(s, ct, MVT_F32, 4));
- #else
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- #endif
- case MVT_LLVector3d:
- if (n != 24)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- htonmemcpy(s + 16, ct + 16, MVT_F64, 8);
- htonmemcpy(s + 8, ct + 8, MVT_F64, 8);
- return(htonmemcpy(s, ct, MVT_F64, 8));
- #else
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- #endif
- case MVT_LLVector4:
- if (n != 16)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- htonmemcpy(s + 12, ct + 12, MVT_F32, 4);
- htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
- htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
- return(htonmemcpy(s, ct, MVT_F32, 4));
- #else
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- #endif
- case MVT_U16Vec3:
- if (n != 6)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
- htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
- return(htonmemcpy(s, ct, MVT_U16, 2));
- #else
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- #endif
- case MVT_U16Quat:
- if (n != 8)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- htonmemcpy(s + 6, ct + 6, MVT_U16, 2);
- htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
- htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
- return(htonmemcpy(s, ct, MVT_U16, 2));
- #else
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- #endif
- case MVT_S16Array:
- if (n % 2)
- {
- llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
- }
- #ifdef LL_BIG_ENDIAN
- length = n % 2;
- for (i = 1; i < length; i++)
- {
- htonmemcpy(s + i*2, ct + i*2, MVT_S16, 2);
- }
- return(htonmemcpy(s, ct, MVT_S16, 2));
- #else
- return(memcpy(s,ct,n));
- #endif
- default:
- return(memcpy(s,ct,n)); /* Flawfinder: ignore */
- }
- }
- inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n)
- {
- return(htonmemcpy(s,ct,type, n));
- }
- inline const LLHost& LLMessageSystem::getReceivingInterface() const {return mLastReceivingIF;}
- inline U32 LLMessageSystem::getSenderIP() const
- {
- return mLastSender.getAddress();
- }
- inline U32 LLMessageSystem::getSenderPort() const
- {
- return mLastSender.getPort();
- }
- //-----------------------------------------------------------------------------
- // Transmission aliases
- //-----------------------------------------------------------------------------
- inline S32 LLMessageSystem::sendMessage(const U32 circuit)
- {
- return sendMessage(findHost(circuit));
- }
- #endif