aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/message.h
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/llmessage/message.h')
-rw-r--r--linden/indra/llmessage/message.h1270
1 files changed, 1270 insertions, 0 deletions
diff --git a/linden/indra/llmessage/message.h b/linden/indra/llmessage/message.h
new file mode 100644
index 0000000..df062e7
--- /dev/null
+++ b/linden/indra/llmessage/message.h
@@ -0,0 +1,1270 @@
1/**
2 * @file message.h
3 * @brief LLMessageSystem class header file
4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#ifndef LL_MESSAGE_H
29#define LL_MESSAGE_H
30
31#include <cstring>
32#include <stdio.h>
33#include <map>
34#include <set>
35
36#if LL_LINUX
37#include <endian.h>
38#include <netinet/in.h>
39#endif
40
41#if LL_WINDOWS
42#include "winsock2.h" // htons etc.
43#endif
44
45#include "llerror.h"
46#include "net.h"
47#include "string_table.h"
48#include "llptrskipmap.h"
49#include "llcircuit.h"
50#include "lltimer.h"
51#include "llpacketring.h"
52#include "llhost.h"
53#include "llpacketack.h"
54#include "doublelinkedlist.h"
55#include "message_prehash.h"
56#include "llstl.h"
57#include "lldarray.h"
58
59const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
60const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
61
62const S32 MESSAGE_MAX_PER_FRAME = 400;
63
64class LLMessageStringTable
65{
66public:
67 LLMessageStringTable();
68 ~LLMessageStringTable();
69
70 char *getString(const char *str);
71
72 U32 mUsed;
73 BOOL mEmpty[MESSAGE_NUMBER_OF_HASH_BUCKETS];
74 char mString[MESSAGE_NUMBER_OF_HASH_BUCKETS][MESSAGE_MAX_STRINGS_LENGTH]; /* Flawfinder: ignore */
75};
76
77extern LLMessageStringTable gMessageStringTable;
78
79// Individual Messages are described with the following format
80// Note that to ease parsing, keywords are used
81//
82// // Comment (Comment like a C++ single line comment)
83// Comments can only be placed between Messages
84// {
85// MessageName (same naming restrictions as C variable)
86// Frequency ("High", "Medium", or "Low" - determines whether message ID is 8, 16, or 32-bits --
87// there can 254 messages in the first 2 groups, 32K in the last group)
88// (A message can be made up only of the Name if it is only a signal)
89// Trust ("Trusted", "NotTrusted" - determines if a message will be accepted
90// on a circuit. "Trusted" messages are not accepted from NotTrusted circuits
91// while NotTrusted messages are accepted on any circuit. An example of a
92// NotTrusted circuit is any circuit from the viewer.)
93// Encoding ("Zerocoded", "Unencoded" - zerocoded messages attempt to compress sequences of
94// zeros, but if there is no space win, it discards the compression and goes unencoded)
95// {
96// Block Name (same naming restrictions as C variable)
97// Block Type ("Single", "Multiple", or "Variable" - determines if the block is coded once,
98// a known number of times, or has a 8 bit argument encoded to tell the decoder
99// how many times the group is repeated)
100// Block Repeat Number (Optional - used only with the "Multiple" type - tells how many times the field is repeated
101// {
102// Variable 1 Name (same naming restrictions as C variable)
103// Variable Type ("Fixed" or "Variable" - determines if the variable is of fixed size or needs to
104// encode an argument describing the size in bytes)
105// Variable Size (In bytes, either of the "Fixed" variable itself or of the size argument)
106//
107// repeat variables
108//
109// }
110//
111// Repeat for number of variables in block
112// }
113//
114// Repeat for number of blocks in message
115// }
116// Repeat for number of messages in file
117//
118
119// Constants
120const S32 MAX_MESSAGE_INTERNAL_NAME_SIZE = 255;
121const S32 MAX_BUFFER_SIZE = NET_BUFFER_SIZE;
122const S32 MAX_BLOCKS = 255;
123
124const U8 LL_ZERO_CODE_FLAG = 0x80;
125const U8 LL_RELIABLE_FLAG = 0x40;
126const U8 LL_RESENT_FLAG = 0x20;
127const U8 LL_ACK_FLAG = 0x10;
128
129const S32 LL_MINIMUM_VALID_PACKET_SIZE = LL_PACKET_ID_SIZE + 1; // 4 bytes id + 1 byte message name (high)
130
131const S32 LL_DEFAULT_RELIABLE_RETRIES = 3;
132const F32 LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS = 1.f;
133const F32 LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS = 1.f;
134const F32 LL_PING_BASED_TIMEOUT_DUMMY = 0.0f;
135
136// *NOTE: Maybe these factors shouldn't include the msec to sec conversion
137// implicitly.
138// However, all units should be MKS.
139const F32 LL_SEMIRELIABLE_TIMEOUT_FACTOR = 5.f / 1000.f; // factor * averaged ping
140const F32 LL_RELIABLE_TIMEOUT_FACTOR = 5.f / 1000.f; // factor * averaged ping
141const F32 LL_FILE_XFER_TIMEOUT_FACTOR = 5.f / 1000.f; // factor * averaged ping
142const F32 LL_LOST_TIMEOUT_FACTOR = 16.f / 1000.f; // factor * averaged ping for marking packets "Lost"
143const F32 LL_MAX_LOST_TIMEOUT = 5.f; // Maximum amount of time before considering something "lost"
144
145const S32 MAX_MESSAGE_COUNT_NUM = 1024;
146
147// Forward declarations
148class LLCircuit;
149class LLVector3;
150class LLVector4;
151class LLVector3d;
152class LLQuaternion;
153class LLSD;
154class LLUUID;
155class LLMessageSystem;
156
157// message data pieces are used to collect the data called for by the message template
158
159// iterator typedefs precede each class as needed
160typedef enum e_message_variable_type
161{
162 MVT_NULL,
163 MVT_FIXED,
164 MVT_VARIABLE,
165 MVT_U8,
166 MVT_U16,
167 MVT_U32,
168 MVT_U64,
169 MVT_S8,
170 MVT_S16,
171 MVT_S32,
172 MVT_S64,
173 MVT_F32,
174 MVT_F64,
175 MVT_LLVector3,
176 MVT_LLVector3d,
177 MVT_LLVector4,
178 MVT_LLQuaternion,
179 MVT_LLUUID,
180 MVT_BOOL,
181 MVT_IP_ADDR,
182 MVT_IP_PORT,
183 MVT_U16Vec3,
184 MVT_U16Quat,
185 MVT_S16Array,
186 MVT_EOL
187} EMsgVariableType;
188
189// message system exceptional condition handlers.
190enum EMessageException
191{
192 MX_UNREGISTERED_MESSAGE, // message number not part of template
193 MX_PACKET_TOO_SHORT, // invalid packet, shorter than minimum packet size
194 MX_RAN_OFF_END_OF_PACKET, // ran off the end of the packet during decode
195 MX_WROTE_PAST_BUFFER_SIZE // wrote past buffer size in zero code expand
196};
197typedef void (*msg_exception_callback)(LLMessageSystem*,void*,EMessageException);
198
199
200
201class LLMsgData;
202class LLMsgBlkData;
203class LLMessageTemplate;
204
205class LLMessagePollInfo;
206
207class LLMessageSystem
208{
209public:
210 U8 mSendBuffer[MAX_BUFFER_SIZE];
211 // Encoded send buffer needs to be slightly larger since the zero
212 // coding can potentially increase the size of the send data.
213 U8 mEncodedSendBuffer[2 * MAX_BUFFER_SIZE];
214 S32 mSendSize;
215 S32 mCurrentSendTotal;
216
217 LLPacketRing mPacketRing;
218 LLReliablePacketParams mReliablePacketParams;
219
220 //LLLinkedList<LLPacketAck> mAckList;
221
222 // Set this flag to TRUE when you want *very* verbose logs.
223 BOOL mVerboseLog;
224
225 U32 mMessageFileChecksum;
226 F32 mMessageFileVersionNumber;
227
228 typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t;
229 typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t;
230
231private:
232 message_template_name_map_t mMessageTemplates;
233 message_template_number_map_t mMessageNumbers;
234
235public:
236 S32 mSystemVersionMajor;
237 S32 mSystemVersionMinor;
238 S32 mSystemVersionPatch;
239 S32 mSystemVersionServer;
240 U32 mVersionFlags;
241
242
243 BOOL mbProtected;
244
245 U32 mNumberHighFreqMessages;
246 U32 mNumberMediumFreqMessages;
247 U32 mNumberLowFreqMessages;
248 S32 mPort;
249 S32 mSocket;
250
251 U32 mPacketsIn; // total packets in, including compressed and uncompressed
252 U32 mPacketsOut; // total packets out, including compressed and uncompressed
253
254 U64 mBytesIn; // total bytes in, including compressed and uncompressed
255 U64 mBytesOut; // total bytes out, including compressed and uncompressed
256
257 U32 mCompressedPacketsIn; // total compressed packets in
258 U32 mCompressedPacketsOut; // total compressed packets out
259
260 U32 mReliablePacketsIn; // total reliable packets in
261 U32 mReliablePacketsOut; // total reliable packets out
262
263 U32 mDroppedPackets; // total dropped packets in
264 U32 mResentPackets; // total resent packets out
265 U32 mFailedResendPackets; // total resend failure packets out
266 U32 mOffCircuitPackets; // total # of off-circuit packets rejected
267 U32 mInvalidOnCircuitPackets; // total # of on-circuit but invalid packets rejected
268
269 S64 mUncompressedBytesIn; // total uncompressed size of compressed packets in
270 S64 mUncompressedBytesOut; // total uncompressed size of compressed packets out
271 S64 mCompressedBytesIn; // total compressed size of compressed packets in
272 S64 mCompressedBytesOut; // total compressed size of compressed packets out
273 S64 mTotalBytesIn; // total size of all uncompressed packets in
274 S64 mTotalBytesOut; // total size of all uncompressed packets out
275
276 BOOL mSendReliable; // does the outgoing message require a pos ack?
277
278 LLCircuit mCircuitInfo;
279 F64 mCircuitPrintTime; // used to print circuit debug info every couple minutes
280 F32 mCircuitPrintFreq; // seconds
281
282 std::map<U64, U32> mIPPortToCircuitCode;
283 std::map<U32, U64> mCircuitCodeToIPPort;
284 U32 mOurCircuitCode;
285 S32 mSendPacketFailureCount;
286 S32 mUnackedListDepth;
287 S32 mUnackedListSize;
288 S32 mDSMaxListDepth;
289
290public:
291 // Read file and build message templates
292 LLMessageSystem(const char *filename, U32 port, S32 version_major,
293 S32 version_minor, S32 version_patch);
294
295public:
296 // Subclass use.
297 LLMessageSystem();
298
299public:
300 virtual ~LLMessageSystem();
301
302 BOOL isOK() const { return !mbError; }
303 S32 getErrorCode() const { return mErrorCode; }
304
305 // Read file and build message templates filename must point to a
306 // valid string which specifies the path of a valid linden
307 // template.
308 void loadTemplateFile(const char* filename);
309
310
311 // methods for building, sending, receiving, and handling messages
312 void setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL);
313 void setHandlerFunc(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL)
314 {
315 setHandlerFuncFast(gMessageStringTable.getString(name), handler_func, user_data);
316 }
317
318 bool callHandler(const char *name, bool trustedSource,
319 LLMessageSystem* msg);
320
321 // Set a callback function for a message system exception.
322 void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL);
323 // Call the specified exception func, and return TRUE if a
324 // function was found and called. Otherwise return FALSE.
325 BOOL callExceptionFunc(EMessageException exception);
326
327 // This method returns true if the code is in the circuit codes map.
328 BOOL isCircuitCodeKnown(U32 code) const;
329
330 // usually called in response to an AddCircuitCode message, but
331 // may also be called by the login process.
332 bool addCircuitCode(U32 code, const LLUUID& session_id);
333
334 BOOL poll(F32 seconds); // Number of seconds that we want to block waiting for data, returns if data was received
335 BOOL checkMessages( S64 frame_count = 0 );
336 void processAcks();
337
338 BOOL isMessageFast(const char *msg);
339 BOOL isMessage(const char *msg)
340 {
341 return isMessageFast(gMessageStringTable.getString(msg));
342 }
343
344 void dumpPacketToLog();
345
346 char *getMessageName();
347
348 const LLHost& getSender() const;
349 U32 getSenderIP() const; // getSender() is preferred
350 U32 getSenderPort() const; // getSender() is preferred
351
352 // This method returns the uuid associated with the sender. The
353 // UUID will be null if it is not yet known or is a server
354 // circuit.
355 const LLUUID& getSenderID() const;
356
357 // This method returns the session id associated with the last
358 // sender.
359 const LLUUID& getSenderSessionID() const;
360
361 // set & get the session id (useful for viewers for now.)
362 void setMySessionID(const LLUUID& session_id) { mSessionID = session_id; }
363 const LLUUID& getMySessionID() { return mSessionID; }
364
365 virtual void newMessageFast(const char *name);
366 void newMessage(const char *name)
367 {
368 newMessageFast(gMessageStringTable.getString(name));
369 }
370
371 void copyMessageRtoS();
372 void clearMessage();
373
374 virtual void nextBlockFast(const char *blockname);
375 void nextBlock(const char *blockname)
376 {
377 nextBlockFast(gMessageStringTable.getString(blockname));
378 }
379private:
380 void addDataFast(const char *varname, const void *data, EMsgVariableType type, S32 size); // Use only for types not in system already
381 void addData(const char *varname, const void *data, EMsgVariableType type, S32 size)
382 {
383 addDataFast(gMessageStringTable.getString(varname), data, type, size);
384 }
385
386
387 void addDataFast(const char *varname, const void *data, EMsgVariableType type); // DEPRECATED - not typed, doesn't check storage space
388 void addData(const char *varname, const void *data, EMsgVariableType type)
389 {
390 addDataFast(gMessageStringTable.getString(varname), data, type);
391 }
392public:
393 void addBinaryDataFast(const char *varname, const void *data, S32 size)
394 {
395 addDataFast(varname, data, MVT_FIXED, size);
396 }
397 void addBinaryData(const char *varname, const void *data, S32 size)
398 {
399 addDataFast(gMessageStringTable.getString(varname), data, MVT_FIXED, size);
400 }
401
402 void addBOOLFast( const char* varname, BOOL b); // typed, checks storage space
403 void addBOOL( const char* varname, BOOL b); // typed, checks storage space
404 void addS8Fast( const char *varname, S8 s); // typed, checks storage space
405 void addS8( const char *varname, S8 s); // typed, checks storage space
406 void addU8Fast( const char *varname, U8 u); // typed, checks storage space
407 void addU8( const char *varname, U8 u); // typed, checks storage space
408 void addS16Fast( const char *varname, S16 i); // typed, checks storage space
409 void addS16( const char *varname, S16 i); // typed, checks storage space
410 void addU16Fast( const char *varname, U16 i); // typed, checks storage space
411 void addU16( const char *varname, U16 i); // typed, checks storage space
412 void addF32Fast( const char *varname, F32 f); // typed, checks storage space
413 void addF32( const char *varname, F32 f); // typed, checks storage space
414 void addS32Fast( const char *varname, S32 s); // typed, checks storage space
415 void addS32( const char *varname, S32 s); // typed, checks storage space
416 virtual void addU32Fast( const char *varname, U32 u); // typed, checks storage space
417 void addU32( const char *varname, U32 u); // typed, checks storage space
418 void addU64Fast( const char *varname, U64 lu); // typed, checks storage space
419 void addU64( const char *varname, U64 lu); // typed, checks storage space
420 void addF64Fast( const char *varname, F64 d); // typed, checks storage space
421 void addF64( const char *varname, F64 d); // typed, checks storage space
422 void addVector3Fast( const char *varname, const LLVector3& vec); // typed, checks storage space
423 void addVector3( const char *varname, const LLVector3& vec); // typed, checks storage space
424 void addVector4Fast( const char *varname, const LLVector4& vec); // typed, checks storage space
425 void addVector4( const char *varname, const LLVector4& vec); // typed, checks storage space
426 void addVector3dFast( const char *varname, const LLVector3d& vec); // typed, checks storage space
427 void addVector3d( const char *varname, const LLVector3d& vec); // typed, checks storage space
428 void addQuatFast( const char *varname, const LLQuaternion& quat); // typed, checks storage space
429 void addQuat( const char *varname, const LLQuaternion& quat); // typed, checks storage space
430 virtual void addUUIDFast( const char *varname, const LLUUID& uuid); // typed, checks storage space
431 void addUUID( const char *varname, const LLUUID& uuid); // typed, checks storage space
432 void addIPAddrFast( const char *varname, const U32 ip); // typed, checks storage space
433 void addIPAddr( const char *varname, const U32 ip); // typed, checks storage space
434 void addIPPortFast( const char *varname, const U16 port); // typed, checks storage space
435 void addIPPort( const char *varname, const U16 port); // typed, checks storage space
436 void addStringFast( const char* varname, const char* s); // typed, checks storage space
437 void addString( const char* varname, const char* s); // typed, checks storage space
438 void addStringFast( const char* varname, const std::string& s); // typed, checks storage space
439 void addString( const char* varname, const std::string& s); // typed, checks storage space
440
441 S32 getCurrentSendTotal() const { return mCurrentSendTotal; }
442
443 // This method checks for current send total and returns true if
444 // you need to go to the next block type or need to start a new
445 // message. Specify the current blockname to check block counts,
446 // otherwise the method only checks against MTU.
447 BOOL isSendFull(const char* blockname = NULL);
448 BOOL isSendFullFast(const char* blockname = NULL);
449
450 BOOL removeLastBlock();
451
452 void buildMessage();
453
454 S32 zeroCode(U8 **data, S32 *data_size);
455 S32 zeroCodeExpand(U8 **data, S32 *data_size);
456 S32 zeroCodeAdjustCurrentSendTotal();
457
458 // Uses ping-based retry
459 virtual S32 sendReliable(const LLHost &host);
460
461 // Uses ping-based retry
462 S32 sendReliable(const U32 circuit) { return sendReliable(findHost(circuit)); }
463
464 // Use this one if you DON'T want automatic ping-based retry.
465 S32 sendReliable( const LLHost &host,
466 S32 retries,
467 BOOL ping_based_retries,
468 F32 timeout,
469 void (*callback)(void **,S32),
470 void ** callback_data);
471
472 S32 sendSemiReliable( const LLHost &host,
473 void (*callback)(void **,S32), void ** callback_data);
474
475 // flush sends a message only if data's been pushed on it.
476 S32 flushSemiReliable( const LLHost &host,
477 void (*callback)(void **,S32), void ** callback_data);
478
479 S32 flushReliable( const LLHost &host );
480
481 void forwardMessage(const LLHost &host);
482 void forwardReliable(const LLHost &host);
483 void forwardReliable(const U32 circuit_code);
484
485 S32 sendMessage(const LLHost &host);
486 S32 sendMessage(const U32 circuit);
487
488 BOOL decodeData(const U8 *buffer, const LLHost &host);
489
490 // TODO: Consolide these functions
491 // TODO: Make these private, force use of typed functions.
492 // If size is not 0, an error is generated if size doesn't exactly match the size of the data.
493 // At all times, the number if bytes written to *datap is <= max_size.
494private:
495 void getDataFast(const char *blockname, const char *varname, void *datap, S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX);
496 void getData(const char *blockname, const char *varname, void *datap, S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX)
497 {
498 getDataFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname), datap, size, blocknum, max_size);
499 }
500public:
501 void getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX)
502 {
503 getDataFast(blockname, varname, datap, size, blocknum, max_size);
504 }
505 void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX)
506 {
507 getDataFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname), datap, size, blocknum, max_size);
508 }
509
510 void getBOOLFast( const char *block, const char *var, BOOL &data, S32 blocknum = 0);
511 void getBOOL( const char *block, const char *var, BOOL &data, S32 blocknum = 0);
512 void getS8Fast( const char *block, const char *var, S8 &data, S32 blocknum = 0);
513 void getS8( const char *block, const char *var, S8 &data, S32 blocknum = 0);
514 void getU8Fast( const char *block, const char *var, U8 &data, S32 blocknum = 0);
515 void getU8( const char *block, const char *var, U8 &data, S32 blocknum = 0);
516 void getS16Fast( const char *block, const char *var, S16 &data, S32 blocknum = 0);
517 void getS16( const char *block, const char *var, S16 &data, S32 blocknum = 0);
518 void getU16Fast( const char *block, const char *var, U16 &data, S32 blocknum = 0);
519 void getU16( const char *block, const char *var, U16 &data, S32 blocknum = 0);
520 void getS32Fast( const char *block, const char *var, S32 &data, S32 blocknum = 0);
521 void getS32( const char *block, const char *var, S32 &data, S32 blocknum = 0);
522 void getF32Fast( const char *block, const char *var, F32 &data, S32 blocknum = 0);
523 void getF32( const char *block, const char *var, F32 &data, S32 blocknum = 0);
524 virtual void getU32Fast( const char *block, const char *var, U32 &data, S32 blocknum = 0);
525 void getU32( const char *block, const char *var, U32 &data, S32 blocknum = 0);
526 virtual void getU64Fast( const char *block, const char *var, U64 &data, S32 blocknum = 0);
527 void getU64( const char *block, const char *var, U64 &data, S32 blocknum = 0);
528 void getF64Fast( const char *block, const char *var, F64 &data, S32 blocknum = 0);
529 void getF64( const char *block, const char *var, F64 &data, S32 blocknum = 0);
530 void getVector3Fast( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0);
531 void getVector3( const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0);
532 void getVector4Fast( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0);
533 void getVector4( const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0);
534 void getVector3dFast(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
535 void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);
536 void getQuatFast( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
537 void getQuat( const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);
538 virtual void getUUIDFast( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
539 void getUUID( const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);
540 virtual void getIPAddrFast( const char *block, const char *var, U32 &ip, S32 blocknum = 0);
541 void getIPAddr( const char *block, const char *var, U32 &ip, S32 blocknum = 0);
542 virtual void getIPPortFast( const char *block, const char *var, U16 &port, S32 blocknum = 0);
543 void getIPPort( const char *block, const char *var, U16 &port, S32 blocknum = 0);
544 virtual void getStringFast( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
545 void getString( const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);
546
547
548 // Utility functions to generate a replay-resistant digest check
549 // against the shared secret. The window specifies how much of a
550 // time window is allowed - 1 second is good for tight
551 // connections, but multi-process windows might want to be upwards
552 // of 5 seconds. For generateDigest, you want to pass in a
553 // character array of at least MD5HEX_STR_SIZE so that the hex
554 // digest and null termination will fit.
555 bool generateDigestForNumberAndUUIDs(char* digest, const U32 number, const LLUUID &id1, const LLUUID &id2) const;
556 bool generateDigestForWindowAndUUIDs(char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const;
557 bool isMatchingDigestForWindowAndUUIDs(const char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const;
558
559 bool generateDigestForNumber(char* digest, const U32 number) const;
560 bool generateDigestForWindow(char* digest, const S32 window) const;
561 bool isMatchingDigestForWindow(const char* digest, const S32 window) const;
562
563 void showCircuitInfo();
564 LLString getCircuitInfoString();
565
566 virtual U32 getOurCircuitCode();
567
568 void enableCircuit(const LLHost &host, BOOL trusted);
569 void disableCircuit(const LLHost &host);
570
571 // Use this to establish trust on startup and in response to
572 // DenyTrustedCircuit.
573 void sendCreateTrustedCircuit(const LLHost& host, const LLUUID & id1, const LLUUID & id2);
574
575 // Use this to inform a peer that they aren't currently trusted...
576 // This now enqueues the request so that we can ensure that we only send
577 // one deny per circuit per message loop so that this doesn't become a DoS.
578 // The actual sending is done by reallySendDenyTrustedCircuit()
579 void sendDenyTrustedCircuit(const LLHost &host);
580
581private:
582 // A list of the circuits that need to be sent DenyTrustedCircuit messages.
583 typedef std::set<LLHost> host_set_t;
584 host_set_t mDenyTrustedCircuitSet;
585
586 // Really sends the DenyTrustedCircuit message to a given host
587 // related to sendDenyTrustedCircuit()
588 void reallySendDenyTrustedCircuit(const LLHost &host);
589
590
591public:
592 // Use this to establish trust to and from a host. This blocks
593 // until trust has been established, and probably should only be
594 // used on startup.
595 void establishBidirectionalTrust(const LLHost &host, S64 frame_count = 0);
596
597 // returns whether the given host is on a trusted circuit
598 BOOL getCircuitTrust(const LLHost &host);
599
600 void setCircuitAllowTimeout(const LLHost &host, BOOL allow);
601 void setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost &host, void *user_data), void *user_data);
602
603 BOOL checkCircuitBlocked(const U32 circuit);
604 BOOL checkCircuitAlive(const U32 circuit);
605 BOOL checkCircuitAlive(const LLHost &host);
606 void setCircuitProtection(BOOL b_protect);
607 U32 findCircuitCode(const LLHost &host);
608 LLHost findHost(const U32 circuit_code);
609 void sanityCheck();
610
611 S32 getNumberOfBlocksFast(const char *blockname);
612 S32 getNumberOfBlocks(const char *blockname)
613 {
614 return getNumberOfBlocksFast(gMessageStringTable.getString(blockname));
615 }
616 S32 getSizeFast(const char *blockname, const char *varname);
617 S32 getSize(const char *blockname, const char *varname)
618 {
619 return getSizeFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname));
620 }
621 S32 getSizeFast(const char *blockname, S32 blocknum, const char *varname); // size in bytes of variable length data
622 S32 getSize(const char *blockname, S32 blocknum, const char *varname)
623 {
624 return getSizeFast(gMessageStringTable.getString(blockname), blocknum, gMessageStringTable.getString(varname));
625 }
626
627 void resetReceiveCounts(); // resets receive counts for all message types to 0
628 void dumpReceiveCounts(); // dumps receive count for each message type to llinfos
629 void dumpCircuitInfo(); // Circuit information to llinfos
630
631 BOOL isClear() const; // returns mbSClear;
632 S32 flush(const LLHost &host);
633
634 U32 getListenPort( void ) const;
635
636 void startLogging(); // start verbose logging
637 void stopLogging(); // flush and close file
638 void summarizeLogs(std::ostream& str); // log statistics
639
640 S32 getReceiveSize() const { return mReceiveSize; }
641 S32 getReceiveCompressedSize() const { return mIncomingCompressedSize; }
642 S32 getReceiveBytes() const;
643
644 S32 getUnackedListSize() const { return mUnackedListSize; }
645
646 const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
647 const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
648
649 // friends
650 friend std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg);
651
652 void setMaxMessageTime(const F32 seconds); // Max time to process messages before warning and dumping (neg to disable)
653 void setMaxMessageCounts(const S32 num); // Max number of messages before dumping (neg to disable)
654
655 // statics
656public:
657 static U64 getMessageTimeUsecs(const BOOL update = FALSE); // Get the current message system time in microseconds
658 static F64 getMessageTimeSeconds(const BOOL update = FALSE); // Get the current message system time in seconds
659
660 static void setTimeDecodes( BOOL b )
661 { LLMessageSystem::mTimeDecodes = b; }
662
663 static void setTimeDecodesSpamThreshold( F32 seconds )
664 { LLMessageSystem::mTimeDecodesSpamThreshold = seconds; }
665
666 // message handlers internal to the message systesm
667 //static void processAssignCircuitCode(LLMessageSystem* msg, void**);
668 static void processAddCircuitCode(LLMessageSystem* msg, void**);
669 static void processUseCircuitCode(LLMessageSystem* msg, void**);
670
671 void setMessageBans(const LLSD& trusted, const LLSD& untrusted);
672
673private:
674 // data used in those internal handlers
675
676 // The mCircuitCodes is a map from circuit codes to session
677 // ids. This allows us to verify sessions on connect.
678 typedef std::map<U32, LLUUID> code_session_map_t;
679 code_session_map_t mCircuitCodes;
680
681 // Viewers need to track a process session in order to make sure
682 // that no one gives them a bad circuit code.
683 LLUUID mSessionID;
684
685private:
686 void addTemplate(LLMessageTemplate *templatep);
687 void clearReceiveState();
688 BOOL decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );
689
690 void logMsgFromInvalidCircuit( const LLHost& sender, BOOL recv_reliable );
691 void logTrustedMsgFromUntrustedCircuit( const LLHost& sender );
692 void logValidMsg(LLCircuitData *cdp, const LLHost& sender, BOOL recv_reliable, BOOL recv_resent, BOOL recv_acks );
693 void logRanOffEndOfPacket( const LLHost& sender );
694
695private:
696 class LLMessageCountInfo
697 {
698 public:
699 U32 mMessageNum;
700 U32 mMessageBytes;
701 BOOL mInvalid;
702 };
703
704 LLMessagePollInfo *mPollInfop;
705
706 U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE];
707 U8 mTrueReceiveBuffer[MAX_BUFFER_SIZE];
708 S32 mTrueReceiveSize;
709
710 // Must be valid during decode
711 S32 mReceiveSize;
712 TPACKETID mCurrentRecvPacketID; // packet ID of current receive packet (for reporting)
713 LLMessageTemplate *mCurrentRMessageTemplate;
714 LLMsgData *mCurrentRMessageData;
715 S32 mIncomingCompressedSize; // original size of compressed msg (0 if uncomp.)
716 LLHost mLastSender;
717
718 // send message storage
719 LLMsgData *mCurrentSMessageData;
720 LLMessageTemplate *mCurrentSMessageTemplate;
721 LLMsgBlkData *mCurrentSDataBlock;
722 char *mCurrentSMessageName;
723 char *mCurrentSBlockName;
724
725 BOOL mbError;
726 S32 mErrorCode;
727
728 BOOL mbSBuilt; // is send message built?
729 BOOL mbSClear; // is the send message clear?
730
731 F64 mResendDumpTime; // The last time we dumped resends
732
733 LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM];
734 S32 mNumMessageCounts;
735 F32 mReceiveTime;
736 F32 mMaxMessageTime; // Max number of seconds for processing messages
737 S32 mMaxMessageCounts; // Max number of messages to process before dumping.
738 F64 mMessageCountTime;
739
740 F64 mCurrentMessageTimeSeconds; // The current "message system time" (updated the first call to checkMessages after a resetReceiveCount
741
742 // message system exceptions
743 typedef std::pair<msg_exception_callback, void*> exception_t;
744 typedef std::map<EMessageException, exception_t> callbacks_t;
745 callbacks_t mExceptionCallbacks;
746
747 // stuff for logging
748 LLTimer mMessageSystemTimer;
749
750 static F32 mTimeDecodesSpamThreshold; // If mTimeDecodes is on, all this many seconds for each msg decode before spamming
751 static BOOL mTimeDecodes; // Measure time for all message decodes if TRUE;
752
753 void init(); // ctor shared initialisation.
754};
755
756
757// external hook into messaging system
758extern LLMessageSystem *gMessageSystem;
759//extern const char* MESSAGE_LOG_FILENAME;
760
761void encrypt_template(const char *src_name, const char *dest_name);
762BOOL decrypt_template(const char *src_name, const char *dest_name);
763
764// Must specific overall system version, which is used to determine
765// if a patch is available in the message template checksum verification.
766// Return TRUE if able to initialize system.
767BOOL start_messaging_system(
768 const std::string& template_name,
769 U32 port,
770 S32 version_major,
771 S32 version_minor,
772 S32 version_patch,
773 BOOL b_dump_prehash_file,
774 const std::string& secret);
775
776void end_messaging_system();
777
778void null_message_callback(LLMessageSystem *msg, void **data);
779void process_log_control(LLMessageSystem* msg, void**);
780
781//
782// Inlines
783//
784
785static inline void *htonmemcpy(void *vs, const void *vct, EMsgVariableType type, size_t n)
786{
787 char *s = (char *)vs;
788 const char *ct = (const char *)vct;
789#ifdef LL_BIG_ENDIAN
790 S32 i, length;
791#endif
792 switch(type)
793 {
794 case MVT_FIXED:
795 case MVT_VARIABLE:
796 case MVT_U8:
797 case MVT_S8:
798 case MVT_BOOL:
799 case MVT_LLUUID:
800 case MVT_IP_ADDR: // these two are swizzled in the getters and setters
801 case MVT_IP_PORT: // these two are swizzled in the getters and setters
802 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
803
804 case MVT_U16:
805 case MVT_S16:
806 if (n != 2)
807 {
808 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
809 }
810#ifdef LL_BIG_ENDIAN
811 *(s + 1) = *(ct);
812 *(s) = *(ct + 1);
813 return(vs);
814#else
815 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
816#endif
817
818 case MVT_U32:
819 case MVT_S32:
820 case MVT_F32:
821 if (n != 4)
822 {
823 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
824 }
825#ifdef LL_BIG_ENDIAN
826 *(s + 3) = *(ct);
827 *(s + 2) = *(ct + 1);
828 *(s + 1) = *(ct + 2);
829 *(s) = *(ct + 3);
830 return(vs);
831#else
832 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
833#endif
834
835 case MVT_U64:
836 case MVT_S64:
837 case MVT_F64:
838 if (n != 8)
839 {
840 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
841 }
842#ifdef LL_BIG_ENDIAN
843 *(s + 7) = *(ct);
844 *(s + 6) = *(ct + 1);
845 *(s + 5) = *(ct + 2);
846 *(s + 4) = *(ct + 3);
847 *(s + 3) = *(ct + 4);
848 *(s + 2) = *(ct + 5);
849 *(s + 1) = *(ct + 6);
850 *(s) = *(ct + 7);
851 return(vs);
852#else
853 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
854#endif
855
856 case MVT_LLVector3:
857 case MVT_LLQuaternion: // We only send x, y, z and infer w (we set x, y, z to ensure that w >= 0)
858 if (n != 12)
859 {
860 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
861 }
862#ifdef LL_BIG_ENDIAN
863 htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
864 htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
865 return(htonmemcpy(s, ct, MVT_F32, 4));
866#else
867 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
868#endif
869
870 case MVT_LLVector3d:
871 if (n != 24)
872 {
873 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
874 }
875#ifdef LL_BIG_ENDIAN
876 htonmemcpy(s + 16, ct + 16, MVT_F64, 8);
877 htonmemcpy(s + 8, ct + 8, MVT_F64, 8);
878 return(htonmemcpy(s, ct, MVT_F64, 8));
879#else
880 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
881#endif
882
883 case MVT_LLVector4:
884 if (n != 16)
885 {
886 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
887 }
888#ifdef LL_BIG_ENDIAN
889 htonmemcpy(s + 12, ct + 12, MVT_F32, 4);
890 htonmemcpy(s + 8, ct + 8, MVT_F32, 4);
891 htonmemcpy(s + 4, ct + 4, MVT_F32, 4);
892 return(htonmemcpy(s, ct, MVT_F32, 4));
893#else
894 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
895#endif
896
897 case MVT_U16Vec3:
898 if (n != 6)
899 {
900 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
901 }
902#ifdef LL_BIG_ENDIAN
903 htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
904 htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
905 return(htonmemcpy(s, ct, MVT_U16, 2));
906#else
907 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
908#endif
909
910 case MVT_U16Quat:
911 if (n != 8)
912 {
913 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
914 }
915#ifdef LL_BIG_ENDIAN
916 htonmemcpy(s + 6, ct + 6, MVT_U16, 2);
917 htonmemcpy(s + 4, ct + 4, MVT_U16, 2);
918 htonmemcpy(s + 2, ct + 2, MVT_U16, 2);
919 return(htonmemcpy(s, ct, MVT_U16, 2));
920#else
921 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
922#endif
923
924 case MVT_S16Array:
925 if (n % 2)
926 {
927 llerrs << "Size argument passed to htonmemcpy doesn't match swizzle type size" << llendl;
928 }
929#ifdef LL_BIG_ENDIAN
930 length = n % 2;
931 for (i = 1; i < length; i++)
932 {
933 htonmemcpy(s + i*2, ct + i*2, MVT_S16, 2);
934 }
935 return(htonmemcpy(s, ct, MVT_S16, 2));
936#else
937 return(memcpy(s,ct,n));
938#endif
939
940 default:
941 return(memcpy(s,ct,n)); /* Flawfinder: ignore */
942 }
943}
944
945inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n)
946{
947 return(htonmemcpy(s,ct,type, n));
948}
949
950
951inline const LLHost& LLMessageSystem::getSender() const
952{
953 return mLastSender;
954}
955
956inline U32 LLMessageSystem::getSenderIP() const
957{
958 return mLastSender.getAddress();
959}
960
961inline U32 LLMessageSystem::getSenderPort() const
962{
963 return mLastSender.getPort();
964}
965
966inline void LLMessageSystem::addS8Fast(const char *varname, S8 s)
967{
968 addDataFast(varname, &s, MVT_S8, sizeof(s));
969}
970
971inline void LLMessageSystem::addS8(const char *varname, S8 s)
972{
973 addDataFast(gMessageStringTable.getString(varname), &s, MVT_S8, sizeof(s));
974}
975
976inline void LLMessageSystem::addU8Fast(const char *varname, U8 u)
977{
978 addDataFast(varname, &u, MVT_U8, sizeof(u));
979}
980
981inline void LLMessageSystem::addU8(const char *varname, U8 u)
982{
983 addDataFast(gMessageStringTable.getString(varname), &u, MVT_U8, sizeof(u));
984}
985
986inline void LLMessageSystem::addS16Fast(const char *varname, S16 i)
987{
988 addDataFast(varname, &i, MVT_S16, sizeof(i));
989}
990
991inline void LLMessageSystem::addS16(const char *varname, S16 i)
992{
993 addDataFast(gMessageStringTable.getString(varname), &i, MVT_S16, sizeof(i));
994}
995
996inline void LLMessageSystem::addU16Fast(const char *varname, U16 i)
997{
998 addDataFast(varname, &i, MVT_U16, sizeof(i));
999}
1000
1001inline void LLMessageSystem::addU16(const char *varname, U16 i)
1002{
1003 addDataFast(gMessageStringTable.getString(varname), &i, MVT_U16, sizeof(i));
1004}
1005
1006inline void LLMessageSystem::addF32Fast(const char *varname, F32 f)
1007{
1008 addDataFast(varname, &f, MVT_F32, sizeof(f));
1009}
1010
1011inline void LLMessageSystem::addF32(const char *varname, F32 f)
1012{
1013 addDataFast(gMessageStringTable.getString(varname), &f, MVT_F32, sizeof(f));
1014}
1015
1016inline void LLMessageSystem::addS32Fast(const char *varname, S32 s)
1017{
1018 addDataFast(varname, &s, MVT_S32, sizeof(s));
1019}
1020
1021inline void LLMessageSystem::addS32(const char *varname, S32 s)
1022{
1023 addDataFast(gMessageStringTable.getString(varname), &s, MVT_S32, sizeof(s));
1024}
1025
1026inline void LLMessageSystem::addU32Fast(const char *varname, U32 u)
1027{
1028 addDataFast(varname, &u, MVT_U32, sizeof(u));
1029}
1030
1031inline void LLMessageSystem::addU32(const char *varname, U32 u)
1032{
1033 addDataFast(gMessageStringTable.getString(varname), &u, MVT_U32, sizeof(u));
1034}
1035
1036inline void LLMessageSystem::addU64Fast(const char *varname, U64 lu)
1037{
1038 addDataFast(varname, &lu, MVT_U64, sizeof(lu));
1039}
1040
1041inline void LLMessageSystem::addU64(const char *varname, U64 lu)
1042{
1043 addDataFast(gMessageStringTable.getString(varname), &lu, MVT_U64, sizeof(lu));
1044}
1045
1046inline void LLMessageSystem::addF64Fast(const char *varname, F64 d)
1047{
1048 addDataFast(varname, &d, MVT_F64, sizeof(d));
1049}
1050
1051inline void LLMessageSystem::addF64(const char *varname, F64 d)
1052{
1053 addDataFast(gMessageStringTable.getString(varname), &d, MVT_F64, sizeof(d));
1054}
1055
1056inline void LLMessageSystem::addIPAddrFast(const char *varname, U32 u)
1057{
1058 addDataFast(varname, &u, MVT_IP_ADDR, sizeof(u));
1059}
1060
1061inline void LLMessageSystem::addIPAddr(const char *varname, U32 u)
1062{
1063 addDataFast(gMessageStringTable.getString(varname), &u, MVT_IP_ADDR, sizeof(u));
1064}
1065
1066inline void LLMessageSystem::addIPPortFast(const char *varname, U16 u)
1067{
1068 u = htons(u);
1069 addDataFast(varname, &u, MVT_IP_PORT, sizeof(u));
1070}
1071
1072inline void LLMessageSystem::addIPPort(const char *varname, U16 u)
1073{
1074 u = htons(u);
1075 addDataFast(gMessageStringTable.getString(varname), &u, MVT_IP_PORT, sizeof(u));
1076}
1077
1078inline void LLMessageSystem::addBOOLFast(const char* varname, BOOL b)
1079{
1080 // Can't just cast a BOOL (actually a U32) to a U8.
1081 // In some cases the low order bits will be zero.
1082 U8 temp = (b != 0);
1083 addDataFast(varname, &temp, MVT_BOOL, sizeof(temp));
1084}
1085
1086inline void LLMessageSystem::addBOOL(const char* varname, BOOL b)
1087{
1088 // Can't just cast a BOOL (actually a U32) to a U8.
1089 // In some cases the low order bits will be zero.
1090 U8 temp = (b != 0);
1091 addDataFast(gMessageStringTable.getString(varname), &temp, MVT_BOOL, sizeof(temp));
1092}
1093
1094inline void LLMessageSystem::addStringFast(const char* varname, const char* s)
1095{
1096 if (s)
1097 addDataFast( varname, (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1); /* Flawfinder: ignore */
1098 else
1099 addDataFast( varname, NULL, MVT_VARIABLE, 0);
1100}
1101
1102inline void LLMessageSystem::addString(const char* varname, const char* s)
1103{
1104 if (s)
1105 addDataFast( gMessageStringTable.getString(varname), (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1); /* Flawfinder: ignore */
1106 else
1107 addDataFast( gMessageStringTable.getString(varname), NULL, MVT_VARIABLE, 0);
1108}
1109
1110inline void LLMessageSystem::addStringFast(const char* varname, const std::string& s)
1111{
1112 if (s.size())
1113 addDataFast( varname, (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);
1114 else
1115 addDataFast( varname, NULL, MVT_VARIABLE, 0);
1116}
1117
1118inline void LLMessageSystem::addString(const char* varname, const std::string& s)
1119{
1120 if (s.size())
1121 addDataFast( gMessageStringTable.getString(varname), (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);
1122 else
1123 addDataFast( gMessageStringTable.getString(varname), NULL, MVT_VARIABLE, 0);
1124}
1125
1126
1127//-----------------------------------------------------------------------------
1128// Retrieval aliases
1129//-----------------------------------------------------------------------------
1130inline void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u, S32 blocknum)
1131{
1132 getDataFast(block, var, &u, sizeof(S8), blocknum);
1133}
1134
1135inline void LLMessageSystem::getS8(const char *block, const char *var, S8 &u, S32 blocknum)
1136{
1137 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(S8), blocknum);
1138}
1139
1140inline void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u, S32 blocknum)
1141{
1142 getDataFast(block, var, &u, sizeof(U8), blocknum);
1143}
1144
1145inline void LLMessageSystem::getU8(const char *block, const char *var, U8 &u, S32 blocknum)
1146{
1147 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U8), blocknum);
1148}
1149
1150inline void LLMessageSystem::getBOOLFast(const char *block, const char *var, BOOL &b, S32 blocknum )
1151{
1152 U8 value;
1153 getDataFast(block, var, &value, sizeof(U8), blocknum);
1154 b = (BOOL) value;
1155}
1156
1157inline void LLMessageSystem::getBOOL(const char *block, const char *var, BOOL &b, S32 blocknum )
1158{
1159 U8 value;
1160 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &value, sizeof(U8), blocknum);
1161 b = (BOOL) value;
1162}
1163
1164inline void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d, S32 blocknum)
1165{
1166 getDataFast(block, var, &d, sizeof(S16), blocknum);
1167}
1168
1169inline void LLMessageSystem::getS16(const char *block, const char *var, S16 &d, S32 blocknum)
1170{
1171 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(S16), blocknum);
1172}
1173
1174inline void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d, S32 blocknum)
1175{
1176 getDataFast(block, var, &d, sizeof(U16), blocknum);
1177}
1178
1179inline void LLMessageSystem::getU16(const char *block, const char *var, U16 &d, S32 blocknum)
1180{
1181 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U16), blocknum);
1182}
1183
1184inline void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d, S32 blocknum)
1185{
1186 getDataFast(block, var, &d, sizeof(S32), blocknum);
1187}
1188
1189inline void LLMessageSystem::getS32(const char *block, const char *var, S32 &d, S32 blocknum)
1190{
1191 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(S32), blocknum);
1192}
1193
1194inline void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d, S32 blocknum)
1195{
1196 getDataFast(block, var, &d, sizeof(U32), blocknum);
1197}
1198
1199inline void LLMessageSystem::getU32(const char *block, const char *var, U32 &d, S32 blocknum)
1200{
1201 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U32), blocknum);
1202}
1203
1204inline void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d, S32 blocknum)
1205{
1206 getDataFast(block, var, &d, sizeof(U64), blocknum);
1207}
1208
1209inline void LLMessageSystem::getU64(const char *block, const char *var, U64 &d, S32 blocknum)
1210{
1211 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U64), blocknum);
1212}
1213
1214
1215inline void LLMessageSystem::getIPAddrFast(const char *block, const char *var, U32 &u, S32 blocknum)
1216{
1217 getDataFast(block, var, &u, sizeof(U32), blocknum);
1218}
1219
1220inline void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum)
1221{
1222 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U32), blocknum);
1223}
1224
1225inline void LLMessageSystem::getIPPortFast(const char *block, const char *var, U16 &u, S32 blocknum)
1226{
1227 getDataFast(block, var, &u, sizeof(U16), blocknum);
1228 u = ntohs(u);
1229}
1230
1231inline void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u, S32 blocknum)
1232{
1233 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U16), blocknum);
1234 u = ntohs(u);
1235}
1236
1237
1238inline void LLMessageSystem::getStringFast(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum )
1239{
1240 s[0] = '\0';
1241 getDataFast(block, var, s, 0, blocknum, buffer_size);
1242 s[buffer_size - 1] = '\0';
1243}
1244
1245inline void LLMessageSystem::getString(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum )
1246{
1247 s[0] = '\0';
1248 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), s, 0, blocknum, buffer_size);
1249 s[buffer_size - 1] = '\0';
1250}
1251
1252//-----------------------------------------------------------------------------
1253// Transmission aliases
1254//-----------------------------------------------------------------------------
1255//inline S32 LLMessageSystem::sendMessage(U32 ip, U32 port, BOOL zero_code)
1256//{
1257// return sendMessage(LLHost(ip, port), zero_code);
1258//}
1259
1260//inline S32 LLMessageSystem::sendMessage(const char *ip_str, U32 port, BOOL zero_code)
1261//{
1262// return sendMessage(LLHost(ip_str, port), zero_code);
1263//}
1264
1265inline S32 LLMessageSystem::sendMessage(const U32 circuit)//, BOOL zero_code)
1266{
1267 return sendMessage(findHost(circuit));//, zero_code);
1268}
1269
1270#endif