PageRenderTime 72ms CodeModel.GetById 11ms app.highlight 52ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llmessage/message.h

https://bitbucket.org/lindenlab/viewer-beta/
C++ Header | 1055 lines | 673 code | 184 blank | 198 comment | 20 complexity | e65720b5f26239bd090faf059646f40b MD5 | raw file
   1/** 
   2 * @file message.h
   3 * @brief LLMessageSystem class header file
   4 *
   5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#ifndef LL_MESSAGE_H
  28#define LL_MESSAGE_H
  29
  30#include <cstring>
  31#include <set>
  32
  33#if LL_LINUX
  34#include <endian.h>
  35#include <netinet/in.h>
  36#endif
  37
  38#if LL_SOLARIS
  39#include <netinet/in.h>
  40#endif
  41
  42#if LL_WINDOWS
  43#include "winsock2.h" // htons etc.
  44#endif
  45
  46#include "llerror.h"
  47#include "net.h"
  48#include "string_table.h"
  49#include "llcircuit.h"
  50#include "lltimer.h"
  51#include "llpacketring.h"
  52#include "llhost.h"
  53#include "llhttpclient.h"
  54#include "llhttpnode.h"
  55#include "llpacketack.h"
  56#include "llsingleton.h"
  57#include "message_prehash.h"
  58#include "llstl.h"
  59#include "llmsgvariabletype.h"
  60#include "llmessagesenderinterface.h"
  61
  62#include "llstoredmessage.h"
  63
  64const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
  65const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
  66
  67const S32 MESSAGE_MAX_PER_FRAME = 400;
  68
  69class LLMessageStringTable : public LLSingleton<LLMessageStringTable>
  70{
  71public:
  72	LLMessageStringTable();
  73	~LLMessageStringTable();
  74
  75	char *getString(const char *str);
  76
  77	U32	 mUsed;
  78	BOOL mEmpty[MESSAGE_NUMBER_OF_HASH_BUCKETS];
  79	char mString[MESSAGE_NUMBER_OF_HASH_BUCKETS][MESSAGE_MAX_STRINGS_LENGTH];	/* Flawfinder: ignore */
  80};
  81
  82
  83// Individual Messages are described with the following format
  84// Note that to ease parsing, keywords are used
  85//
  86//	// Comment 					(Comment like a C++ single line comment)
  87//  							Comments can only be placed between Messages
  88// {
  89// MessageName					(same naming restrictions as C variable)
  90// Frequency					("High", "Medium", or "Low" - determines whether message ID is 8, 16, or 32-bits -- 
  91//								 there can 254 messages in the first 2 groups, 32K in the last group)
  92//								(A message can be made up only of the Name if it is only a signal)
  93// Trust						("Trusted", "NotTrusted" - determines if a message will be accepted
  94//								 on a circuit.  "Trusted" messages are not accepted from NotTrusted circuits
  95//								 while NotTrusted messages are accepted on any circuit.  An example of a
  96//								 NotTrusted circuit is any circuit from the viewer.)
  97// Encoding						("Zerocoded", "Unencoded" - zerocoded messages attempt to compress sequences of 
  98//								 zeros, but if there is no space win, it discards the compression and goes unencoded)
  99//		{
 100//		Block Name				(same naming restrictions as C variable)
 101//		Block Type				("Single", "Multiple", or "Variable" - determines if the block is coded once, 
 102//								 a known number of times, or has a 8 bit argument encoded to tell the decoder 
 103//								 how many times the group is repeated)
 104//		Block Repeat Number		(Optional - used only with the "Multiple" type - tells how many times the field is repeated
 105//			{
 106//			Variable 1 Name		(same naming restrictions as C variable)
 107//			Variable Type		("Fixed" or "Variable" - determines if the variable is of fixed size or needs to 
 108//								 encode an argument describing the size in bytes)
 109//			Variable Size		(In bytes, either of the "Fixed" variable itself or of the size argument)
 110//
 111//			repeat variables
 112//
 113//			}
 114//
 115//			Repeat for number of variables in block		
 116//		}
 117//
 118//		Repeat for number of blocks in message
 119// }
 120// Repeat for number of messages in file
 121//
 122
 123// Constants
 124const S32 MAX_MESSAGE_INTERNAL_NAME_SIZE = 255;
 125const S32 MAX_BUFFER_SIZE = NET_BUFFER_SIZE;
 126const S32 MAX_BLOCKS = 255;
 127
 128const U8 LL_ZERO_CODE_FLAG = 0x80;
 129const U8 LL_RELIABLE_FLAG = 0x40;
 130const U8 LL_RESENT_FLAG = 0x20;
 131const U8 LL_ACK_FLAG = 0x10;
 132
 133// 1 byte flags, 4 bytes sequence, 1 byte offset + 1 byte message name (high)
 134const S32 LL_MINIMUM_VALID_PACKET_SIZE = LL_PACKET_ID_SIZE + 1;
 135enum EPacketHeaderLayout
 136{
 137	PHL_FLAGS = 0,
 138	PHL_PACKET_ID = 1,
 139	PHL_OFFSET = 5,
 140	PHL_NAME = 6
 141};
 142
 143
 144const S32 LL_DEFAULT_RELIABLE_RETRIES = 3;
 145const F32 LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS = 1.f;
 146const F32 LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS = 1.f;
 147const F32 LL_PING_BASED_TIMEOUT_DUMMY = 0.0f;
 148
 149// *NOTE: Maybe these factors shouldn't include the msec to sec conversion
 150// implicitly.
 151// However, all units should be MKS.
 152const F32 LL_SEMIRELIABLE_TIMEOUT_FACTOR	= 5.f / 1000.f;		// factor * averaged ping
 153const F32 LL_RELIABLE_TIMEOUT_FACTOR		= 5.f / 1000.f;      // factor * averaged ping
 154const F32 LL_FILE_XFER_TIMEOUT_FACTOR		= 5.f / 1000.f;      // factor * averaged ping
 155const F32 LL_LOST_TIMEOUT_FACTOR			= 16.f / 1000.f;     // factor * averaged ping for marking packets "Lost"
 156const F32 LL_MAX_LOST_TIMEOUT				= 5.f;				// Maximum amount of time before considering something "lost"
 157
 158const S32 MAX_MESSAGE_COUNT_NUM = 1024;
 159
 160// Forward declarations
 161class LLCircuit;
 162class LLVector3;
 163class LLVector4;
 164class LLVector3d;
 165class LLQuaternion;
 166class LLSD;
 167class LLUUID;
 168class LLMessageSystem;
 169class LLPumpIO;
 170
 171// message system exceptional condition handlers.
 172enum EMessageException
 173{
 174	MX_UNREGISTERED_MESSAGE, // message number not part of template
 175	MX_PACKET_TOO_SHORT, // invalid packet, shorter than minimum packet size
 176	MX_RAN_OFF_END_OF_PACKET, // ran off the end of the packet during decode
 177	MX_WROTE_PAST_BUFFER_SIZE // wrote past buffer size in zero code expand
 178};
 179typedef void (*msg_exception_callback)(LLMessageSystem*,void*,EMessageException);
 180
 181
 182// message data pieces are used to collect the data called for by the message template
 183class LLMsgData;
 184class LLMsgBlkData;
 185class LLMessageTemplate;
 186
 187class LLMessagePollInfo;
 188class LLMessageBuilder;
 189class LLTemplateMessageBuilder;
 190class LLSDMessageBuilder;
 191class LLMessageReader;
 192class LLTemplateMessageReader;
 193class LLSDMessageReader;
 194
 195
 196
 197class LLUseCircuitCodeResponder
 198{
 199	LOG_CLASS(LLMessageSystem);
 200	
 201public:
 202	virtual ~LLUseCircuitCodeResponder();
 203	virtual void complete(const LLHost& host, const LLUUID& agent) const = 0;
 204};
 205
 206class LLMessageSystem : public LLMessageSenderInterface
 207{
 208 private:
 209	U8					mSendBuffer[MAX_BUFFER_SIZE];
 210	S32					mSendSize;
 211
 212	bool				mBlockUntrustedInterface;
 213	LLHost				mUntrustedInterface;
 214
 215 public:
 216	LLPacketRing				mPacketRing;
 217	LLReliablePacketParams			mReliablePacketParams;
 218
 219	// Set this flag to TRUE when you want *very* verbose logs.
 220	BOOL mVerboseLog;
 221
 222	F32                                     mMessageFileVersionNumber;
 223
 224	typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t;
 225	typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
 226
 227private:
 228	message_template_name_map_t		mMessageTemplates;
 229	message_template_number_map_t		mMessageNumbers;
 230
 231public:
 232	S32					mSystemVersionMajor;
 233	S32					mSystemVersionMinor;
 234	S32					mSystemVersionPatch;
 235	S32					mSystemVersionServer;
 236	U32					mVersionFlags;
 237
 238	BOOL					mbProtected;
 239
 240	U32					mNumberHighFreqMessages;
 241	U32					mNumberMediumFreqMessages;
 242	U32					mNumberLowFreqMessages;
 243	S32					mPort;
 244	S32					mSocket;
 245
 246	U32					mPacketsIn;		    // total packets in, including compressed and uncompressed
 247	U32					mPacketsOut;		    // total packets out, including compressed and uncompressed
 248
 249	U64					mBytesIn;		    // total bytes in, including compressed and uncompressed
 250	U64					mBytesOut;		    // total bytes out, including compressed and uncompressed
 251	
 252	U32					mCompressedPacketsIn;	    // total compressed packets in
 253	U32					mCompressedPacketsOut;	    // total compressed packets out
 254
 255	U32					mReliablePacketsIn;	    // total reliable packets in
 256	U32					mReliablePacketsOut;	    // total reliable packets out
 257
 258	U32                                     mDroppedPackets;            // total dropped packets in
 259	U32                                     mResentPackets;             // total resent packets out
 260	U32                                     mFailedResendPackets;       // total resend failure packets out
 261	U32                                     mOffCircuitPackets;         // total # of off-circuit packets rejected
 262	U32                                     mInvalidOnCircuitPackets;   // total # of on-circuit but invalid packets rejected
 263
 264	S64					mUncompressedBytesIn;	    // total uncompressed size of compressed packets in
 265	S64					mUncompressedBytesOut;	    // total uncompressed size of compressed packets out
 266	S64					mCompressedBytesIn;	    // total compressed size of compressed packets in
 267	S64					mCompressedBytesOut;	    // total compressed size of compressed packets out
 268	S64					mTotalBytesIn;		    // total size of all uncompressed packets in
 269	S64					mTotalBytesOut;		    // total size of all uncompressed packets out
 270
 271	BOOL                                    mSendReliable;              // does the outgoing message require a pos ack?
 272
 273	LLCircuit 	 			mCircuitInfo;
 274	F64					mCircuitPrintTime;	    // used to print circuit debug info every couple minutes
 275	F32					mCircuitPrintFreq;	    // seconds
 276
 277	std::map<U64, U32>			mIPPortToCircuitCode;
 278	std::map<U32, U64>			mCircuitCodeToIPPort;
 279	U32					mOurCircuitCode;
 280	S32					mSendPacketFailureCount;
 281	S32					mUnackedListDepth;
 282	S32					mUnackedListSize;
 283	S32					mDSMaxListDepth;
 284
 285public:
 286	// Read file and build message templates
 287	LLMessageSystem(const std::string& filename, U32 port, S32 version_major,
 288					S32 version_minor, S32 version_patch,
 289					bool failure_is_fatal,
 290					const F32 circuit_heartbeat_interval, const F32 circuit_timeout);
 291
 292	~LLMessageSystem();
 293
 294	BOOL isOK() const { return !mbError; }
 295	S32 getErrorCode() const { return mErrorCode; }
 296
 297	// Read file and build message templates filename must point to a
 298	// valid string which specifies the path of a valid linden
 299	// template.
 300	void loadTemplateFile(const std::string& filename, bool failure_is_fatal);
 301
 302
 303	// methods for building, sending, receiving, and handling messages
 304	void	setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL);
 305	void	setHandlerFunc(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL)
 306	{
 307		setHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data);
 308	}
 309
 310	// Set a callback function for a message system exception.
 311	void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL);
 312	// Call the specified exception func, and return TRUE if a
 313	// function was found and called. Otherwise return FALSE.
 314	BOOL callExceptionFunc(EMessageException exception);
 315
 316	// Set a function that will be called once per packet processed with the 
 317	// hashed message name and the time spent in the processing handler function
 318	// measured in seconds.  JC
 319	typedef void (*msg_timing_callback)(const char* hashed_name, F32 time, void* data);
 320	void setTimingFunc(msg_timing_callback func, void* data = NULL);
 321	msg_timing_callback getTimingCallback() 
 322	{ 
 323		return mTimingCallback; 
 324	}
 325	void* getTimingCallbackData() 
 326	{
 327		return mTimingCallbackData;
 328	}
 329
 330	// This method returns true if the code is in the circuit codes map.
 331	BOOL isCircuitCodeKnown(U32 code) const;
 332
 333	// usually called in response to an AddCircuitCode message, but
 334	// may also be called by the login process.
 335	bool addCircuitCode(U32 code, const LLUUID& session_id);
 336
 337	BOOL	poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received
 338	BOOL	checkMessages( S64 frame_count = 0 );
 339	void	processAcks();
 340
 341	BOOL	isMessageFast(const char *msg);
 342	BOOL	isMessage(const char *msg)
 343	{
 344		return isMessageFast(LLMessageStringTable::getInstance()->getString(msg));
 345	}
 346
 347	void dumpPacketToLog();
 348
 349	char	*getMessageName();
 350
 351	const LLHost& getSender() const;
 352	U32		getSenderIP() const;			// getSender() is preferred
 353	U32		getSenderPort() const;		// getSender() is preferred
 354
 355	const LLHost& getReceivingInterface() const;
 356
 357	// This method returns the uuid associated with the sender. The
 358	// UUID will be null if it is not yet known or is a server
 359	// circuit.
 360	const LLUUID& getSenderID() const;
 361
 362	// This method returns the session id associated with the last
 363	// sender.
 364	const LLUUID& getSenderSessionID() const;
 365
 366	// set & get the session id (useful for viewers for now.)
 367	void setMySessionID(const LLUUID& session_id) { mSessionID = session_id; }
 368	const LLUUID& getMySessionID() { return mSessionID; }
 369
 370	void newMessageFast(const char *name);
 371	void newMessage(const char *name);
 372
 373
 374public:
 375	LLStoredMessagePtr getReceivedMessage() const; 
 376	LLStoredMessagePtr getBuiltMessage() const;
 377	S32 sendMessage(const LLHost &host, LLStoredMessagePtr message);
 378
 379private:
 380	LLSD getReceivedMessageLLSD() const;
 381	LLSD getBuiltMessageLLSD() const;
 382
 383	// NOTE: babbage: Only use to support legacy misuse of the
 384	// LLMessageSystem API where values are dangerously written
 385	// as one type and read as another. LLSD does not support
 386	// dangerous conversions and so converting the message to an
 387	// LLSD would result in the reads failing. All code which
 388	// misuses the message system in this way should be made safe
 389	// but while the unsafe code is run in old processes, this
 390	// method should be used to forward unsafe messages.
 391	LLSD wrapReceivedTemplateData() const;
 392	LLSD wrapBuiltTemplateData() const;
 393
 394public:
 395
 396	void copyMessageReceivedToSend();
 397	void clearMessage();
 398
 399	void nextBlockFast(const char *blockname);
 400	void nextBlock(const char *blockname);
 401
 402public:
 403	void addBinaryDataFast(const char *varname, const void *data, S32 size);
 404	void addBinaryData(const char *varname, const void *data, S32 size);
 405
 406	void	addBOOLFast( const char* varname, BOOL b);						// typed, checks storage space
 407	void	addBOOL( const char* varname, BOOL b);						// typed, checks storage space
 408	void	addS8Fast(	const char *varname, S8 s);							// typed, checks storage space
 409	void	addS8(	const char *varname, S8 s);							// typed, checks storage space
 410	void	addU8Fast(	const char *varname, U8 u);							// typed, checks storage space
 411	void	addU8(	const char *varname, U8 u);							// typed, checks storage space
 412	void	addS16Fast(	const char *varname, S16 i);						// typed, checks storage space
 413	void	addS16(	const char *varname, S16 i);						// typed, checks storage space
 414	void	addU16Fast(	const char *varname, U16 i);						// typed, checks storage space
 415	void	addU16(	const char *varname, U16 i);						// typed, checks storage space
 416	void	addF32Fast(	const char *varname, F32 f);						// typed, checks storage space
 417	void	addF32(	const char *varname, F32 f);						// typed, checks storage space
 418	void	addS32Fast(	const char *varname, S32 s);						// typed, checks storage space
 419	void	addS32(	const char *varname, S32 s);						// typed, checks storage space
 420	void addU32Fast(	const char *varname, U32 u);						// typed, checks storage space
 421	void	addU32(	const char *varname, U32 u);						// typed, checks storage space
 422	void	addU64Fast(	const char *varname, U64 lu);						// typed, checks storage space
 423	void	addU64(	const char *varname, U64 lu);						// typed, checks storage space
 424	void	addF64Fast(	const char *varname, F64 d);						// typed, checks storage space
 425	void	addF64(	const char *varname, F64 d);						// typed, checks storage space
 426	void	addVector3Fast(	const char *varname, const LLVector3& vec);		// typed, checks storage space
 427	void	addVector3(	const char *varname, const LLVector3& vec);		// typed, checks storage space
 428	void	addVector4Fast(	const char *varname, const LLVector4& vec);		// typed, checks storage space
 429	void	addVector4(	const char *varname, const LLVector4& vec);		// typed, checks storage space
 430	void	addVector3dFast( const char *varname, const LLVector3d& vec);	// typed, checks storage space
 431	void	addVector3d( const char *varname, const LLVector3d& vec);	// typed, checks storage space
 432	void	addQuatFast( const char *varname, const LLQuaternion& quat);	// typed, checks storage space
 433	void	addQuat( const char *varname, const LLQuaternion& quat);	// typed, checks storage space
 434	void addUUIDFast( const char *varname, const LLUUID& uuid);			// typed, checks storage space
 435	void	addUUID( const char *varname, const LLUUID& uuid);			// typed, checks storage space
 436	void	addIPAddrFast( const char *varname, const U32 ip);			// typed, checks storage space
 437	void	addIPAddr( const char *varname, const U32 ip);			// typed, checks storage space
 438	void	addIPPortFast( const char *varname, const U16 port);			// typed, checks storage space
 439	void	addIPPort( const char *varname, const U16 port);			// typed, checks storage space
 440	void	addStringFast( const char* varname, const char* s);				// typed, checks storage space
 441	void	addString( const char* varname, const char* s);				// typed, checks storage space
 442	void	addStringFast( const char* varname, const std::string& s);				// typed, checks storage space
 443	void	addString( const char* varname, const std::string& s);				// typed, checks storage space
 444
 445	S32 getCurrentSendTotal() const;
 446	TPACKETID getCurrentRecvPacketID() { return mCurrentRecvPacketID; }
 447
 448	// This method checks for current send total and returns true if
 449	// you need to go to the next block type or need to start a new
 450	// message. Specify the current blockname to check block counts,
 451	// otherwise the method only checks against MTU.
 452	BOOL isSendFull(const char* blockname = NULL);
 453	BOOL isSendFullFast(const char* blockname = NULL);
 454
 455	BOOL removeLastBlock();
 456
 457	//void	buildMessage();
 458
 459	S32     zeroCode(U8 **data, S32 *data_size);
 460	S32		zeroCodeExpand(U8 **data, S32 *data_size);
 461	S32		zeroCodeAdjustCurrentSendTotal();
 462
 463	// Uses ping-based retry
 464	S32 sendReliable(const LLHost &host);
 465
 466	// Uses ping-based retry
 467	S32	sendReliable(const U32 circuit)			{ return sendReliable(findHost(circuit)); }
 468
 469	// Use this one if you DON'T want automatic ping-based retry.
 470	S32	sendReliable(	const LLHost &host, 
 471							S32 retries, 
 472							BOOL ping_based_retries,
 473							F32 timeout, 
 474							void (*callback)(void **,S32), 
 475							void ** callback_data);
 476
 477	S32 sendSemiReliable(	const LLHost &host, 
 478							void (*callback)(void **,S32), void ** callback_data);
 479
 480	// flush sends a message only if data's been pushed on it.
 481	S32	 flushSemiReliable(	const LLHost &host, 
 482								void (*callback)(void **,S32), void ** callback_data);
 483
 484	S32	flushReliable(	const LLHost &host );
 485
 486	void forwardMessage(const LLHost &host);
 487	void forwardReliable(const LLHost &host);
 488	void forwardReliable(const U32 circuit_code);
 489	S32 forwardReliable(
 490		const LLHost &host, 
 491		S32 retries, 
 492		BOOL ping_based_timeout,
 493		F32 timeout, 
 494		void (*callback)(void **,S32), 
 495		void ** callback_data);
 496
 497	LLHTTPClient::ResponderPtr createResponder(const std::string& name);
 498	S32		sendMessage(const LLHost &host);
 499	S32		sendMessage(const U32 circuit);
 500private:
 501	S32		sendMessage(const LLHost &host, const char* name,
 502						const LLSD& message);
 503public:
 504	// BOOL	decodeData(const U8 *buffer, const LLHost &host);
 505
 506	/**
 507	gets binary data from the current message.
 508	
 509	@param blockname the name of the block in the message (from the message template)
 510
 511	@param varname 
 512
 513	@param datap
 514	
 515	@param size expected size - set to zero to get any amount of data up to max_size.
 516	Make sure max_size is set in that case!
 517
 518	@param blocknum
 519
 520	@param max_size the max number of bytes to read
 521	*/
 522	void	getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
 523	void	getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);
 524	void	getBOOLFast(	const char *block, const char *var, BOOL &data, S32 blocknum = 0);
 525	void	getBOOL(	const char *block, const char *var, BOOL &data, S32 blocknum = 0);
 526	void	getS8Fast(		const char *block, const char *var, S8 &data, S32 blocknum = 0);
 527	void	getS8(		const char *block, const char *var, S8 &data, S32 blocknum = 0);
 528	void	getU8Fast(		const char *block, const char *var, U8 &data, S32 blocknum = 0);
 529	void	getU8(		const char *block, const char *var, U8 &data, S32 blocknum = 0);
 530	void	getS16Fast(		const char *block, const char *var, S16 &data, S32 blocknum = 0);
 531	void	getS16(		const char *block, const char *var, S16 &data, S32 blocknum = 0);
 532	void	getU16Fast(		const char *block, const char *var, U16 &data, S32 blocknum = 0);
 533	void	getU16(		const char *block, const char *var, U16 &data, S32 blocknum = 0);
 534	void	getS32Fast(		const char *block, const char *var, S32 &data, S32 blocknum = 0);
 535	void	getS32(		const char *block, const char *var, S32 &data, S32 blocknum = 0);
 536	void	getF32Fast(		const char *block, const char *var, F32 &data, S32 blocknum = 0);
 537	void	getF32(		const char *block, const char *var, F32 &data, S32 blocknum = 0);
 538	void getU32Fast(		const char *block, const char *var, U32 &data, S32 blocknum = 0);
 539	void	getU32(		const char *block, const char *var, U32 &data, S32 blocknum = 0);
 540	void getU64Fast(		const char *block, const char *var, U64 &data, S32 blocknum = 0);
 541	void	getU64(		const char *block, const char *var, U64 &data, S32 blocknum = 0);
 542	void	getF64Fast(		const char *block, const char *var, F64 &data, S32 blocknum = 0);
 543	void	getF64(		const char *block, const char *var, F64 &data, S32 blocknum = 0);
 544	void	getVector3Fast(	const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0);
 545	void	getVector3(	const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0);
 546	void	getVector4Fast(	const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0);
 547	void	getVector4(	const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0);
 548	void	getVector3dFast(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
 549	void	getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
 550	void	getQuatFast(	const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
 551	void	getQuat(	const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
 552	void getUUIDFast(	const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
 553	void	getUUID(	const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
 554	void getIPAddrFast(	const char *block, const char *var, U32 &ip, S32 blocknum = 0);
 555	void	getIPAddr(	const char *block, const char *var, U32 &ip, S32 blocknum = 0);
 556	void getIPPortFast(	const char *block, const char *var, U16 &port, S32 blocknum = 0);
 557	void	getIPPort(	const char *block, const char *var, U16 &port, S32 blocknum = 0);
 558	void getStringFast(	const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
 559	void	getString(	const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
 560	void getStringFast(	const char *block, const char *var, std::string& outstr, S32 blocknum = 0);
 561	void	getString(	const char *block, const char *var, std::string& outstr, S32 blocknum = 0);
 562
 563
 564	// Utility functions to generate a replay-resistant digest check
 565	// against the shared secret. The window specifies how much of a
 566	// time window is allowed - 1 second is good for tight
 567	// connections, but multi-process windows might want to be upwards
 568	// of 5 seconds. For generateDigest, you want to pass in a
 569	// character array of at least MD5HEX_STR_SIZE so that the hex
 570	// digest and null termination will fit.
 571	bool generateDigestForNumberAndUUIDs(char* digest, const U32 number, const LLUUID &id1, const LLUUID &id2) const;
 572	bool generateDigestForWindowAndUUIDs(char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const;
 573	bool isMatchingDigestForWindowAndUUIDs(const char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const;
 574
 575	bool generateDigestForNumber(char* digest, const U32 number) const;
 576	bool generateDigestForWindow(char* digest, const S32 window) const;
 577	bool isMatchingDigestForWindow(const char* digest, const S32 window) const;
 578
 579	void	showCircuitInfo();
 580	void getCircuitInfo(LLSD& info) const;
 581
 582	U32 getOurCircuitCode();
 583	
 584	void	enableCircuit(const LLHost &host, BOOL trusted);
 585	void	disableCircuit(const LLHost &host);
 586	
 587	// Use this to establish trust on startup and in response to
 588	// DenyTrustedCircuit.
 589	void sendCreateTrustedCircuit(const LLHost& host, const LLUUID & id1, const LLUUID & id2);
 590
 591	// Use this to inform a peer that they aren't currently trusted...
 592	// This now enqueues the request so that we can ensure that we only send
 593	// one deny per circuit per message loop so that this doesn't become a DoS.
 594	// The actual sending is done by reallySendDenyTrustedCircuit()
 595	void	sendDenyTrustedCircuit(const LLHost &host);
 596
 597	/** Return false if host is unknown or untrusted */
 598	// Note:DaveH/Babbage some trusted messages can be received without a circuit
 599	bool isTrustedSender(const LLHost& host) const;
 600
 601	/** Return true if current message is from trusted source */
 602	bool isTrustedSender() const;
 603
 604	/** Return false true if name is unknown or untrusted */
 605	bool isTrustedMessage(const std::string& name) const;
 606
 607	/** Return false true if name is unknown or trusted */
 608	bool isUntrustedMessage(const std::string& name) const;
 609
 610	// Mark an interface ineligible for trust
 611	void setUntrustedInterface( const LLHost host ) { mUntrustedInterface = host; }
 612	LLHost getUntrustedInterface() const { return mUntrustedInterface; }
 613	void setBlockUntrustedInterface( bool block ) { mBlockUntrustedInterface = block; } // Throw a switch to allow, sending warnings only
 614	bool getBlockUntrustedInterface() const { return mBlockUntrustedInterface; }
 615
 616	// Change this message to be UDP black listed.
 617	void banUdpMessage(const std::string& name);
 618
 619
 620private:
 621	// A list of the circuits that need to be sent DenyTrustedCircuit messages.
 622	typedef std::set<LLHost> host_set_t;
 623	host_set_t mDenyTrustedCircuitSet;
 624
 625	// Really sends the DenyTrustedCircuit message to a given host
 626	// related to sendDenyTrustedCircuit()
 627	void	reallySendDenyTrustedCircuit(const LLHost &host);
 628
 629public:
 630	// Use this to establish trust to and from a host.  This blocks
 631	// until trust has been established, and probably should only be
 632	// used on startup.
 633	void	establishBidirectionalTrust(const LLHost &host, S64 frame_count = 0);
 634
 635	// returns whether the given host is on a trusted circuit
 636	// Note:DaveH/Babbage some trusted messages can be received without a circuit
 637	BOOL    getCircuitTrust(const LLHost &host);
 638	
 639	void	setCircuitAllowTimeout(const LLHost &host, BOOL allow);
 640	void	setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost &host, void *user_data), void *user_data);
 641
 642	BOOL	checkCircuitBlocked(const U32 circuit);
 643	BOOL	checkCircuitAlive(const U32 circuit);
 644	BOOL	checkCircuitAlive(const LLHost &host);
 645	void	setCircuitProtection(BOOL b_protect);
 646	U32		findCircuitCode(const LLHost &host);
 647	LLHost	findHost(const U32 circuit_code);
 648	void	sanityCheck();
 649
 650	BOOL	has(const char *blockname) const;
 651	S32		getNumberOfBlocksFast(const char *blockname) const;
 652	S32		getNumberOfBlocks(const char *blockname) const;
 653	S32		getSizeFast(const char *blockname, const char *varname) const;
 654	S32		getSize(const char *blockname, const char *varname) const;
 655	S32		getSizeFast(const char *blockname, S32 blocknum, 
 656						const char *varname) const; // size in bytes of data
 657	S32		getSize(const char *blockname, S32 blocknum, const char *varname) const;
 658
 659	void	resetReceiveCounts();				// resets receive counts for all message types to 0
 660	void	dumpReceiveCounts();				// dumps receive count for each message type to llinfos
 661	void	dumpCircuitInfo();					// Circuit information to llinfos
 662
 663	BOOL	isClear() const;					// returns mbSClear;
 664	S32 	flush(const LLHost &host);
 665
 666	U32		getListenPort( void ) const;
 667
 668	void startLogging();					// start verbose  logging
 669	void stopLogging();						// flush and close file
 670	void summarizeLogs(std::ostream& str);	// log statistics
 671
 672	S32		getReceiveSize() const;
 673	S32		getReceiveCompressedSize() const { return mIncomingCompressedSize; }
 674	S32		getReceiveBytes() const;
 675
 676	S32		getUnackedListSize() const			{ return mUnackedListSize; }
 677
 678	//const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
 679	//const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
 680
 681	// friends
 682	friend std::ostream&	operator<<(std::ostream& s, LLMessageSystem &msg);
 683
 684	void setMaxMessageTime(const F32 seconds);	// Max time to process messages before warning and dumping (neg to disable)
 685	void setMaxMessageCounts(const S32 num);	// Max number of messages before dumping (neg to disable)
 686	
 687	static U64 getMessageTimeUsecs(const BOOL update = FALSE);	// Get the current message system time in microseconds
 688	static F64 getMessageTimeSeconds(const BOOL update = FALSE); // Get the current message system time in seconds
 689
 690	static void setTimeDecodes(BOOL b);
 691	static void setTimeDecodesSpamThreshold(F32 seconds); 
 692
 693	// message handlers internal to the message systesm
 694	//static void processAssignCircuitCode(LLMessageSystem* msg, void**);
 695	static void processAddCircuitCode(LLMessageSystem* msg, void**);
 696	static void processUseCircuitCode(LLMessageSystem* msg, void**);
 697	static void processError(LLMessageSystem* msg, void**);
 698
 699	// dispatch llsd message to http node tree
 700	static void dispatch(const std::string& msg_name,
 701						 const LLSD& message);
 702	static void dispatch(const std::string& msg_name,
 703						 const LLSD& message,
 704						 LLHTTPNode::ResponsePtr responsep);
 705
 706	// this is added to support specific legacy messages and is
 707	// ***not intended for general use*** Si, Gabriel, 2009
 708	static void dispatchTemplate(const std::string& msg_name,
 709						 const LLSD& message,
 710						 LLHTTPNode::ResponsePtr responsep);
 711
 712	void setMessageBans(const LLSD& trusted, const LLSD& untrusted);
 713
 714	/**
 715	 * @brief send an error message to the host. This is a helper method.
 716	 *
 717	 * @param host Destination host.
 718	 * @param agent_id Destination agent id (may be null)
 719	 * @param code An HTTP status compatible error code.
 720	 * @param token A specific short string based message
 721	 * @param id The transactionid/uniqueid/sessionid whatever.
 722	 * @param system The hierarchical path to the system (255 bytes)
 723	 * @param message Human readable message (1200 bytes) 
 724	 * @param data Extra info.
 725	 * @return Returns value returned from sendReliable().
 726	 */
 727	S32 sendError(
 728		const LLHost& host,
 729		const LLUUID& agent_id,
 730		S32 code,
 731		const std::string& token,
 732		const LLUUID& id,
 733		const std::string& system,
 734		const std::string& message,
 735		const LLSD& data);
 736
 737	// Check UDP messages and pump http_pump to receive HTTP messages.
 738	bool checkAllMessages(S64 frame_count, LLPumpIO* http_pump);
 739
 740	// Moved to allow access from LLTemplateMessageDispatcher
 741	void clearReceiveState();
 742
 743	// This will cause all trust queries to return true until the next message
 744	// is read: use with caution!
 745	void receivedMessageFromTrustedSender();
 746	
 747private:
 748
 749	bool mLastMessageFromTrustedMessageService;
 750	
 751	// The mCircuitCodes is a map from circuit codes to session
 752	// ids. This allows us to verify sessions on connect.
 753	typedef std::map<U32, LLUUID> code_session_map_t;
 754	code_session_map_t mCircuitCodes;
 755
 756	// Viewers need to track a process session in order to make sure
 757	// that no one gives them a bad circuit code.
 758	LLUUID mSessionID;
 759	
 760	void	addTemplate(LLMessageTemplate *templatep);
 761	BOOL		decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );
 762
 763	void		logMsgFromInvalidCircuit( const LLHost& sender, BOOL recv_reliable );
 764	void		logTrustedMsgFromUntrustedCircuit( const LLHost& sender );
 765	void		logValidMsg(LLCircuitData *cdp, const LLHost& sender, BOOL recv_reliable, BOOL recv_resent, BOOL recv_acks );
 766	void		logRanOffEndOfPacket( const LLHost& sender );
 767
 768	class LLMessageCountInfo
 769	{
 770	public:
 771		U32 mMessageNum;
 772		U32 mMessageBytes;
 773		BOOL mInvalid;
 774	};
 775
 776	LLMessagePollInfo						*mPollInfop;
 777
 778	U8	mEncodedRecvBuffer[MAX_BUFFER_SIZE];
 779	U8	mTrueReceiveBuffer[MAX_BUFFER_SIZE];
 780	S32	mTrueReceiveSize;
 781
 782	// Must be valid during decode
 783	
 784	BOOL	mbError;
 785	S32	mErrorCode;
 786
 787	F64										mResendDumpTime; // The last time we dumped resends
 788
 789	LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM];
 790	S32 mNumMessageCounts;
 791	F32 mReceiveTime;
 792	F32 mMaxMessageTime; // Max number of seconds for processing messages
 793	S32 mMaxMessageCounts; // Max number of messages to process before dumping.
 794	F64 mMessageCountTime;
 795
 796	F64 mCurrentMessageTimeSeconds; // The current "message system time" (updated the first call to checkMessages after a resetReceiveCount
 797
 798	// message system exceptions
 799	typedef std::pair<msg_exception_callback, void*> exception_t;
 800	typedef std::map<EMessageException, exception_t> callbacks_t;
 801	callbacks_t mExceptionCallbacks;
 802
 803	// stuff for logging
 804	LLTimer mMessageSystemTimer;
 805
 806	static F32 mTimeDecodesSpamThreshold;  // If mTimeDecodes is on, all this many seconds for each msg decode before spamming
 807	static BOOL mTimeDecodes;  // Measure time for all message decodes if TRUE;
 808
 809	msg_timing_callback mTimingCallback;
 810	void* mTimingCallbackData;
 811
 812	void init(); // ctor shared initialisation.
 813
 814	LLHost mLastSender;
 815	LLHost mLastReceivingIF;
 816	S32 mIncomingCompressedSize;		// original size of compressed msg (0 if uncomp.)
 817	TPACKETID mCurrentRecvPacketID;       // packet ID of current receive packet (for reporting)
 818
 819	LLMessageBuilder* mMessageBuilder;
 820	LLTemplateMessageBuilder* mTemplateMessageBuilder;
 821	LLSDMessageBuilder* mLLSDMessageBuilder;
 822	LLMessageReader* mMessageReader;
 823	LLTemplateMessageReader* mTemplateMessageReader;
 824	LLSDMessageReader* mLLSDMessageReader;
 825
 826	friend class LLMessageHandlerBridge;
 827	
 828	bool callHandler(const char *name, bool trustedSource,
 829					 LLMessageSystem* msg);
 830
 831
 832	/** Find, create or revive circuit for host as needed */
 833	LLCircuitData* findCircuit(const LLHost& host, bool resetPacketId);
 834};
 835
 836
 837// external hook into messaging system
 838extern LLMessageSystem	*gMessageSystem;
 839
 840// Must specific overall system version, which is used to determine
 841// if a patch is available in the message template checksum verification.
 842// Return true if able to initialize system.
 843bool start_messaging_system(
 844	const std::string& template_name,
 845	U32 port, 
 846	S32 version_major,
 847	S32 version_minor,
 848	S32 version_patch,
 849	bool b_dump_prehash_file,
 850	const std::string& secret,
 851	const LLUseCircuitCodeResponder* responder,
 852	bool failure_is_fatal,
 853	const F32 circuit_heartbeat_interval, 
 854	const F32 circuit_timeout);
 855
 856void end_messaging_system(bool print_summary = true);
 857
 858void null_message_callback(LLMessageSystem *msg, void **data);
 859
 860//
 861// Inlines
 862//
 863
 864#if !defined( LL_BIG_ENDIAN ) && !defined( LL_LITTLE_ENDIAN )
 865#error Unknown endianness for htonmemcpy. Did you miss a common include?
 866#endif
 867
 868static inline void *htonmemcpy(void *vs, const void *vct, EMsgVariableType type, size_t n)
 869{
 870	char *s = (char *)vs;
 871	const char *ct = (const char *)vct;
 872#ifdef LL_BIG_ENDIAN
 873	S32 i, length;
 874#endif
 875	switch(type)
 876	{
 877	case MVT_FIXED:
 878	case MVT_VARIABLE:
 879	case MVT_U8:
 880	case MVT_S8:
 881	case MVT_BOOL:
 882	case MVT_LLUUID:
 883	case MVT_IP_ADDR:	// these two are swizzled in the getters and setters
 884	case MVT_IP_PORT:	// these two are swizzled in the getters and setters
 885		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
 886
 887	case MVT_U16:
 888	case MVT_S16:
 889		if (n != 2)
 890		{
 891			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
 892		}
 893#ifdef LL_BIG_ENDIAN
 894		*(s + 1) = *(ct);
 895		*(s) = *(ct + 1);
 896		return(vs);
 897#else
 898		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
 899#endif
 900
 901	case MVT_U32:
 902	case MVT_S32:
 903	case MVT_F32:
 904		if (n != 4)
 905		{
 906			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
 907		}
 908#ifdef LL_BIG_ENDIAN
 909		*(s + 3) = *(ct);
 910		*(s + 2) = *(ct + 1);
 911		*(s + 1) = *(ct + 2);
 912		*(s) = *(ct + 3);
 913		return(vs);
 914#else
 915		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
 916#endif
 917
 918	case MVT_U64:
 919	case MVT_S64:
 920	case MVT_F64:
 921		if (n != 8)
 922		{
 923			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
 924		}
 925#ifdef LL_BIG_ENDIAN
 926		*(s + 7) = *(ct);
 927		*(s + 6) = *(ct + 1);
 928		*(s + 5) = *(ct + 2);
 929		*(s + 4) = *(ct + 3);
 930		*(s + 3) = *(ct + 4);
 931		*(s + 2) = *(ct + 5);
 932		*(s + 1) = *(ct + 6);
 933		*(s) = *(ct + 7);
 934		return(vs);
 935#else
 936		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
 937#endif
 938
 939	case MVT_LLVector3:
 940	case MVT_LLQuaternion:  // We only send x, y, z and infer w (we set x, y, z to ensure that w >= 0)
 941		if (n != 12)
 942		{
 943			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
 944		}
 945#ifdef LL_BIG_ENDIAN
 946		htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
 947		htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
 948		return(htonmemcpy(s, ct, MVT_F32, 4));
 949#else
 950		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
 951#endif
 952
 953	case MVT_LLVector3d:
 954		if (n != 24)
 955		{
 956			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
 957		}
 958#ifdef LL_BIG_ENDIAN
 959		htonmemcpy(s + 16, ct + 16, MVT_F64, 8);
 960		htonmemcpy(s + 8, ct + 8, MVT_F64, 8);
 961		return(htonmemcpy(s, ct, MVT_F64, 8));
 962#else
 963		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
 964#endif
 965
 966	case MVT_LLVector4:
 967		if (n != 16)
 968		{
 969			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
 970		}
 971#ifdef LL_BIG_ENDIAN
 972		htonmemcpy(s + 12, ct + 12, MVT_F32, 4);
 973		htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
 974		htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
 975		return(htonmemcpy(s, ct, MVT_F32, 4));
 976#else
 977		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
 978#endif
 979
 980	case MVT_U16Vec3:
 981		if (n != 6)
 982		{
 983			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
 984		}
 985#ifdef LL_BIG_ENDIAN
 986		htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
 987		htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
 988		return(htonmemcpy(s, ct, MVT_U16, 2));
 989#else
 990		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
 991#endif
 992
 993	case MVT_U16Quat:
 994		if (n != 8)
 995		{
 996			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
 997		}
 998#ifdef LL_BIG_ENDIAN
 999		htonmemcpy(s + 6, ct + 6, MVT_U16, 2);
1000		htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
1001		htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
1002		return(htonmemcpy(s, ct, MVT_U16, 2));
1003#else
1004		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
1005#endif
1006
1007	case MVT_S16Array:
1008		if (n % 2)
1009		{
1010			llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
1011		}
1012#ifdef LL_BIG_ENDIAN
1013		length = n % 2;
1014		for (i = 1; i < length; i++)
1015		{
1016			htonmemcpy(s + i*2, ct + i*2, MVT_S16, 2);
1017		}
1018		return(htonmemcpy(s, ct, MVT_S16, 2));
1019#else
1020		return(memcpy(s,ct,n));
1021#endif
1022
1023	default:
1024		return(memcpy(s,ct,n));	/* Flawfinder: ignore */ 
1025	}
1026}
1027
1028inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n)
1029{
1030	return(htonmemcpy(s,ct,type, n));
1031}
1032
1033inline const LLHost& LLMessageSystem::getReceivingInterface() const {return mLastReceivingIF;}
1034
1035inline U32 LLMessageSystem::getSenderIP() const 
1036{
1037	return mLastSender.getAddress();
1038}
1039
1040inline U32 LLMessageSystem::getSenderPort() const
1041{
1042	return mLastSender.getPort();
1043}
1044
1045
1046//-----------------------------------------------------------------------------
1047// Transmission aliases
1048//-----------------------------------------------------------------------------
1049
1050inline S32 LLMessageSystem::sendMessage(const U32 circuit)
1051{
1052	return sendMessage(findHost(circuit));
1053}
1054
1055#endif