aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/message.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:54 -0500
committerJacek Antonelli2008-08-15 23:44:54 -0500
commitb2afb8800bb033a04bb3ecdf0363068d56648ef1 (patch)
tree3568129b5bbddb47cd39d622b4137a8fbff4abaf /linden/indra/llmessage/message.cpp
parentSecond Life viewer sources 1.14.0.1 (diff)
downloadmeta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.zip
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.gz
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.bz2
meta-impy-b2afb8800bb033a04bb3ecdf0363068d56648ef1.tar.xz
Second Life viewer sources 1.15.0.2
Diffstat (limited to 'linden/indra/llmessage/message.cpp')
-rw-r--r--linden/indra/llmessage/message.cpp3169
1 files changed, 1057 insertions, 2112 deletions
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp
index 2e7cb6a..ef22b63 100644
--- a/linden/indra/llmessage/message.cpp
+++ b/linden/indra/llmessage/message.cpp
@@ -4,6 +4,7 @@
4 * 4 *
5 * Copyright (c) 2001-2007, Linden Research, Inc. 5 * Copyright (c) 2001-2007, Linden Research, Inc.
6 * 6 *
7 * Second Life Viewer Source Code
7 * The source code in this file ("Source Code") is provided by Linden Lab 8 * 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 * 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 * ("GPL"), unless you have obtained a separate licensing agreement
@@ -52,11 +53,23 @@
52 53
53// linden library headers 54// linden library headers
54#include "indra_constants.h" 55#include "indra_constants.h"
56#include "lldarray.h"
55#include "lldir.h" 57#include "lldir.h"
56#include "llerror.h" 58#include "llerror.h"
59#include "llerrorlegacy.h"
57#include "llfasttimer.h" 60#include "llfasttimer.h"
61#include "llhttpclient.h"
62#include "llhttpsender.h"
58#include "llmd5.h" 63#include "llmd5.h"
64#include "llmessagebuilder.h"
65#include "llmessageconfig.h"
66#include "llpumpio.h"
67#include "lltemplatemessagebuilder.h"
68#include "lltemplatemessagereader.h"
69#include "llmessagetemplate.h"
59#include "llsd.h" 70#include "llsd.h"
71#include "llsdmessagebuilder.h"
72#include "llsdmessagereader.h"
60#include "lltransfermanager.h" 73#include "lltransfermanager.h"
61#include "lluuid.h" 74#include "lluuid.h"
62#include "llxfermanager.h" 75#include "llxfermanager.h"
@@ -73,406 +86,6 @@
73static const F32 CIRCUIT_DUMP_TIMEOUT = 30.f; 86static const F32 CIRCUIT_DUMP_TIMEOUT = 30.f;
74static const S32 TRUST_TIME_WINDOW = 3; 87static const S32 TRUST_TIME_WINDOW = 3;
75 88
76class LLMsgVarData
77{
78public:
79 LLMsgVarData() : mName(NULL), mSize(-1), mDataSize(-1), mData(NULL), mType(MVT_U8)
80 {
81 }
82
83 LLMsgVarData(const char *name, EMsgVariableType type) : mSize(-1), mDataSize(-1), mData(NULL), mType(type)
84 {
85 mName = (char *)name;
86 }
87
88 ~LLMsgVarData()
89 {
90 // copy constructor just copies the mData pointer, so only delete mData explicitly
91 }
92
93 void deleteData()
94 {
95 delete[] mData;
96 mData = NULL;
97 }
98
99 void addData(const void *indata, S32 size, EMsgVariableType type, S32 data_size = -1);
100
101 char *getName() const { return mName; }
102 S32 getSize() const { return mSize; }
103 void *getData() { return (void*)mData; }
104 S32 getDataSize() const { return mDataSize; }
105 EMsgVariableType getType() const { return mType; }
106
107protected:
108 char *mName;
109 S32 mSize;
110 S32 mDataSize;
111
112 U8 *mData;
113 EMsgVariableType mType;
114};
115
116
117class LLMsgBlkData
118{
119public:
120 LLMsgBlkData(const char *name, S32 blocknum) : mOffset(-1), mBlockNumber(blocknum), mTotalSize(-1)
121 {
122 mName = (char *)name;
123 }
124
125 ~LLMsgBlkData()
126 {
127 for (msg_var_data_map_t::iterator iter = mMemberVarData.begin();
128 iter != mMemberVarData.end(); iter++)
129 {
130 iter->deleteData();
131 }
132 }
133
134 void addVariable(const char *name, EMsgVariableType type)
135 {
136 LLMsgVarData tmp(name,type);
137 mMemberVarData[name] = tmp;
138 }
139
140 void addData(char *name, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1)
141 {
142 LLMsgVarData* temp = &mMemberVarData[name]; // creates a new entry if one doesn't exist
143 temp->addData(data, size, type, data_size);
144 }
145
146 S32 mOffset;
147 S32 mBlockNumber;
148 typedef LLDynamicArrayIndexed<LLMsgVarData, const char *, 8> msg_var_data_map_t;
149 msg_var_data_map_t mMemberVarData;
150 char *mName;
151 S32 mTotalSize;
152};
153
154
155class LLMsgData
156{
157public:
158 LLMsgData(const char *name) : mTotalSize(-1)
159 {
160 mName = (char *)name;
161 }
162 ~LLMsgData()
163 {
164 for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer());
165 }
166
167 void addBlock(LLMsgBlkData *blockp)
168 {
169 mMemberBlocks[blockp->mName] = blockp;
170 }
171
172 void addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1);
173
174public:
175 S32 mOffset;
176 typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t;
177 msg_blk_data_map_t mMemberBlocks;
178 char *mName;
179 S32 mTotalSize;
180};
181
182inline void LLMsgVarData::addData(const void *data, S32 size, EMsgVariableType type, S32 data_size)
183{
184 mSize = size;
185 mDataSize = data_size;
186 if ( (type != MVT_VARIABLE) && (type != MVT_FIXED)
187 && (mType != MVT_VARIABLE) && (mType != MVT_FIXED))
188 {
189 if (mType != type)
190 {
191 llwarns << "Type mismatch in addData for " << mName
192 << " message: " << gMessageSystem->getCurrentSMessageName()
193 << " block: " << gMessageSystem->getCurrentSBlockName()
194 << llendl;
195 }
196 }
197 if(size)
198 {
199 delete mData; // Delete it if it already exists
200 mData = new U8[size];
201 htonmemcpy(mData, data, mType, size);
202 }
203}
204
205
206
207inline void LLMsgData::addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size)
208{
209 // remember that if the blocknumber is > 0 then the number is appended to the name
210 char *namep = (char *)blockname;
211 LLMsgBlkData* block_data = mMemberBlocks[namep];
212 if (block_data->mBlockNumber)
213 {
214 namep += block_data->mBlockNumber;
215 block_data->addData(varname, data, size, type, data_size);
216 }
217 else
218 {
219 block_data->addData(varname, data, size, type, data_size);
220 }
221}
222
223// LLMessage* classes store the template of messages
224
225
226class LLMessageVariable
227{
228public:
229 LLMessageVariable() : mName(NULL), mType(MVT_NULL), mSize(-1)
230 {
231 }
232
233 LLMessageVariable(char *name) : mType(MVT_NULL), mSize(-1)
234 {
235 mName = name;
236 }
237
238 LLMessageVariable(char *name, const EMsgVariableType type, const S32 size) : mType(type), mSize(size)
239 {
240 mName = gMessageStringTable.getString(name);
241 }
242
243 ~LLMessageVariable() {}
244
245 friend std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg);
246
247 EMsgVariableType getType() const { return mType; }
248 S32 getSize() const { return mSize; }
249 char *getName() const { return mName; }
250protected:
251 char *mName;
252 EMsgVariableType mType;
253 S32 mSize;
254};
255
256
257typedef enum e_message_block_type
258{
259 MBT_NULL,
260 MBT_SINGLE,
261 MBT_MULTIPLE,
262 MBT_VARIABLE,
263 MBT_EOF
264} EMsgBlockType;
265
266class LLMessageBlock
267{
268public:
269 LLMessageBlock(char *name, EMsgBlockType type, S32 number = 1) : mType(type), mNumber(number), mTotalSize(0)
270 {
271 mName = gMessageStringTable.getString(name);
272 }
273
274 ~LLMessageBlock()
275 {
276 for_each(mMemberVariables.begin(), mMemberVariables.end(), DeletePairedPointer());
277 }
278
279 void addVariable(char *name, const EMsgVariableType type, const S32 size)
280 {
281 LLMessageVariable** varp = &mMemberVariables[name];
282 if (*varp != NULL)
283 {
284 llerrs << name << " has already been used as a variable name!" << llendl;
285 }
286 *varp = new LLMessageVariable(name, type, size);
287 if (((*varp)->getType() != MVT_VARIABLE)
288 &&(mTotalSize != -1))
289 {
290 mTotalSize += (*varp)->getSize();
291 }
292 else
293 {
294 mTotalSize = -1;
295 }
296 }
297
298 EMsgVariableType getVariableType(char *name)
299 {
300 return (mMemberVariables[name])->getType();
301 }
302
303 S32 getVariableSize(char *name)
304 {
305 return (mMemberVariables[name])->getSize();
306 }
307
308 friend std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg);
309
310 typedef std::map<const char *, LLMessageVariable*> message_variable_map_t;
311 message_variable_map_t mMemberVariables;
312 char *mName;
313 EMsgBlockType mType;
314 S32 mNumber;
315 S32 mTotalSize;
316};
317
318
319enum EMsgFrequency
320{
321 MFT_NULL = 0, // value is size of message number in bytes
322 MFT_HIGH = 1,
323 MFT_MEDIUM = 2,
324 MFT_LOW = 4
325};
326
327typedef enum e_message_trust
328{
329 MT_TRUST,
330 MT_NOTRUST
331} EMsgTrust;
332
333enum EMsgEncoding
334{
335 ME_UNENCODED,
336 ME_ZEROCODED
337};
338
339class LLMessageTemplate
340{
341public:
342 LLMessageTemplate(const char *name, U32 message_number, EMsgFrequency freq)
343 :
344 //mMemberBlocks(),
345 mName(NULL),
346 mFrequency(freq),
347 mTrust(MT_NOTRUST),
348 mEncoding(ME_ZEROCODED),
349 mMessageNumber(message_number),
350 mTotalSize(0),
351 mReceiveCount(0),
352 mReceiveBytes(0),
353 mReceiveInvalid(0),
354 mDecodeTimeThisFrame(0.f),
355 mTotalDecoded(0),
356 mTotalDecodeTime(0.f),
357 mMaxDecodeTimePerMsg(0.f),
358 mBanFromTrusted(false),
359 mBanFromUntrusted(false),
360 mHandlerFunc(NULL),
361 mUserData(NULL)
362 {
363 mName = gMessageStringTable.getString(name);
364 }
365
366 ~LLMessageTemplate()
367 {
368 for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer());
369 }
370
371 void addBlock(LLMessageBlock *blockp)
372 {
373 LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName];
374 if (*member_blockp != NULL)
375 {
376 llerrs << "Block " << blockp->mName
377 << "has already been used as a block name!" << llendl;
378 }
379 *member_blockp = blockp;
380 if ( (mTotalSize != -1)
381 &&(blockp->mTotalSize != -1)
382 &&( (blockp->mType == MBT_SINGLE)
383 ||(blockp->mType == MBT_MULTIPLE)))
384 {
385 mTotalSize += blockp->mNumber*blockp->mTotalSize;
386 }
387 else
388 {
389 mTotalSize = -1;
390 }
391 }
392
393 LLMessageBlock *getBlock(char *name)
394 {
395 return mMemberBlocks[name];
396 }
397
398 // Trusted messages can only be recieved on trusted circuits.
399 void setTrust(EMsgTrust t)
400 {
401 mTrust = t;
402 }
403
404 EMsgTrust getTrust(void)
405 {
406 return mTrust;
407 }
408
409 // controls for how the message should be encoded
410 void setEncoding(EMsgEncoding e)
411 {
412 mEncoding = e;
413 }
414 EMsgEncoding getEncoding()
415 {
416 return mEncoding;
417 }
418
419 void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data)
420 {
421 mHandlerFunc = handler_func;
422 mUserData = user_data;
423 }
424
425 BOOL callHandlerFunc(LLMessageSystem *msgsystem)
426 {
427 if (mHandlerFunc)
428 {
429 mHandlerFunc(msgsystem, mUserData);
430 return TRUE;
431 }
432 return FALSE;
433 }
434
435 bool isBanned(bool trustedSource)
436 {
437 return trustedSource ? mBanFromTrusted : mBanFromUntrusted;
438 }
439
440 friend std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg);
441
442public:
443 typedef std::map<char*, LLMessageBlock*> message_block_map_t;
444 message_block_map_t mMemberBlocks;
445 char *mName;
446 EMsgFrequency mFrequency;
447 EMsgTrust mTrust;
448 EMsgEncoding mEncoding;
449 U32 mMessageNumber;
450 S32 mTotalSize;
451 U32 mReceiveCount; // how many of this template have been received since last reset
452 U32 mReceiveBytes; // How many bytes received
453 U32 mReceiveInvalid; // How many "invalid" packets
454 F32 mDecodeTimeThisFrame; // Total seconds spent decoding this frame
455 U32 mTotalDecoded; // Total messages successfully decoded
456 F32 mTotalDecodeTime; // Total time successfully decoding messages
457 F32 mMaxDecodeTimePerMsg;
458
459 bool mBanFromTrusted;
460 bool mBanFromUntrusted;
461
462private:
463 // message handler function (this is set by each application)
464 void (*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data);
465 void **mUserData;
466};
467
468
469
470// static
471BOOL LLMessageSystem::mTimeDecodes = FALSE;
472
473// static, 50ms per message decode
474F32 LLMessageSystem::mTimeDecodesSpamThreshold = 0.05f;
475
476// *NOTE: This needs to be moved into a seperate file so that it never gets 89// *NOTE: This needs to be moved into a seperate file so that it never gets
477// included in the viewer. 30 Sep 2002 mark 90// included in the viewer. 30 Sep 2002 mark
478// *NOTE: I don't think it's important that the messgage system tracks 91// *NOTE: I don't think it's important that the messgage system tracks
@@ -487,113 +100,6 @@ public:
487 apr_pollfd_t mPollFD; 100 apr_pollfd_t mPollFD;
488}; 101};
489 102
490
491// LLMessageVariable functions and friends
492
493std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg)
494{
495 s << "\t\t" << msg.mName << " (";
496 switch (msg.mType)
497 {
498 case MVT_FIXED:
499 s << "Fixed, " << msg.mSize << " bytes total)\n";
500 break;
501 case MVT_VARIABLE:
502 s << "Variable, " << msg.mSize << " bytes of size info)\n";
503 break;
504 default:
505 s << "Unknown\n";
506 break;
507 }
508 return s;
509}
510
511// LLMessageBlock functions and friends
512
513std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg)
514{
515 s << "\t" << msg.mName << " (";
516 switch (msg.mType)
517 {
518 case MBT_SINGLE:
519 s << "Fixed";
520 break;
521 case MBT_MULTIPLE:
522 s << "Multiple - " << msg.mNumber << " copies";
523 break;
524 case MBT_VARIABLE:
525 s << "Variable";
526 break;
527 default:
528 s << "Unknown";
529 break;
530 }
531 if (msg.mTotalSize != -1)
532 {
533 s << ", " << msg.mTotalSize << " bytes each, " << msg.mNumber*msg.mTotalSize << " bytes total)\n";
534 }
535 else
536 {
537 s << ")\n";
538 }
539
540
541 for (LLMessageBlock::message_variable_map_t::iterator iter = msg.mMemberVariables.begin();
542 iter != msg.mMemberVariables.end(); iter++)
543 {
544 LLMessageVariable& ci = *(iter->second);
545 s << ci;
546 }
547
548 return s;
549}
550
551// LLMessageTemplate functions and friends
552
553std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg)
554{
555 switch (msg.mFrequency)
556 {
557 case MFT_HIGH:
558 s << "========================================\n" << "Message #" << msg.mMessageNumber << "\n" << msg.mName << " (";
559 s << "High";
560 break;
561 case MFT_MEDIUM:
562 s << "========================================\n" << "Message #";
563 s << (msg.mMessageNumber & 0xFF) << "\n" << msg.mName << " (";
564 s << "Medium";
565 break;
566 case MFT_LOW:
567 s << "========================================\n" << "Message #";
568 s << (msg.mMessageNumber & 0xFFFF) << "\n" << msg.mName << " (";
569 s << "Low";
570 break;
571 default:
572 s << "Unknown";
573 break;
574 }
575
576 if (msg.mTotalSize != -1)
577 {
578 s << ", " << msg.mTotalSize << " bytes total)\n";
579 }
580 else
581 {
582 s << ")\n";
583 }
584
585 for (LLMessageTemplate::message_block_map_t::iterator iter = msg.mMemberBlocks.begin();
586 iter != msg.mMemberBlocks.end(); iter++)
587 {
588 LLMessageBlock* ci = iter->second;
589 s << *ci;
590 }
591
592 return s;
593}
594
595// LLMessageList functions and friends
596
597// Lets support a small subset of regular expressions here 103// Lets support a small subset of regular expressions here
598// Syntax is a string made up of: 104// Syntax is a string made up of:
599// a - checks against alphanumeric ([A-Za-z0-9]) 105// a - checks against alphanumeric ([A-Za-z0-9])
@@ -795,6 +301,106 @@ BOOL b_positive_integer_ok(char *token)
795 return TRUE; 301 return TRUE;
796} 302}
797 303
304namespace
305{
306 class LLFnPtrResponder : public LLHTTPClient::Responder
307 {
308 public:
309 LLFnPtrResponder(void (*callback)(void **,S32), void **callbackData) :
310 mCallback(callback),
311 mCallbackData(callbackData)
312 {
313 }
314
315 virtual void error(U32 status, const std::string& reason)
316 {
317 // TODO: Map status in to useful error code.
318 if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT);
319 }
320
321 virtual void result(const LLSD& content)
322 {
323 if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_NOERR);
324 }
325
326 private:
327
328 void (*mCallback)(void **,S32);
329 void **mCallbackData;
330 };
331}
332
333
334class LLTrustedMessageService : public LLHTTPNode
335{
336 virtual bool validate(const std::string& name, LLSD& context) const
337 { return true; }
338
339 virtual void post(LLHTTPNode::ResponsePtr response,
340 const LLSD& context,
341 const LLSD& input) const;
342};
343
344//virtual
345void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response,
346 const LLSD& context,
347 const LLSD& input) const
348{
349 std::string name = context["request"]["wildcard"]["message-name"];
350 std::string senderIP = context["request"]["remote-host"];
351 std::string senderPort = context["request"]["headers"]
352 ["x-secondlife-udp-listen-port"];
353
354 LLSD message_data;
355 message_data["sender"] = senderIP + ":" + senderPort;
356 message_data["body"] = input;
357
358 LLMessageSystem::dispatch(name, message_data, response);
359}
360
361class LLMessageHandlerBridge : public LLHTTPNode
362{
363 virtual bool validate(const std::string& name, LLSD& context) const
364 { return true; }
365
366 virtual void post(LLHTTPNode::ResponsePtr response, const LLSD& context,
367 const LLSD& input) const;
368};
369
370//virtual
371void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,
372 const LLSD& context, const LLSD& input) const
373{
374 std::string name = context["request"]["wildcard"]["message-name"];
375
376 lldebugs << "Setting mLastSender " << input["sender"].asString() << llendl;
377 gMessageSystem->mLastSender = LLHost(input["sender"].asString());
378 gMessageSystem->mPacketsIn += 1;
379 gMessageSystem->mLLSDMessageReader->setMessage(name, input["body"]);
380 gMessageSystem->mMessageReader = gMessageSystem->mLLSDMessageReader;
381
382 if(gMessageSystem->callHandler(name.c_str(), false, gMessageSystem))
383 {
384 response->result(LLSD());
385 }
386 else
387 {
388 response->notFound();
389 }
390}
391
392LLHTTPRegistration<LLMessageHandlerBridge>
393 gHTTPRegistrationMessageWildcard("/message/<message-name>");
394
395LLHTTPRegistration<LLTrustedMessageService>
396 gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>");
397
398//virtual
399LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder()
400{
401 // even abstract base classes need a concrete destructor
402}
403
798void LLMessageSystem::init() 404void LLMessageSystem::init()
799{ 405{
800 // initialize member variables 406 // initialize member variables
@@ -802,25 +408,12 @@ void LLMessageSystem::init()
802 408
803 mbError = FALSE; 409 mbError = FALSE;
804 mErrorCode = 0; 410 mErrorCode = 0;
805 mIncomingCompressedSize = 0;
806 mSendReliable = FALSE; 411 mSendReliable = FALSE;
807 412
808 mbSBuilt = FALSE;
809 mbSClear = TRUE;
810
811 mUnackedListDepth = 0; 413 mUnackedListDepth = 0;
812 mUnackedListSize = 0; 414 mUnackedListSize = 0;
813 mDSMaxListDepth = 0; 415 mDSMaxListDepth = 0;
814 416
815 mCurrentRMessageData = NULL;
816 mCurrentRMessageTemplate = NULL;
817
818 mCurrentSMessageData = NULL;
819 mCurrentSMessageTemplate = NULL;
820 mCurrentSMessageName = NULL;
821
822 mCurrentRecvPacketID = 0;
823
824 mNumberHighFreqMessages = 0; 417 mNumberHighFreqMessages = 0;
825 mNumberMediumFreqMessages = 0; 418 mNumberMediumFreqMessages = 0;
826 mNumberLowFreqMessages = 0; 419 mNumberLowFreqMessages = 0;
@@ -844,54 +437,26 @@ void LLMessageSystem::init()
844 437
845 mOurCircuitCode = 0; 438 mOurCircuitCode = 0;
846 439
440 mIncomingCompressedSize = 0;
441 mCurrentRecvPacketID = 0;
442
847 mMessageFileChecksum = 0; 443 mMessageFileChecksum = 0;
848 mMessageFileVersionNumber = 0.f; 444 mMessageFileVersionNumber = 0.f;
849}
850
851LLMessageSystem::LLMessageSystem()
852{
853 init();
854 445
855 mSystemVersionMajor = 0; 446 mTimingCallback = NULL;
856 mSystemVersionMinor = 0; 447 mTimingCallbackData = NULL;
857 mSystemVersionPatch = 0;
858 mSystemVersionServer = 0;
859 mVersionFlags = 0x0;
860
861 // default to not accepting packets from not alive circuits
862 mbProtected = TRUE;
863 448
864 mSendPacketFailureCount = 0; 449 mMessageBuilder = NULL;
865 mCircuitPrintFreq = 0.f; // seconds 450 mMessageReader = NULL;
866
867 // initialize various bits of net info
868 mSocket = 0;
869 mPort = 0;
870
871 mPollInfop = NULL;
872
873 mResendDumpTime = 0;
874 mMessageCountTime = 0;
875 mCircuitPrintTime = 0;
876 mCurrentMessageTimeSeconds = 0;
877
878 // Constants for dumping output based on message processing time/count
879 mNumMessageCounts = 0;
880 mMaxMessageCounts = 0; // >= 0 means dump warnings
881 mMaxMessageTime = 0.f;
882
883 mTrueReceiveSize = 0;
884
885 // Error if checking this state, subclass methods which aren't implemented are delegated
886 // to properly constructed message system.
887 mbError = TRUE;
888} 451}
889 452
890// Read file and build message templates 453// Read file and build message templates
891LLMessageSystem::LLMessageSystem(const char *filename, U32 port, 454LLMessageSystem::LLMessageSystem(const char *filename, U32 port,
892 S32 version_major, 455 S32 version_major,
893 S32 version_minor, 456 S32 version_minor,
894 S32 version_patch) 457 S32 version_patch) :
458 mTemplateConfirmed(FALSE),
459 mTemplateMatches(FALSE)
895{ 460{
896 init(); 461 init();
897 462
@@ -910,6 +475,14 @@ LLMessageSystem::LLMessageSystem(const char *filename, U32 port,
910 475
911 loadTemplateFile(filename); 476 loadTemplateFile(filename);
912 477
478 mTemplateMessageBuilder = new LLTemplateMessageBuilder(mMessageTemplates);
479 mLLSDMessageBuilder = new LLSDMessageBuilder();
480 mMessageBuilder = NULL;
481
482 mTemplateMessageReader = new LLTemplateMessageReader(mMessageNumbers);
483 mLLSDMessageReader = new LLSDMessageReader();
484 mMessageReader = NULL;
485
913 // initialize various bits of net info 486 // initialize various bits of net info
914 mSocket = 0; 487 mSocket = 0;
915 mPort = port; 488 mPort = port;
@@ -1728,25 +1301,25 @@ LLMessageSystem::~LLMessageSystem()
1728 end_net(); 1301 end_net();
1729 } 1302 }
1730 1303
1731 delete mCurrentRMessageData; 1304 delete mMessageReader;
1732 mCurrentRMessageData = NULL; 1305 mMessageReader = NULL;
1733 1306
1734 delete mCurrentSMessageData; 1307 delete mMessageBuilder;
1735 mCurrentSMessageData = NULL; 1308 mMessageBuilder = NULL;
1736 1309
1737 delete mPollInfop; 1310 delete mPollInfop;
1738 mPollInfop = NULL; 1311 mPollInfop = NULL;
1312
1313 mIncomingCompressedSize = 0;
1314 mCurrentRecvPacketID = 0;
1739} 1315}
1740 1316
1741void LLMessageSystem::clearReceiveState() 1317void LLMessageSystem::clearReceiveState()
1742{ 1318{
1743 mReceiveSize = -1;
1744 mCurrentRecvPacketID = 0; 1319 mCurrentRecvPacketID = 0;
1745 mCurrentRMessageTemplate = NULL;
1746 delete mCurrentRMessageData;
1747 mCurrentRMessageData = NULL;
1748 mIncomingCompressedSize = 0; 1320 mIncomingCompressedSize = 0;
1749 mLastSender.invalidate(); 1321 mLastSender.invalidate();
1322 mMessageReader->clearMessage();
1750} 1323}
1751 1324
1752 1325
@@ -1773,20 +1346,23 @@ BOOL LLMessageSystem::poll(F32 seconds)
1773// Returns TRUE if a valid, on-circuit message has been received. 1346// Returns TRUE if a valid, on-circuit message has been received.
1774BOOL LLMessageSystem::checkMessages( S64 frame_count ) 1347BOOL LLMessageSystem::checkMessages( S64 frame_count )
1775{ 1348{
1349 // Pump
1776 BOOL valid_packet = FALSE; 1350 BOOL valid_packet = FALSE;
1351 mMessageReader = mTemplateMessageReader;
1777 1352
1778 LLTransferTargetVFile::updateQueue(); 1353 LLTransferTargetVFile::updateQueue();
1779 1354
1780 if (!mNumMessageCounts) 1355 if (!mNumMessageCounts)
1781 { 1356 {
1782 // This is the first message being handled after a resetReceiveCounts, we must be starting 1357 // This is the first message being handled after a resetReceiveCounts,
1783 // the message processing loop. Reset the timers. 1358 // we must be starting the message processing loop. Reset the timers.
1784 mCurrentMessageTimeSeconds = totalTime() * SEC_PER_USEC; 1359 mCurrentMessageTimeSeconds = totalTime() * SEC_PER_USEC;
1785 mMessageCountTime = getMessageTimeSeconds(); 1360 mMessageCountTime = getMessageTimeSeconds();
1786 } 1361 }
1787 1362
1788 // loop until either no packets or a valid packet 1363 // loop until either no packets or a valid packet
1789 // i.e., burn through packets from unregistered circuits 1364 // i.e., burn through packets from unregistered circuits
1365 S32 receive_size = 0;
1790 do 1366 do
1791 { 1367 {
1792 clearReceiveState(); 1368 clearReceiveState();
@@ -1802,16 +1378,16 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
1802 // If you want to dump all received packets into SecondLife.log, uncomment this 1378 // If you want to dump all received packets into SecondLife.log, uncomment this
1803 //dumpPacketToLog(); 1379 //dumpPacketToLog();
1804 1380
1805 mReceiveSize = mTrueReceiveSize; 1381 receive_size = mTrueReceiveSize;
1806 mLastSender = mPacketRing.getLastSender(); 1382 mLastSender = mPacketRing.getLastSender();
1807 1383
1808 if (mReceiveSize < (S32) LL_MINIMUM_VALID_PACKET_SIZE) 1384 if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE)
1809 { 1385 {
1810 // A receive size of zero is OK, that means that there are no more packets available. 1386 // A receive size of zero is OK, that means that there are no more packets available.
1811 // Ones that are non-zero but below the minimum packet size are worrisome. 1387 // Ones that are non-zero but below the minimum packet size are worrisome.
1812 if (mReceiveSize > 0) 1388 if (receive_size > 0)
1813 { 1389 {
1814 llwarns << "Invalid (too short) packet discarded " << mReceiveSize << llendl; 1390 llwarns << "Invalid (too short) packet discarded " << receive_size << llendl;
1815 callExceptionFunc(MX_PACKET_TOO_SHORT); 1391 callExceptionFunc(MX_PACKET_TOO_SHORT);
1816 } 1392 }
1817 // no data in packet receive buffer 1393 // no data in packet receive buffer
@@ -1825,18 +1401,18 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
1825 // note if packet acks are appended. 1401 // note if packet acks are appended.
1826 if(buffer[0] & LL_ACK_FLAG) 1402 if(buffer[0] & LL_ACK_FLAG)
1827 { 1403 {
1828 acks += buffer[--mReceiveSize]; 1404 acks += buffer[--receive_size];
1829 true_rcv_size = mReceiveSize; 1405 true_rcv_size = receive_size;
1830 if(mReceiveSize >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE))) 1406 if(receive_size >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE)))
1831 { 1407 {
1832 mReceiveSize -= acks * sizeof(TPACKETID); 1408 receive_size -= acks * sizeof(TPACKETID);
1833 } 1409 }
1834 else 1410 else
1835 { 1411 {
1836 // mal-formed packet. ignore it and continue with 1412 // mal-formed packet. ignore it and continue with
1837 // the next one 1413 // the next one
1838 llwarns << "Malformed packet received. Packet size " 1414 llwarns << "Malformed packet received. Packet size "
1839 << mReceiveSize << " with invalid no. of acks " << acks 1415 << receive_size << " with invalid no. of acks " << acks
1840 << llendl; 1416 << llendl;
1841 valid_packet = FALSE; 1417 valid_packet = FALSE;
1842 continue; 1418 continue;
@@ -1845,7 +1421,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
1845 1421
1846 // process the message as normal 1422 // process the message as normal
1847 1423
1848 mIncomingCompressedSize = zeroCodeExpand(&buffer,&mReceiveSize); 1424 mIncomingCompressedSize = zeroCodeExpand(&buffer,&receive_size);
1849 mCurrentRecvPacketID = buffer[1] + ((buffer[0] & 0x0f ) * 256); 1425 mCurrentRecvPacketID = buffer[1] + ((buffer[0] & 0x0f ) * 256);
1850 if (sizeof(TPACKETID) == 4) 1426 if (sizeof(TPACKETID) == 4)
1851 { 1427 {
@@ -1969,7 +1545,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
1969 std::ostringstream str; 1545 std::ostringstream str;
1970 str << "MSG: <- " << host; 1546 str << "MSG: <- " << host;
1971 char buffer[MAX_STRING]; /* Flawfinder: ignore*/ 1547 char buffer[MAX_STRING]; /* Flawfinder: ignore*/
1972 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize : mReceiveSize), mCurrentRecvPacketID);/* Flawfinder: ignore*/ 1548 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", receive_size, (mIncomingCompressedSize ? mIncomingCompressedSize : receive_size), mCurrentRecvPacketID); /* Flawfinder: ignore */
1973 str << buffer << "(unknown)" 1549 str << buffer << "(unknown)"
1974 << (recv_reliable ? " reliable" : "") 1550 << (recv_reliable ? " reliable" : "")
1975 << " resent " 1551 << " resent "
@@ -1987,23 +1563,22 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
1987 // But we don't want to acknowledge UseCircuitCode until the circuit is 1563 // But we don't want to acknowledge UseCircuitCode until the circuit is
1988 // available, which is why the acknowledgement test is done above. JC 1564 // available, which is why the acknowledgement test is done above. JC
1989 1565
1990 valid_packet = decodeTemplate( buffer, mReceiveSize, &mCurrentRMessageTemplate ); 1566 valid_packet = mTemplateMessageReader->validateMessage(buffer,
1991 if( valid_packet ) 1567 receive_size,
1992 { 1568 host);
1993 mCurrentRMessageTemplate->mReceiveCount++;
1994 lldebugst(LLERR_MESSAGE) << "MessageRecvd:" << mCurrentRMessageTemplate->mName << " from " << host << llendl;
1995 }
1996 1569
1997 // UseCircuitCode is allowed in even from an invalid circuit, so that 1570 // UseCircuitCode is allowed in even from an invalid circuit, so that
1998 // we can toss circuits around. 1571 // we can toss circuits around.
1999 if (valid_packet && !cdp && (mCurrentRMessageTemplate->mName != _PREHASH_UseCircuitCode) ) 1572 if(valid_packet && !cdp &&
1573 (mTemplateMessageReader->getMessageName() != _PREHASH_UseCircuitCode))
2000 { 1574 {
2001 logMsgFromInvalidCircuit( host, recv_reliable ); 1575 logMsgFromInvalidCircuit( host, recv_reliable );
2002 clearReceiveState(); 1576 clearReceiveState();
2003 valid_packet = FALSE; 1577 valid_packet = FALSE;
2004 } 1578 }
2005 1579
2006 if (valid_packet && cdp && !cdp->getTrusted() && (mCurrentRMessageTemplate->getTrust() == MT_TRUST) ) 1580 if(valid_packet && cdp && !cdp->getTrusted() &&
1581 mTemplateMessageReader->isTrusted())
2007 { 1582 {
2008 logTrustedMsgFromUntrustedCircuit( host ); 1583 logTrustedMsgFromUntrustedCircuit( host );
2009 clearReceiveState(); 1584 clearReceiveState();
@@ -2013,11 +1588,11 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
2013 } 1588 }
2014 1589
2015 if (valid_packet 1590 if (valid_packet
2016 && mCurrentRMessageTemplate->isBanned(cdp && cdp->getTrusted())) 1591 && mTemplateMessageReader->isBanned(cdp && cdp->getTrusted()))
2017 { 1592 {
2018 llwarns << "LLMessageSystem::checkMessages " 1593 llwarns << "LLMessageSystem::checkMessages "
2019 << "received banned message " 1594 << "received banned message "
2020 << mCurrentRMessageTemplate->mName 1595 << mTemplateMessageReader->getMessageName()
2021 << " from " 1596 << " from "
2022 << ((cdp && cdp->getTrusted()) ? "trusted " : "untrusted ") 1597 << ((cdp && cdp->getTrusted()) ? "trusted " : "untrusted ")
2023 << host << llendl; 1598 << host << llendl;
@@ -2029,7 +1604,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
2029 { 1604 {
2030 logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) ); 1605 logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) );
2031 1606
2032 valid_packet = decodeData( buffer, host ); 1607 valid_packet = mTemplateMessageReader->readMessage(buffer, host);
2033 } 1608 }
2034 1609
2035 // It's possible that the circuit went away, because ANY message can disable the circuit 1610 // It's possible that the circuit went away, because ANY message can disable the circuit
@@ -2042,7 +1617,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
2042 if( 1 ) 1617 if( 1 )
2043 { 1618 {
2044 static char* object_update = gMessageStringTable.getString("ObjectUpdate"); 1619 static char* object_update = gMessageStringTable.getString("ObjectUpdate");
2045 if(object_update == mCurrentRMessageTemplate->mName ) 1620 if(object_update == mTemplateMessageReader->getMessageName() )
2046 { 1621 {
2047 llinfos << "ObjectUpdate:" << llendl; 1622 llinfos << "ObjectUpdate:" << llendl;
2048 U32 i; 1623 U32 i;
@@ -2053,8 +1628,8 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
2053 } 1628 }
2054 llinfos << "" << llendl; 1629 llinfos << "" << llendl;
2055 1630
2056 llinfos << " Zero Unencoded: " << mReceiveSize << llendl; 1631 llinfos << " Zero Unencoded: " << receive_size << llendl;
2057 for( i = 0; i<mReceiveSize; i++ ) 1632 for( i = 0; i<receive_size; i++ )
2058 { 1633 {
2059 llinfos << " " << i << ": " << (U32) buffer[i] << llendl; 1634 llinfos << " " << i << ": " << (U32) buffer[i] << llendl;
2060 } 1635 }
@@ -2143,7 +1718,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
2143 if (mbProtected && (!cdp)) 1718 if (mbProtected && (!cdp))
2144 { 1719 {
2145 llwarns << "Packet " 1720 llwarns << "Packet "
2146 << (mCurrentRMessageTemplate ? mCurrentRMessageTemplate->mName : "") 1721 << mTemplateMessageReader->getMessageName()
2147 << " from invalid circuit " << host << llendl; 1722 << " from invalid circuit " << host << llendl;
2148 mOffCircuitPackets++; 1723 mOffCircuitPackets++;
2149 } 1724 }
@@ -2156,7 +1731,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
2156 // Code for dumping the complete contents of a message 1731 // Code for dumping the complete contents of a message
2157 // delete [] zero_unexpanded_buffer; 1732 // delete [] zero_unexpanded_buffer;
2158 } 1733 }
2159 } while (!valid_packet && mReceiveSize > 0); 1734 } while (!valid_packet && receive_size > 0);
2160 1735
2161 F64 mt_sec = getMessageTimeSeconds(); 1736 F64 mt_sec = getMessageTimeSeconds();
2162 // Check to see if we need to print debug info 1737 // Check to see if we need to print debug info
@@ -2257,600 +1832,56 @@ void LLMessageSystem::processAcks()
2257 } 1832 }
2258} 1833}
2259 1834
2260
2261void LLMessageSystem::newMessageFast(const char *name)
2262{
2263 mbSBuilt = FALSE;
2264 mbSClear = FALSE;
2265
2266 mCurrentSendTotal = 0;
2267 mSendReliable = FALSE;
2268
2269 char *namep = (char *)name;
2270
2271 if (mMessageTemplates.count(namep) > 0)
2272 {
2273 mCurrentSMessageTemplate = mMessageTemplates[namep];
2274 if (mCurrentSMessageData)
2275 {
2276 delete mCurrentSMessageData;
2277 }
2278 mCurrentSMessageData = new LLMsgData(namep);
2279 mCurrentSMessageName = namep;
2280 mCurrentSDataBlock = NULL;
2281 mCurrentSBlockName = NULL;
2282
2283 // add at one of each block
2284 LLMessageTemplate* msg_template = mMessageTemplates[namep];
2285 for (LLMessageTemplate::message_block_map_t::iterator iter = msg_template->mMemberBlocks.begin();
2286 iter != msg_template->mMemberBlocks.end(); iter++)
2287 {
2288 LLMessageBlock* ci = iter->second;
2289 LLMsgBlkData *tblockp;
2290 tblockp = new LLMsgBlkData(ci->mName, 0);
2291 mCurrentSMessageData->addBlock(tblockp);
2292 }
2293 }
2294 else
2295 {
2296 llerrs << "newMessage - Message " << name << " not registered" << llendl;
2297 }
2298}
2299
2300void LLMessageSystem::copyMessageRtoS() 1835void LLMessageSystem::copyMessageRtoS()
2301{ 1836{
2302 if (!mCurrentRMessageTemplate) 1837 // NOTE: babbage: switch builder to match reader to avoid
1838 // converting message format
1839 if(mMessageReader == mTemplateMessageReader)
2303 { 1840 {
2304 return; 1841 mMessageBuilder = mTemplateMessageBuilder;
2305 } 1842 }
2306 newMessageFast(mCurrentRMessageTemplate->mName); 1843 else
2307
2308 // copy the blocks
2309 // counting variables used to encode multiple block info
2310 S32 block_count = 0;
2311 char *block_name = NULL;
2312
2313 // loop through msg blocks to loop through variables, totalling up size data and filling the new (send) message
2314 LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.begin();
2315 LLMsgData::msg_blk_data_map_t::iterator end = mCurrentRMessageData->mMemberBlocks.end();
2316 for(; iter != end; ++iter)
2317 { 1844 {
2318 LLMsgBlkData* mbci = iter->second; 1845 mMessageBuilder = mLLSDMessageBuilder;
2319 if(!mbci) continue;
2320
2321 // do we need to encode a block code?
2322 if (block_count == 0)
2323 {
2324 block_count = mbci->mBlockNumber;
2325 block_name = (char *)mbci->mName;
2326 }
2327
2328 // counting down mutliple blocks
2329 block_count--;
2330
2331 nextBlockFast(block_name);
2332
2333 // now loop through the variables
2334 LLMsgBlkData::msg_var_data_map_t::iterator dit = mbci->mMemberVarData.begin();
2335 LLMsgBlkData::msg_var_data_map_t::iterator dend = mbci->mMemberVarData.end();
2336
2337 for(; dit != dend; ++dit)
2338 {
2339 LLMsgVarData& mvci = *dit;
2340 addDataFast(mvci.getName(), mvci.getData(), mvci.getType(), mvci.getSize());
2341 }
2342 } 1846 }
1847 mSendReliable = FALSE;
1848 mMessageBuilder->newMessage(mMessageReader->getMessageName());
1849 mMessageReader->copyToBuilder(*mMessageBuilder);
2343} 1850}
2344 1851
2345void LLMessageSystem::clearMessage() 1852void LLMessageSystem::clearMessage()
2346{ 1853{
2347 mbSBuilt = FALSE;
2348 mbSClear = TRUE;
2349
2350 mCurrentSendTotal = 0;
2351 mSendReliable = FALSE; 1854 mSendReliable = FALSE;
2352 1855 mMessageBuilder->clearMessage();
2353 mCurrentSMessageTemplate = NULL;
2354
2355 delete mCurrentSMessageData;
2356 mCurrentSMessageData = NULL;
2357
2358 mCurrentSMessageName = NULL;
2359 mCurrentSDataBlock = NULL;
2360 mCurrentSBlockName = NULL;
2361} 1856}
2362 1857
2363
2364// set block to add data to within current message 1858// set block to add data to within current message
2365void LLMessageSystem::nextBlockFast(const char *blockname) 1859void LLMessageSystem::nextBlockFast(const char *blockname)
2366{ 1860{
2367 char *bnamep = (char *)blockname; 1861 mMessageBuilder->nextBlock(blockname);
2368
2369 if (!mCurrentSMessageTemplate)
2370 {
2371 llerrs << "newMessage not called prior to setBlock" << llendl;
2372 return;
2373 }
2374
2375 // now, does this block exist?
2376 LLMessageTemplate::message_block_map_t::iterator temp_iter = mCurrentSMessageTemplate->mMemberBlocks.find(bnamep);
2377 if (temp_iter == mCurrentSMessageTemplate->mMemberBlocks.end())
2378 {
2379 llerrs << "LLMessageSystem::nextBlockFast " << bnamep
2380 << " not a block in " << mCurrentSMessageTemplate->mName << llendl;
2381 return;
2382 }
2383
2384 LLMessageBlock* template_data = temp_iter->second;
2385
2386 // ok, have we already set this block?
2387 LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep];
2388 if (block_data->mBlockNumber == 0)
2389 {
2390 // nope! set this as the current block
2391 block_data->mBlockNumber = 1;
2392 mCurrentSDataBlock = block_data;
2393 mCurrentSBlockName = bnamep;
2394
2395 // add placeholders for each of the variables
2396 for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin();
2397 iter != template_data->mMemberVariables.end(); iter++)
2398 {
2399 LLMessageVariable& ci = *(iter->second);
2400 mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
2401 }
2402 return;
2403 }
2404 else
2405 {
2406 // already have this block. . .
2407 // are we supposed to have a new one?
2408
2409 // if the block is type MBT_SINGLE this is bad!
2410 if (template_data->mType == MBT_SINGLE)
2411 {
2412 llerrs << "LLMessageSystem::nextBlockFast called multiple times"
2413 << " for " << bnamep << " but is type MBT_SINGLE" << llendl;
2414 return;
2415 }
2416
2417
2418 // if the block is type MBT_MULTIPLE then we need a known number, make sure that we're not exceeding it
2419 if ( (template_data->mType == MBT_MULTIPLE)
2420 &&(mCurrentSDataBlock->mBlockNumber == template_data->mNumber))
2421 {
2422 llerrs << "LLMessageSystem::nextBlockFast called "
2423 << mCurrentSDataBlock->mBlockNumber << " times for " << bnamep
2424 << " exceeding " << template_data->mNumber
2425 << " specified in type MBT_MULTIPLE." << llendl;
2426 return;
2427 }
2428
2429 // ok, we can make a new one
2430 // modify the name to avoid name collision by adding number to end
2431 S32 count = block_data->mBlockNumber;
2432
2433 // incrememt base name's count
2434 block_data->mBlockNumber++;
2435
2436 if (block_data->mBlockNumber > MAX_BLOCKS)
2437 {
2438 llerrs << "Trying to pack too many blocks into MBT_VARIABLE type (limited to " << MAX_BLOCKS << ")" << llendl;
2439 }
2440
2441 // create new name
2442 // Nota Bene: if things are working correctly, mCurrentMessageData->mMemberBlocks[blockname]->mBlockNumber == mCurrentDataBlock->mBlockNumber + 1
2443
2444 char *nbnamep = bnamep + count;
2445
2446 mCurrentSDataBlock = new LLMsgBlkData(bnamep, count);
2447 mCurrentSDataBlock->mName = nbnamep;
2448 mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock;
2449
2450 // add placeholders for each of the variables
2451 for (LLMessageBlock::message_variable_map_t::iterator
2452 iter = template_data->mMemberVariables.begin(),
2453 end = template_data->mMemberVariables.end();
2454 iter != end; iter++)
2455 {
2456 LLMessageVariable& ci = *(iter->second);
2457 mCurrentSDataBlock->addVariable(ci.getName(), ci.getType());
2458 }
2459 return;
2460 }
2461}
2462
2463// add data to variable in current block
2464void LLMessageSystem::addDataFast(const char *varname, const void *data, EMsgVariableType type, S32 size)
2465{
2466 char *vnamep = (char *)varname;
2467
2468 // do we have a current message?
2469 if (!mCurrentSMessageTemplate)
2470 {
2471 llerrs << "newMessage not called prior to addData" << llendl;
2472 return;
2473 }
2474
2475 // do we have a current block?
2476 if (!mCurrentSDataBlock)
2477 {
2478 llerrs << "setBlock not called prior to addData" << llendl;
2479 return;
2480 }
2481
2482 // kewl, add the data if it exists
2483 LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep];
2484 if (!var_data || !var_data->getName())
2485 {
2486 llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
2487 return;
2488 }
2489
2490 // ok, it seems ok. . . are we the correct size?
2491 if (var_data->getType() == MVT_VARIABLE)
2492 {
2493 // Variable 1 can only store 255 bytes, make sure our data is smaller
2494 if ((var_data->getSize() == 1) &&
2495 (size > 255))
2496 {
2497 llwarns << "Field " << varname << " is a Variable 1 but program "
2498 << "attempted to stuff more than 255 bytes in "
2499 << "(" << size << "). Clamping size and truncating data." << llendl;
2500 size = 255;
2501 char *truncate = (char *)data;
2502 truncate[255] = 0;
2503 }
2504
2505 // no correct size for MVT_VARIABLE, instead we need to tell how many bytes the size will be encoded as
2506 mCurrentSDataBlock->addData(vnamep, data, size, type, var_data->getSize());
2507 mCurrentSendTotal += size;
2508 }
2509 else
2510 {
2511 if (size != var_data->getSize())
2512 {
2513 llerrs << varname << " is type MVT_FIXED but request size " << size << " doesn't match template size "
2514 << var_data->getSize() << llendl;
2515 return;
2516 }
2517 // alright, smash it in
2518 mCurrentSDataBlock->addData(vnamep, data, size, type);
2519 mCurrentSendTotal += size;
2520 }
2521}
2522
2523// add data to variable in current block - fails if variable isn't MVT_FIXED
2524void LLMessageSystem::addDataFast(const char *varname, const void *data, EMsgVariableType type)
2525{
2526 char *vnamep = (char *)varname;
2527
2528 // do we have a current message?
2529 if (!mCurrentSMessageTemplate)
2530 {
2531 llerrs << "newMessage not called prior to addData" << llendl;
2532 return;
2533 }
2534
2535 // do we have a current block?
2536 if (!mCurrentSDataBlock)
2537 {
2538 llerrs << "setBlock not called prior to addData" << llendl;
2539 return;
2540 }
2541
2542 // kewl, add the data if it exists
2543 LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep];
2544 if (!var_data->getName())
2545 {
2546 llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl;
2547 return;
2548 }
2549
2550 // ok, it seems ok. . . are we MVT_VARIABLE?
2551 if (var_data->getType() == MVT_VARIABLE)
2552 {
2553 // nope
2554 llerrs << vnamep << " is type MVT_VARIABLE. Call using addData(name, data, size)" << llendl;
2555 return;
2556 }
2557 else
2558 {
2559 mCurrentSDataBlock->addData(vnamep, data, var_data->getSize(), type);
2560 mCurrentSendTotal += var_data->getSize();
2561 }
2562} 1862}
2563 1863
2564BOOL LLMessageSystem::isSendFull(const char* blockname) 1864BOOL LLMessageSystem::isSendFull(const char* blockname)
2565{ 1865{
2566 if(!blockname) 1866 char* stringTableName = NULL;
1867 if(NULL != blockname)
2567 { 1868 {
2568 return (mCurrentSendTotal > MTUBYTES); 1869 stringTableName = gMessageStringTable.getString(blockname);
2569 } 1870 }
2570 return isSendFullFast(gMessageStringTable.getString(blockname)); 1871 return isSendFullFast(stringTableName);
2571} 1872}
2572 1873
2573BOOL LLMessageSystem::isSendFullFast(const char* blockname) 1874BOOL LLMessageSystem::isSendFullFast(const char* blockname)
2574{ 1875{
2575 if(mCurrentSendTotal > MTUBYTES) 1876 return mMessageBuilder->isMessageFull(blockname);
2576 {
2577 return TRUE;
2578 }
2579 if(!blockname)
2580 {
2581 return FALSE;
2582 }
2583 char* bnamep = (char*)blockname;
2584 S32 max;
2585
2586 LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[bnamep];
2587
2588 switch(template_data->mType)
2589 {
2590 case MBT_SINGLE:
2591 max = 1;
2592 break;
2593 case MBT_MULTIPLE:
2594 max = template_data->mNumber;
2595 break;
2596 case MBT_VARIABLE:
2597 default:
2598 max = MAX_BLOCKS;
2599 break;
2600 }
2601 if(mCurrentSMessageData->mMemberBlocks[bnamep]->mBlockNumber >= max)
2602 {
2603 return TRUE;
2604 }
2605 return FALSE;
2606} 1877}
2607 1878
2608 1879
2609// blow away the last block of a message, return FALSE if that leaves no blocks or there wasn't a block to remove 1880// blow away the last block of a message, return FALSE if that leaves no blocks or there wasn't a block to remove
2610BOOL LLMessageSystem::removeLastBlock() 1881// TODO: Babbage: Remove this horror.
1882BOOL LLMessageSystem::removeLastBlock()
2611{ 1883{
2612 if (mCurrentSBlockName) 1884 return mMessageBuilder->removeLastBlock();
2613 {
2614 if ( (mCurrentSMessageData)
2615 &&(mCurrentSMessageTemplate))
2616 {
2617 if (mCurrentSMessageData->mMemberBlocks[mCurrentSBlockName]->mBlockNumber >= 1)
2618 {
2619 // At least one block for the current block name.
2620
2621 // Store the current block name for future reference.
2622 char *block_name = mCurrentSBlockName;
2623
2624 // Decrement the sent total by the size of the
2625 // data in the message block that we're currently building.
2626
2627 LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName];
2628
2629 for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin();
2630 iter != template_data->mMemberVariables.end(); iter++)
2631 {
2632 LLMessageVariable& ci = *(iter->second);
2633 mCurrentSendTotal -= ci.getSize();
2634 }
2635
2636
2637 // Now we want to find the block that we're blowing away.
2638
2639 // Get the number of blocks.
2640 LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[block_name];
2641 S32 num_blocks = block_data->mBlockNumber;
2642
2643 // Use the same (suspect?) algorithm that's used to generate
2644 // the names in the nextBlock method to find it.
2645 char *block_getting_whacked = block_name + num_blocks - 1;
2646 LLMsgBlkData* whacked_data = mCurrentSMessageData->mMemberBlocks[block_getting_whacked];
2647 delete whacked_data;
2648 mCurrentSMessageData->mMemberBlocks.erase(block_getting_whacked);
2649
2650 if (num_blocks <= 1)
2651 {
2652 // we just blew away the last one, so return FALSE
2653 return FALSE;
2654 }
2655 else
2656 {
2657 // Decrement the counter.
2658 block_data->mBlockNumber--;
2659 return TRUE;
2660 }
2661 }
2662 }
2663 }
2664 return FALSE;
2665}
2666
2667// make sure that all the desired data is in place and then copy the data into mSendBuffer
2668void LLMessageSystem::buildMessage()
2669{
2670 // basic algorithm is to loop through the various pieces, building
2671 // size and offset info if we encounter a -1 for mSize at any
2672 // point that variable wasn't given data
2673
2674 // do we have a current message?
2675 if (!mCurrentSMessageTemplate)
2676 {
2677 llerrs << "newMessage not called prior to buildMessage" << llendl;
2678 return;
2679 }
2680
2681 // zero out some useful values
2682
2683 // leave room for circuit counter
2684 mSendSize = LL_PACKET_ID_SIZE;
2685
2686 // encode message number and adjust total_offset
2687 if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH)
2688 {
2689// old, endian-dependant way
2690// memcpy(&mSendBuffer[mSendSize], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8));
2691
2692// new, independant way
2693 mSendBuffer[mSendSize] = (U8)mCurrentSMessageTemplate->mMessageNumber;
2694 mSendSize += sizeof(U8);
2695 }
2696 else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM)
2697 {
2698 U8 temp = 255;
2699 memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8)); /*Flawfinder: ignore*/
2700 mSendSize += sizeof(U8);
2701
2702 // mask off unsightly bits
2703 temp = mCurrentSMessageTemplate->mMessageNumber & 255;
2704 memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8)); /*Flawfinder: ignore*/
2705 mSendSize += sizeof(U8);
2706 }
2707 else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW)
2708 {
2709 U8 temp = 255;
2710 U16 message_num;
2711 memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8)); /*Flawfinder: ignore*/
2712 mSendSize += sizeof(U8);
2713 memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8)); /*Flawfinder: ignore*/
2714 mSendSize += sizeof(U8);
2715
2716 // mask off unsightly bits
2717 message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF;
2718
2719 // convert to network byte order
2720 message_num = htons(message_num);
2721 memcpy(&mSendBuffer[mSendSize], &message_num, sizeof(U16)); /*Flawfinder: ignore*/
2722 mSendSize += sizeof(U16);
2723 }
2724 else
2725 {
2726 llerrs << "unexpected message frequency in buildMessage" << llendl;
2727 return;
2728 }
2729
2730 // counting variables used to encode multiple block info
2731 S32 block_count = 0;
2732 U8 temp_block_number;
2733
2734 // loop through msg blocks to loop through variables, totalling up size data and copying into mSendBuffer
2735 for (LLMsgData::msg_blk_data_map_t::iterator
2736 iter = mCurrentSMessageData->mMemberBlocks.begin(),
2737 end = mCurrentSMessageData->mMemberBlocks.end();
2738 iter != end; iter++)
2739 {
2740 LLMsgBlkData* mbci = iter->second;
2741 // do we need to encode a block code?
2742 if (block_count == 0)
2743 {
2744 block_count = mbci->mBlockNumber;
2745
2746 LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mbci->mName];
2747
2748 // ok, if this is the first block of a repeating pack, set block_count and, if it's type MBT_VARIABLE encode a byte for how many there are
2749 if (template_data->mType == MBT_VARIABLE)
2750 {
2751 // remember that mBlockNumber is a S32
2752 temp_block_number = (U8)mbci->mBlockNumber;
2753 if ((S32)(mSendSize + sizeof(U8)) < MAX_BUFFER_SIZE)
2754 {
2755 memcpy(&mSendBuffer[mSendSize], &temp_block_number, sizeof(U8)); /* Flawfinder: ignore */
2756 mSendSize += sizeof(U8);
2757 }
2758 else
2759 {
2760 // Just reporting error is likely not enough. Need
2761 // to check how to abort or error out gracefully
2762 // from this function. XXXTBD
2763 llerrs << "buildMessage failed. Message excedding"
2764 " sendBuffersize." << llendl;
2765 }
2766 }
2767 else if (template_data->mType == MBT_MULTIPLE)
2768 {
2769 if (block_count != template_data->mNumber)
2770 {
2771 // nope! need to fill it in all the way!
2772 llerrs << "Block " << mbci->mName
2773 << " is type MBT_MULTIPLE but only has data for "
2774 << block_count << " out of its "
2775 << template_data->mNumber << " blocks" << llendl;
2776 }
2777 }
2778 }
2779
2780 // counting down multiple blocks
2781 block_count--;
2782
2783 // now loop through the variables
2784 for (LLMsgBlkData::msg_var_data_map_t::iterator iter = mbci->mMemberVarData.begin();
2785 iter != mbci->mMemberVarData.end(); iter++)
2786 {
2787 LLMsgVarData& mvci = *iter;
2788 if (mvci.getSize() == -1)
2789 {
2790 // oops, this variable wasn't ever set!
2791 llerrs << "The variable " << mvci.getName() << " in block "
2792 << mbci->mName << " of message "
2793 << mCurrentSMessageData->mName
2794 << " wasn't set prior to buildMessage call" << llendl;
2795 }
2796 else
2797 {
2798 S32 data_size = mvci.getDataSize();
2799 if(data_size > 0)
2800 {
2801 // The type is MVT_VARIABLE, which means that we
2802 // need to encode a size argument. Otherwise,
2803 // there is no need.
2804 S32 size = mvci.getSize();
2805 U8 sizeb;
2806 U16 sizeh;
2807 switch(data_size)
2808 {
2809 case 1:
2810 sizeb = size;
2811 htonmemcpy(&mSendBuffer[mSendSize], &sizeb, MVT_U8, 1);
2812 break;
2813 case 2:
2814 sizeh = size;
2815 htonmemcpy(&mSendBuffer[mSendSize], &sizeh, MVT_U16, 2);
2816 break;
2817 case 4:
2818 htonmemcpy(&mSendBuffer[mSendSize], &size, MVT_S32, 4);
2819 break;
2820 default:
2821 llerrs << "Attempting to build variable field with unknown size of " << size << llendl;
2822 break;
2823 }
2824 mSendSize += mvci.getDataSize();
2825 }
2826
2827 // if there is any data to pack, pack it
2828 if((mvci.getData() != NULL) && mvci.getSize())
2829 {
2830 if(mSendSize + mvci.getSize() < (S32)sizeof(mSendBuffer))
2831 {
2832 memcpy( /* Flawfinder: ignore */
2833 &mSendBuffer[mSendSize],
2834 mvci.getData(),
2835 mvci.getSize());
2836 mSendSize += mvci.getSize();
2837 }
2838 else
2839 {
2840 // Just reporting error is likely not
2841 // enough. Need to check how to abort or error
2842 // out gracefully from this function. XXXTBD
2843 llerrs << "LLMessageSystem::buildMessage failed. "
2844 << "Attempted to pack "
2845 << mSendSize + mvci.getSize()
2846 << " bytes into a buffer with size "
2847 << mSendBuffer << "." << llendl
2848 }
2849 }
2850 }
2851 }
2852 }
2853 mbSBuilt = TRUE;
2854} 1885}
2855 1886
2856S32 LLMessageSystem::sendReliable(const LLHost &host) 1887S32 LLMessageSystem::sendReliable(const LLHost &host)
@@ -2874,7 +1905,9 @@ S32 LLMessageSystem::sendSemiReliable(const LLHost &host, void (*callback)(void
2874 timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX; 1905 timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX;
2875 } 1906 }
2876 1907
2877 return sendReliable(host, 0, FALSE, timeout, callback, callback_data); 1908 const S32 retries = 0;
1909 const BOOL ping_based_timeout = FALSE;
1910 return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);
2878} 1911}
2879 1912
2880// send the message via a UDP packet 1913// send the message via a UDP packet
@@ -2900,7 +1933,8 @@ S32 LLMessageSystem::sendReliable( const LLHost &host,
2900 1933
2901 mSendReliable = TRUE; 1934 mSendReliable = TRUE;
2902 mReliablePacketParams.set(host, retries, ping_based_timeout, timeout, 1935 mReliablePacketParams.set(host, retries, ping_based_timeout, timeout,
2903 callback, callback_data, mCurrentSMessageName); 1936 callback, callback_data,
1937 const_cast<char*>(mMessageBuilder->getMessageName()));
2904 return sendMessage(host); 1938 return sendMessage(host);
2905} 1939}
2906 1940
@@ -2938,11 +1972,13 @@ S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void
2938 } 1972 }
2939 1973
2940 S32 send_bytes = 0; 1974 S32 send_bytes = 0;
2941 if (mCurrentSendTotal) 1975 if (mMessageBuilder->getMessageSize())
2942 { 1976 {
2943 mSendReliable = TRUE; 1977 mSendReliable = TRUE;
2944 // No need for ping-based retry as not going to retry 1978 // No need for ping-based retry as not going to retry
2945 mReliablePacketParams.set(host, 0, FALSE, timeout, callback, callback_data, mCurrentSMessageName); 1979 mReliablePacketParams.set(host, 0, FALSE, timeout, callback,
1980 callback_data,
1981 const_cast<char*>(mMessageBuilder->getMessageName()));
2946 send_bytes = sendMessage(host); 1982 send_bytes = sendMessage(host);
2947 clearMessage(); 1983 clearMessage();
2948 } 1984 }
@@ -2956,7 +1992,7 @@ S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void
2956S32 LLMessageSystem::flushReliable(const LLHost &host) 1992S32 LLMessageSystem::flushReliable(const LLHost &host)
2957{ 1993{
2958 S32 send_bytes = 0; 1994 S32 send_bytes = 0;
2959 if (mCurrentSendTotal) 1995 if (mMessageBuilder->getMessageSize())
2960 { 1996 {
2961 send_bytes = sendReliable(host); 1997 send_bytes = sendReliable(host);
2962 } 1998 }
@@ -2969,13 +2005,12 @@ S32 LLMessageSystem::flushReliable(const LLHost &host)
2969// so should should not use llinfos. 2005// so should should not use llinfos.
2970S32 LLMessageSystem::sendMessage(const LLHost &host) 2006S32 LLMessageSystem::sendMessage(const LLHost &host)
2971{ 2007{
2972 if (!mbSBuilt) 2008 if (! mMessageBuilder->isBuilt())
2973 { 2009 {
2974 buildMessage(); 2010 mSendSize = mMessageBuilder->buildMessage(mSendBuffer,
2011 MAX_BUFFER_SIZE);
2975 } 2012 }
2976 2013
2977 mCurrentSendTotal = 0;
2978
2979 if (!(host.isOk())) // if port and ip are zero, don't bother trying to send the message 2014 if (!(host.isOk())) // if port and ip are zero, don't bother trying to send the message
2980 { 2015 {
2981 return 0; 2016 return 0;
@@ -2992,10 +2027,10 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
2992 if(mVerboseLog) 2027 if(mVerboseLog)
2993 { 2028 {
2994 llinfos << "MSG: -> " << host << "\tUNKNOWN CIRCUIT:\t" 2029 llinfos << "MSG: -> " << host << "\tUNKNOWN CIRCUIT:\t"
2995 << mCurrentSMessageName << llendl; 2030 << mMessageBuilder->getMessageName() << llendl;
2996 } 2031 }
2997 llwarns << "sendMessage - Trying to send " 2032 llwarns << "sendMessage - Trying to send "
2998 << mCurrentSMessageName << " on unknown circuit " 2033 << mMessageBuilder->getMessageName() << " on unknown circuit "
2999 << host << llendl; 2034 << host << llendl;
3000 return 0; 2035 return 0;
3001 } 2036 }
@@ -3014,15 +2049,41 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
3014 if(mVerboseLog) 2049 if(mVerboseLog)
3015 { 2050 {
3016 llinfos << "MSG: -> " << host << "\tDEAD CIRCUIT\t\t" 2051 llinfos << "MSG: -> " << host << "\tDEAD CIRCUIT\t\t"
3017 << mCurrentSMessageName << llendl; 2052 << mMessageBuilder->getMessageName() << llendl;
3018 } 2053 }
3019 llwarns << "sendMessage - Trying to send message " 2054 llwarns << "sendMessage - Trying to send message "
3020 << mCurrentSMessageName << " to dead circuit " 2055 << mMessageBuilder->getMessageName() << " to dead circuit "
3021 << host << llendl; 2056 << host << llendl;
3022 return 0; 2057 return 0;
3023 } 2058 }
3024 } 2059 }
3025 2060
2061 // NOTE: babbage: LLSD message -> HTTP, template message -> UDP
2062 if(mMessageBuilder == mLLSDMessageBuilder)
2063 {
2064 LLSD message = mLLSDMessageBuilder->getMessage();
2065
2066 const LLHTTPSender& sender = LLHTTPSender::getSender(host);
2067 LLHTTPClient::ResponderPtr responder = NULL;
2068 if(mSendReliable)
2069 {
2070 responder =
2071 new LLFnPtrResponder(mReliablePacketParams.mCallback,
2072 mReliablePacketParams.mCallbackData);
2073 }
2074 else
2075 {
2076 llwarns << "LLMessageSystem::sendMessage: Sending unreliable " << mMessageBuilder->getMessageName() << " message via HTTP" << llendl;
2077 responder = new LLFnPtrResponder(NULL, NULL);
2078 }
2079 sender.send(host, mLLSDMessageBuilder->getMessageName(),
2080 message, responder);
2081
2082 mSendReliable = FALSE;
2083 mReliablePacketParams.clear();
2084 return 1;
2085 }
2086
3026 memset(mSendBuffer,0,LL_PACKET_ID_SIZE); // zero out the packet ID field 2087 memset(mSendBuffer,0,LL_PACKET_ID_SIZE); // zero out the packet ID field
3027 2088
3028 // add the send id to the front of the message 2089 // add the send id to the front of the message
@@ -3033,20 +2094,17 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
3033 2094
3034 // Compress the message, which will usually reduce its size. 2095 // Compress the message, which will usually reduce its size.
3035 U8 * buf_ptr = (U8 *)mSendBuffer; 2096 U8 * buf_ptr = (U8 *)mSendBuffer;
3036 S32 buffer_length = mSendSize; 2097 U32 buffer_length = mSendSize;
3037 if(ME_ZEROCODED == mCurrentSMessageTemplate->getEncoding()) 2098 mMessageBuilder->compressMessage(buf_ptr, buffer_length);
3038 {
3039 zeroCode(&buf_ptr, &buffer_length);
3040 }
3041 2099
3042 if (buffer_length > 1500) 2100 if (buffer_length > 1500)
3043 { 2101 {
3044 if((mCurrentSMessageName != _PREHASH_ChildAgentUpdate) 2102 if((mMessageBuilder->getMessageName() != _PREHASH_ChildAgentUpdate)
3045 && (mCurrentSMessageName != _PREHASH_SendXferPacket)) 2103 && (mMessageBuilder->getMessageName() != _PREHASH_SendXferPacket))
3046 { 2104 {
3047 llwarns << "sendMessage - Trying to send " 2105 llwarns << "sendMessage - Trying to send "
3048 << ((buffer_length > 4000) ? "EXTRA " : "") 2106 << ((buffer_length > 4000) ? "EXTRA " : "")
3049 << "BIG message " << mCurrentSMessageName << " - " 2107 << "BIG message " << mMessageBuilder->getMessageName() << " - "
3050 << buffer_length << llendl; 2108 << buffer_length << llendl;
3051 } 2109 }
3052 } 2110 }
@@ -3071,7 +2129,7 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
3071 BOOL is_ack_appended = FALSE; 2129 BOOL is_ack_appended = FALSE;
3072 std::vector<TPACKETID> acks; 2130 std::vector<TPACKETID> acks;
3073 if((space_left > 0) && (ack_count > 0) && 2131 if((space_left > 0) && (ack_count > 0) &&
3074 (mCurrentSMessageName != _PREHASH_PacketAck)) 2132 (mMessageBuilder->getMessageName() != _PREHASH_PacketAck))
3075 { 2133 {
3076 buf_ptr[0] |= LL_ACK_FLAG; 2134 buf_ptr[0] |= LL_ACK_FLAG;
3077 S32 append_ack_count = llmin(space_left, ack_count); 2135 S32 append_ack_count = llmin(space_left, ack_count);
@@ -3142,7 +2200,7 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
3142 char buffer[MAX_STRING]; /* Flawfinder: ignore */ 2200 char buffer[MAX_STRING]; /* Flawfinder: ignore */
3143 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID()); /* Flawfinder: ignore */ 2201 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID()); /* Flawfinder: ignore */
3144 str << buffer 2202 str << buffer
3145 << mCurrentSMessageTemplate->mName 2203 << mMessageBuilder->getMessageName()
3146 << (mSendReliable ? " reliable " : ""); 2204 << (mSendReliable ? " reliable " : "");
3147 if(is_ack_appended) 2205 if(is_ack_appended)
3148 { 2206 {
@@ -3153,89 +2211,19 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
3153 llinfos << str.str() << llendl; 2211 llinfos << str.str() << llendl;
3154 } 2212 }
3155 2213
3156 lldebugst(LLERR_MESSAGE) << "MessageSent at: " << (S32)totalTime() 2214 /*lldebugst(LLERR_MESSAGE) << "MessageSent at: " << (S32)totalTime()
3157 << ", " << mCurrentSMessageTemplate->mName 2215 << "," << mMessageBuilder->getMessageName()
3158 << " to " << host 2216 << " to " << host
3159 << llendl; 2217 << llendl;*/
3160
3161 // ok, clean up temp data
3162 delete mCurrentSMessageData;
3163 mCurrentSMessageData = NULL;
3164 2218
3165 mPacketsOut++; 2219 mPacketsOut++;
3166 mBytesOut += buffer_length; 2220 mBytesOut += buffer_length;
3167 2221
2222 mSendReliable = FALSE;
2223 mReliablePacketParams.clear();
3168 return buffer_length; 2224 return buffer_length;
3169} 2225}
3170 2226
3171
3172// Returns template for the message contained in buffer
3173BOOL LLMessageSystem::decodeTemplate(
3174 const U8* buffer, S32 buffer_size, // inputs
3175 LLMessageTemplate** msg_template ) // outputs
3176{
3177 const U8* header = buffer + LL_PACKET_ID_SIZE;
3178
3179 // is there a message ready to go?
3180 if (buffer_size <= 0)
3181 {
3182 llwarns << "No message waiting for decode!" << llendl;
3183 return(FALSE);
3184 }
3185
3186 U32 num = 0;
3187
3188 if (header[0] != 255)
3189 {
3190 // high frequency message
3191 num = header[0];
3192 }
3193 else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255))
3194 {
3195 // medium frequency message
3196 num = (255 << 8) | header[1];
3197 }
3198 else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255))
3199 {
3200 // low frequency message
3201 U16 message_id_U16 = 0;
3202 // I think this check busts the message system.
3203 // it appears that if there is a NULL in the message #, it won't copy it....
3204 // what was the goal?
3205 //if(header[2])
3206 memcpy(&message_id_U16, &header[2], 2); /* Flawfinder: ignore */
3207
3208 // dependant on endian-ness:
3209 // U32 temp = (255 << 24) | (255 << 16) | header[2];
3210
3211 // independant of endian-ness:
3212 message_id_U16 = ntohs(message_id_U16);
3213 num = 0xFFFF0000 | message_id_U16;
3214 }
3215 else // bogus packet received (too short)
3216 {
3217 llwarns << "Packet with unusable length received (too short): "
3218 << buffer_size << llendl;
3219 return(FALSE);
3220 }
3221
3222 LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num);
3223 if (temp)
3224 {
3225 *msg_template = temp;
3226 }
3227 else
3228 {
3229 llwarns << "Message #" << std::hex << num << std::dec
3230 << " received but not registered!" << llendl;
3231 callExceptionFunc(MX_UNREGISTERED_MESSAGE);
3232 return(FALSE);
3233 }
3234
3235 return(TRUE);
3236}
3237
3238
3239void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_reliable ) 2227void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_reliable )
3240{ 2228{
3241 if(mVerboseLog) 2229 if(mVerboseLog)
@@ -3243,9 +2231,9 @@ void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_re
3243 std::ostringstream str; 2231 std::ostringstream str;
3244 str << "MSG: <- " << host; 2232 str << "MSG: <- " << host;
3245 char buffer[MAX_STRING]; /* Flawfinder: ignore */ 2233 char buffer[MAX_STRING]; /* Flawfinder: ignore */
3246 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize: mReceiveSize), mCurrentRecvPacketID); /* Flawfinder: ignore */ 2234 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID); /* Flawfinder: ignore */
3247 str << buffer 2235 str << buffer
3248 << mCurrentRMessageTemplate->mName 2236 << mMessageReader->getMessageName()
3249 << (recv_reliable ? " reliable" : "") 2237 << (recv_reliable ? " reliable" : "")
3250 << " REJECTED"; 2238 << " REJECTED";
3251 llinfos << str.str() << llendl; 2239 llinfos << str.str() << llendl;
@@ -3260,8 +2248,9 @@ void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_re
3260 } 2248 }
3261 else 2249 else
3262 { 2250 {
3263 mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; 2251 // TODO: babbage: work out if we need these
3264 mMessageCountList[mNumMessageCounts].mMessageBytes = mReceiveSize; 2252 // mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
2253 mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
3265 mMessageCountList[mNumMessageCounts].mInvalid = TRUE; 2254 mMessageCountList[mNumMessageCounts].mInvalid = TRUE;
3266 mNumMessageCounts++; 2255 mNumMessageCounts++;
3267 } 2256 }
@@ -3271,11 +2260,11 @@ void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )
3271{ 2260{
3272 // RequestTrustedCircuit is how we establish trust, so don't spam 2261 // RequestTrustedCircuit is how we establish trust, so don't spam
3273 // if it's received on a trusted circuit. JC 2262 // if it's received on a trusted circuit. JC
3274 if (strcmp(mCurrentRMessageTemplate->mName, "RequestTrustedCircuit")) 2263 if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit"))
3275 { 2264 {
3276 llwarns << "Received trusted message on untrusted circuit. " 2265 llwarns << "Received trusted message on untrusted circuit. "
3277 << "Will reply with deny. " 2266 << "Will reply with deny. "
3278 << "Message: " << mCurrentRMessageTemplate->mName 2267 << "Message: " << mMessageReader->getMessageName()
3279 << " Host: " << host << llendl; 2268 << " Host: " << host << llendl;
3280 } 2269 }
3281 2270
@@ -3287,10 +2276,11 @@ void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )
3287 } 2276 }
3288 else 2277 else
3289 { 2278 {
3290 mMessageCountList[mNumMessageCounts].mMessageNum 2279 // TODO: babbage: work out if we need these
3291 = mCurrentRMessageTemplate->mMessageNumber; 2280 //mMessageCountList[mNumMessageCounts].mMessageNum
2281 // = mCurrentRMessageTemplate->mMessageNumber;
3292 mMessageCountList[mNumMessageCounts].mMessageBytes 2282 mMessageCountList[mNumMessageCounts].mMessageBytes
3293 = mReceiveSize; 2283 = mMessageReader->getMessageSize();
3294 mMessageCountList[mNumMessageCounts].mInvalid = TRUE; 2284 mMessageCountList[mNumMessageCounts].mInvalid = TRUE;
3295 mNumMessageCounts++; 2285 mNumMessageCounts++;
3296 } 2286 }
@@ -3304,8 +2294,9 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r
3304 } 2294 }
3305 else 2295 else
3306 { 2296 {
3307 mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; 2297 // TODO: babbage: work out if we need these
3308 mMessageCountList[mNumMessageCounts].mMessageBytes = mReceiveSize; 2298 //mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
2299 mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
3309 mMessageCountList[mNumMessageCounts].mInvalid = FALSE; 2300 mMessageCountList[mNumMessageCounts].mInvalid = FALSE;
3310 mNumMessageCounts++; 2301 mNumMessageCounts++;
3311 } 2302 }
@@ -3322,9 +2313,9 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r
3322 std::ostringstream str; 2313 std::ostringstream str;
3323 str << "MSG: <- " << host; 2314 str << "MSG: <- " << host;
3324 char buffer[MAX_STRING]; /* Flawfinder: ignore */ 2315 char buffer[MAX_STRING]; /* Flawfinder: ignore */
3325 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize : mReceiveSize), mCurrentRecvPacketID); /* Flawfinder: ignore */ 2316 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID); /* Flawfinder: ignore */
3326 str << buffer 2317 str << buffer
3327 << mCurrentRMessageTemplate->mName 2318 << mMessageReader->getMessageName()
3328 << (recv_reliable ? " reliable" : "") 2319 << (recv_reliable ? " reliable" : "")
3329 << (recv_resent ? " resent" : "") 2320 << (recv_resent ? " resent" : "")
3330 << (recv_acks ? " acks" : ""); 2321 << (recv_acks ? " acks" : "");
@@ -3332,435 +2323,19 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r
3332 } 2323 }
3333} 2324}
3334 2325
3335
3336void LLMessageSystem::logRanOffEndOfPacket( const LLHost& host )
3337{
3338 // we've run off the end of the packet!
3339 llwarns << "Ran off end of packet " << mCurrentRMessageTemplate->mName
3340 << " with id " << mCurrentRecvPacketID << " from " << host
3341 << llendl;
3342 if(mVerboseLog)
3343 {
3344 llinfos << "MSG: -> " << host << "\tREAD PAST END:\t"
3345 << mCurrentRecvPacketID << " "
3346 << mCurrentSMessageTemplate->mName << llendl;
3347 }
3348 callExceptionFunc(MX_RAN_OFF_END_OF_PACKET);
3349}
3350
3351
3352// decode a given message
3353BOOL LLMessageSystem::decodeData(const U8* buffer, const LLHost& sender )
3354{
3355 llassert( mReceiveSize >= 0 );
3356 llassert( mCurrentRMessageTemplate);
3357 llassert( !mCurrentRMessageData );
3358 delete mCurrentRMessageData; // just to make sure
3359
3360 S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency);
3361
3362 // create base working data set
3363 mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName);
3364
3365 // loop through the template building the data structure as we go
3366 for (LLMessageTemplate::message_block_map_t::iterator iter = mCurrentRMessageTemplate->mMemberBlocks.begin();
3367 iter != mCurrentRMessageTemplate->mMemberBlocks.end(); iter++)
3368 {
3369 LLMessageBlock* mbci = iter->second;
3370 U8 repeat_number;
3371 S32 i;
3372
3373 // how many of this block?
3374
3375 if (mbci->mType == MBT_SINGLE)
3376 {
3377 // just one
3378 repeat_number = 1;
3379 }
3380 else if (mbci->mType == MBT_MULTIPLE)
3381 {
3382 // a known number
3383 repeat_number = mbci->mNumber;
3384 }
3385 else if (mbci->mType == MBT_VARIABLE)
3386 {
3387 // need to read the number from the message
3388 // repeat number is a single byte
3389 if (decode_pos >= mReceiveSize)
3390 {
3391 logRanOffEndOfPacket( sender );
3392 return FALSE;
3393 }
3394 repeat_number = buffer[decode_pos];
3395 decode_pos++;
3396 }
3397 else
3398 {
3399 llerrs << "Unknown block type" << llendl;
3400 return FALSE;
3401 }
3402
3403 LLMsgBlkData* cur_data_block = NULL;
3404
3405 // now loop through the block
3406 for (i = 0; i < repeat_number; i++)
3407 {
3408 if (i)
3409 {
3410 // build new name to prevent collisions
3411 // TODO: This should really change to a vector
3412 cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
3413 cur_data_block->mName = mbci->mName + i;
3414 }
3415 else
3416 {
3417 cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number);
3418 }
3419
3420 // add the block to the message
3421 mCurrentRMessageData->addBlock(cur_data_block);
3422
3423 // now read the variables
3424 for (LLMessageBlock::message_variable_map_t::iterator iter = mbci->mMemberVariables.begin();
3425 iter != mbci->mMemberVariables.end(); iter++)
3426 {
3427 LLMessageVariable& mvci = *(iter->second);
3428 // ok, build out the variables
3429 // add variable block
3430 cur_data_block->addVariable(mvci.getName(), mvci.getType());
3431
3432 // what type of variable?
3433 if (mvci.getType() == MVT_VARIABLE)
3434 {
3435 // variable, get the number of bytes to read from the template
3436 S32 data_size = mvci.getSize();
3437 U8 tsizeb = 0;
3438 U16 tsizeh = 0;
3439 U32 tsize = 0;
3440
3441 if ((decode_pos + data_size) > mReceiveSize)
3442 {
3443 logRanOffEndOfPacket( sender );
3444 return FALSE;
3445 }
3446 switch(data_size)
3447 {
3448 case 1:
3449 htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1);
3450 tsize = tsizeb;
3451 break;
3452 case 2:
3453 htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2);
3454 tsize = tsizeh;
3455 break;
3456 case 4:
3457 htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U32, 4);
3458 break;
3459 default:
3460 llerrs << "Attempting to read variable field with unknown size of " << data_size << llendl;
3461 break;
3462
3463 }
3464 decode_pos += data_size;
3465
3466 if ((decode_pos + (S32)tsize) > mReceiveSize)
3467 {
3468 logRanOffEndOfPacket( sender );
3469 return FALSE;
3470 }
3471 cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType());
3472 decode_pos += tsize;
3473 }
3474 else
3475 {
3476 // fixed!
3477 // so, copy data pointer and set data size to fixed size
3478
3479 if ((decode_pos + mvci.getSize()) > mReceiveSize)
3480 {
3481 logRanOffEndOfPacket( sender );
3482 return FALSE;
3483 }
3484
3485 cur_data_block->addData(mvci.getName(), &buffer[decode_pos], mvci.getSize(), mvci.getType());
3486 decode_pos += mvci.getSize();
3487 }
3488 }
3489 }
3490 }
3491
3492 if (mCurrentRMessageData->mMemberBlocks.empty()
3493 && !mCurrentRMessageTemplate->mMemberBlocks.empty())
3494 {
3495 lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl;
3496 return FALSE;
3497 }
3498
3499 {
3500 static LLTimer decode_timer;
3501
3502 if( mTimeDecodes )
3503 {
3504 decode_timer.reset();
3505 }
3506
3507 // if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion )
3508 // {
3509 // VTResume(); // VTune
3510 // }
3511
3512 {
3513 LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES);
3514 if( !mCurrentRMessageTemplate->callHandlerFunc(this) )
3515 {
3516 llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl;
3517 }
3518 }
3519
3520 // if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion )
3521 // {
3522 // VTPause(); // VTune
3523 // }
3524
3525 if( mTimeDecodes )
3526 {
3527 F32 decode_time = decode_timer.getElapsedTimeF32();
3528 mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time;
3529
3530 mCurrentRMessageTemplate->mTotalDecoded++;
3531 mCurrentRMessageTemplate->mTotalDecodeTime += decode_time;
3532
3533 if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time )
3534 {
3535 mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time;
3536 }
3537
3538
3539 if( decode_time > mTimeDecodesSpamThreshold )
3540 {
3541 lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" <<
3542 mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " <<
3543 (mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << llendl;
3544 }
3545 }
3546 }
3547 return TRUE;
3548}
3549
3550void LLMessageSystem::getDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum, S32 max_size)
3551{
3552 // is there a message ready to go?
3553 if (mReceiveSize == -1)
3554 {
3555 llerrs << "No message waiting for decode 2!" << llendl;
3556 return;
3557 }
3558
3559 if (!mCurrentRMessageData)
3560 {
3561 llerrs << "Invalid mCurrentMessageData in getData!" << llendl;
3562 return;
3563 }
3564
3565 char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash. The bnamep is never derefference
3566 char *vnamep = (char *)varname;
3567
3568 LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
3569
3570 if (iter == mCurrentRMessageData->mMemberBlocks.end())
3571 {
3572 llerrs << "Block " << blockname << " #" << blocknum
3573 << " not in message " << mCurrentRMessageData->mName << llendl;
3574 return;
3575 }
3576
3577 LLMsgBlkData *msg_block_data = iter->second;
3578 LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep];
3579
3580 if (!vardata.getName())
3581 {
3582 llerrs << "Variable "<< vnamep << " not in message "
3583 << mCurrentRMessageData->mName<< " block " << bnamep << llendl;
3584 return;
3585 }
3586
3587 if (size && size != vardata.getSize())
3588 {
3589 llerrs << "Msg " << mCurrentRMessageData->mName
3590 << " variable " << vnamep
3591 << " is size " << vardata.getSize()
3592 << " but copying into buffer of size " << size
3593 << llendl;
3594 return;
3595 }
3596
3597
3598 const S32 vardata_size = vardata.getSize();
3599 if( max_size >= vardata_size )
3600 {
3601 switch( vardata_size )
3602 {
3603 case 1:
3604 *((U8*)datap) = *((U8*)vardata.getData());
3605 break;
3606 case 2:
3607 *((U16*)datap) = *((U16*)vardata.getData());
3608 break;
3609 case 4:
3610 *((U32*)datap) = *((U32*)vardata.getData());
3611 break;
3612 case 8:
3613 ((U32*)datap)[0] = ((U32*)vardata.getData())[0];
3614 ((U32*)datap)[1] = ((U32*)vardata.getData())[1];
3615 break;
3616 default:
3617 memcpy(datap, vardata.getData(), vardata_size); /* Flawfinder: ignore */
3618 break;
3619 }
3620 }
3621 else
3622 {
3623 llwarns << "Msg " << mCurrentRMessageData->mName
3624 << " variable " << vnamep
3625 << " is size " << vardata.getSize()
3626 << " but truncated to max size of " << max_size
3627 << llendl;
3628
3629 memcpy(datap, vardata.getData(), max_size); /* Flawfinder: ignore */
3630 }
3631}
3632
3633S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname)
3634{
3635 // is there a message ready to go?
3636 if (mReceiveSize == -1)
3637 {
3638 llerrs << "No message waiting for decode 3!" << llendl;
3639 return -1;
3640 }
3641
3642 if (!mCurrentRMessageData)
3643 {
3644 llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
3645 return -1;
3646 }
3647
3648 char *bnamep = (char *)blockname;
3649
3650 LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
3651
3652 if (iter == mCurrentRMessageData->mMemberBlocks.end())
3653 {
3654// sprintf(errmsg, "Block %s not in message %s", bnamep, mCurrentRMessageData->mName);
3655// llerrs << errmsg << llendl;
3656// return -1;
3657 return 0;
3658 }
3659
3660 return (iter->second)->mBlockNumber;
3661}
3662
3663S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname)
3664{
3665 // is there a message ready to go?
3666 if (mReceiveSize == -1)
3667 {
3668 llerrs << "No message waiting for decode 4!" << llendl;
3669 return -1;
3670 }
3671
3672 if (!mCurrentRMessageData)
3673 {
3674 llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
3675 return -1;
3676 }
3677
3678 char *bnamep = (char *)blockname;
3679
3680 LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
3681
3682 if (iter == mCurrentRMessageData->mMemberBlocks.end())
3683 {
3684 llerrs << "Block " << bnamep << " not in message "
3685 << mCurrentRMessageData->mName << llendl;
3686 return -1;
3687 }
3688
3689 char *vnamep = (char *)varname;
3690
3691 LLMsgBlkData* msg_data = iter->second;
3692 LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
3693
3694 if (!vardata.getName())
3695 {
3696 llerrs << "Variable " << varname << " not in message "
3697 << mCurrentRMessageData->mName << " block " << bnamep << llendl;
3698 return -1;
3699 }
3700
3701 if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE)
3702 {
3703 llerrs << "Block " << bnamep << " isn't type MBT_SINGLE,"
3704 " use getSize with blocknum argument!" << llendl;
3705 return -1;
3706 }
3707
3708 return vardata.getSize();
3709}
3710
3711
3712S32 LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum, const char *varname)
3713{
3714 // is there a message ready to go?
3715 if (mReceiveSize == -1)
3716 {
3717 llerrs << "No message waiting for decode 5!" << llendl;
3718 return -1;
3719 }
3720
3721 if (!mCurrentRMessageData)
3722 {
3723 llerrs << "Invalid mCurrentRMessageData in getData!" << llendl;
3724 return -1;
3725 }
3726
3727 char *bnamep = (char *)blockname + blocknum;
3728 char *vnamep = (char *)varname;
3729
3730 LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep);
3731
3732 if (iter == mCurrentRMessageData->mMemberBlocks.end())
3733 {
3734 llerrs << "Block " << bnamep << " not in message "
3735 << mCurrentRMessageData->mName << llendl;
3736 return -1;
3737 }
3738
3739 LLMsgBlkData* msg_data = iter->second;
3740 LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep];
3741
3742 if (!vardata.getName())
3743 {
3744 llerrs << "Variable " << vnamep << " not in message "
3745 << mCurrentRMessageData->mName << " block " << bnamep << llendl;
3746 return -1;
3747 }
3748
3749 return vardata.getSize();
3750}
3751
3752
3753void LLMessageSystem::sanityCheck() 2326void LLMessageSystem::sanityCheck()
3754{ 2327{
3755 if (!mCurrentRMessageData) 2328// TODO: babbage: reinstate
3756 {
3757 llerrs << "mCurrentRMessageData is NULL" << llendl;
3758 }
3759 2329
3760 if (!mCurrentRMessageTemplate) 2330// if (!mCurrentRMessageData)
3761 { 2331// {
3762 llerrs << "mCurrentRMessageTemplate is NULL" << llendl; 2332// llerrs << "mCurrentRMessageData is NULL" << llendl;
3763 } 2333// }
2334
2335// if (!mCurrentRMessageTemplate)
2336// {
2337// llerrs << "mCurrentRMessageTemplate is NULL" << llendl;
2338// }
3764 2339
3765// if (!mCurrentRTemplateBlock) 2340// if (!mCurrentRTemplateBlock)
3766// { 2341// {
@@ -3772,25 +2347,25 @@ void LLMessageSystem::sanityCheck()
3772// llerrs << "mCurrentRDataBlock is NULL" << llendl; 2347// llerrs << "mCurrentRDataBlock is NULL" << llendl;
3773// } 2348// }
3774 2349
3775 if (!mCurrentSMessageData) 2350// if (!mCurrentSMessageData)
3776 { 2351// {
3777 llerrs << "mCurrentSMessageData is NULL" << llendl; 2352// llerrs << "mCurrentSMessageData is NULL" << llendl;
3778 } 2353// }
3779 2354
3780 if (!mCurrentSMessageTemplate) 2355// if (!mCurrentSMessageTemplate)
3781 { 2356// {
3782 llerrs << "mCurrentSMessageTemplate is NULL" << llendl; 2357// llerrs << "mCurrentSMessageTemplate is NULL" << llendl;
3783 } 2358// }
3784 2359
3785// if (!mCurrentSTemplateBlock) 2360// if (!mCurrentSTemplateBlock)
3786// { 2361// {
3787// llerrs << "mCurrentSTemplateBlock is NULL" << llendl; 2362// llerrs << "mCurrentSTemplateBlock is NULL" << llendl;
3788// } 2363// }
3789 2364
3790 if (!mCurrentSDataBlock) 2365// if (!mCurrentSDataBlock)
3791 { 2366// {
3792 llerrs << "mCurrentSDataBlock is NULL" << llendl; 2367// llerrs << "mCurrentSDataBlock is NULL" << llendl;
3793 } 2368// }
3794} 2369}
3795 2370
3796void LLMessageSystem::showCircuitInfo() 2371void LLMessageSystem::showCircuitInfo()
@@ -4176,7 +2751,8 @@ bool LLMessageSystem::addCircuitCode(U32 code, const LLUUID& session_id)
4176//} 2751//}
4177 2752
4178// static 2753// static
4179void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**) 2754void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg,
2755 void** user)
4180{ 2756{
4181 U32 circuit_code_in; 2757 U32 circuit_code_in;
4182 msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, circuit_code_in); 2758 msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, circuit_code_in);
@@ -4296,6 +2872,13 @@ void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**)
4296 llinfos << "Circuit code " << circuit_code_in << " from " 2872 llinfos << "Circuit code " << circuit_code_in << " from "
4297 << msg->getSender() << " for agent " << id << " in session " 2873 << msg->getSender() << " for agent " << id << " in session "
4298 << session_id << llendl; 2874 << session_id << llendl;
2875
2876 const LLUseCircuitCodeResponder* responder =
2877 (const LLUseCircuitCodeResponder*) user;
2878 if(responder)
2879 {
2880 responder->complete(msg->getSender(), id);
2881 }
4299 } 2882 }
4300 else 2883 else
4301 { 2884 {
@@ -4303,7 +2886,50 @@ void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**)
4303 } 2886 }
4304} 2887}
4305 2888
2889static LLHTTPNode& messageRootNode()
2890{
2891 static LLHTTPNode root_node;
2892 static bool initialized = false;
2893 if (!initialized) {
2894 initialized = true;
2895 LLHTTPRegistrar::buildAllServices(root_node);
2896 }
2897
2898 return root_node;
2899}
4306 2900
2901//static
2902void LLMessageSystem::dispatch(const std::string& msg_name,
2903 const LLSD& message)
2904{
2905 LLPointer<LLSimpleResponse> responsep = LLSimpleResponse::create();
2906 dispatch(msg_name, message, responsep);
2907}
2908
2909//static
2910void LLMessageSystem::dispatch(const std::string& msg_name,
2911 const LLSD& message,
2912 LLHTTPNode::ResponsePtr responsep)
2913{
2914 if (msg_name.empty())
2915 {
2916 llwarns << "LLMessageService::dispatch called with no message name"
2917 << llendl;
2918 return;
2919 }
2920
2921 std::string path = "/message/" + msg_name;
2922 LLSD context;
2923 const LLHTTPNode* handler = messageRootNode().traverse(path, context);
2924 if (!handler)
2925 {
2926 llwarns << "LLMessageService::dispatch > no handler for "
2927 << path << llendl;
2928 return;
2929 }
2930
2931 handler->post(responsep, context, message);
2932}
4307 2933
4308static void check_for_unrecognized_messages( 2934static void check_for_unrecognized_messages(
4309 const char* type, 2935 const char* type,
@@ -4535,76 +3161,6 @@ void process_deny_trusted_circuit(LLMessageSystem *msg, void **)
4535 msg->sendCreateTrustedCircuit(msg->getSender(), local_id, remote_id); 3161 msg->sendCreateTrustedCircuit(msg->getSender(), local_id, remote_id);
4536} 3162}
4537 3163
4538#define LL_ENCRYPT_BUF_LENGTH 16384
4539
4540void encrypt_template(const char *src_name, const char *dest_name)
4541{
4542 // encrypt and decrypt are symmetric
4543 decrypt_template(src_name, dest_name);
4544}
4545
4546BOOL decrypt_template(const char *src_name, const char *dest_name)
4547{
4548 S32 buf_length = LL_ENCRYPT_BUF_LENGTH;
4549 char buf[LL_ENCRYPT_BUF_LENGTH]; /* Flawfinder: ignore */
4550
4551 FILE* infp = NULL;
4552 FILE* outfp = NULL;
4553 BOOL success = FALSE;
4554 char* bufp = NULL;
4555 U32 key = 0;
4556 S32 more_data = 0;
4557
4558 if(src_name==NULL)
4559 {
4560 llwarns << "Input src_name is NULL!!" << llendl;
4561 goto exit;
4562 }
4563
4564 infp = LLFile::fopen(src_name,"rb"); /* Flawfinder: ignore */
4565 if (!infp)
4566 {
4567 llwarns << "could not open " << src_name << " for reading" << llendl;
4568 goto exit;
4569 }
4570
4571 if(dest_name==NULL)
4572 {
4573 llwarns << "Output dest_name is NULL!!" << llendl;
4574 goto exit;
4575 }
4576
4577 outfp = LLFile::fopen(dest_name,"w+b"); /* Flawfinder: ignore */
4578 if (!outfp)
4579 {
4580 llwarns << "could not open " << src_name << " for writing" << llendl;
4581 goto exit;
4582 }
4583
4584 while ((buf_length = (S32)fread(buf,1,LL_ENCRYPT_BUF_LENGTH,infp)))
4585 {
4586 // unscrozzle bits here
4587 bufp = buf;
4588 more_data = buf_length;
4589 while (more_data--)
4590 {
4591 *bufp = *bufp ^ ((key * 43) % 256);
4592 key++;
4593 bufp++;
4594 }
4595
4596 if(buf_length != (S32)fwrite(buf,1,buf_length,outfp))
4597 {
4598 goto exit;
4599 }
4600 }
4601 success = TRUE;
4602
4603 exit:
4604 if(infp) fclose(infp);
4605 if(outfp) fclose(outfp);
4606 return success;
4607}
4608 3164
4609void dump_prehash_files() 3165void dump_prehash_files()
4610{ 3166{
@@ -4688,7 +3244,8 @@ BOOL start_messaging_system(
4688 S32 version_minor, 3244 S32 version_minor,
4689 S32 version_patch, 3245 S32 version_patch,
4690 BOOL b_dump_prehash_file, 3246 BOOL b_dump_prehash_file,
4691 const std::string& secret) 3247 const std::string& secret,
3248 const LLUseCircuitCodeResponder* responder)
4692{ 3249{
4693 gMessageSystem = new LLMessageSystem( 3250 gMessageSystem = new LLMessageSystem(
4694 template_name.c_str(), 3251 template_name.c_str(),
@@ -4737,7 +3294,7 @@ BOOL start_messaging_system(
4737 //gMessageSystem->setHandlerFuncFast(_PREHASH_AssignCircuitCode, LLMessageSystem::processAssignCircuitCode); 3294 //gMessageSystem->setHandlerFuncFast(_PREHASH_AssignCircuitCode, LLMessageSystem::processAssignCircuitCode);
4738 gMessageSystem->setHandlerFuncFast(_PREHASH_AddCircuitCode, LLMessageSystem::processAddCircuitCode); 3295 gMessageSystem->setHandlerFuncFast(_PREHASH_AddCircuitCode, LLMessageSystem::processAddCircuitCode);
4739 //gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode, ack_add_circuit_code, NULL); 3296 //gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode, ack_add_circuit_code, NULL);
4740 gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode); 3297 gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder);
4741 gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck, process_packet_ack, NULL); 3298 gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck, process_packet_ack, NULL);
4742 gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumRequest, process_template_checksum_request, NULL); 3299 gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumRequest, process_template_checksum_request, NULL);
4743 gMessageSystem->setHandlerFuncFast(_PREHASH_SecuredTemplateChecksumRequest, process_secured_template_checksum_request, NULL); 3300 gMessageSystem->setHandlerFuncFast(_PREHASH_SecuredTemplateChecksumRequest, process_secured_template_checksum_request, NULL);
@@ -4790,75 +3347,75 @@ void LLMessageSystem::summarizeLogs(std::ostream& str)
4790 char tmp_str[MAX_STRING]; /* Flawfinder: ignore */ 3347 char tmp_str[MAX_STRING]; /* Flawfinder: ignore */
4791 F32 run_time = mMessageSystemTimer.getElapsedTimeF32(); 3348 F32 run_time = mMessageSystemTimer.getElapsedTimeF32();
4792 str << "START MESSAGE LOG SUMMARY" << std::endl; 3349 str << "START MESSAGE LOG SUMMARY" << std::endl;
4793 snprintf(buffer, MAX_STRING, "Run time: %12.3f seconds", run_time); /* Flawfinder: ignore */ 3350 snprintf(buffer, MAX_STRING, "Run time: %12.3f seconds", run_time); /* Flawfinder: ignore */
4794 3351
4795 // Incoming 3352 // Incoming
4796 str << buffer << std::endl << "Incoming:" << std::endl; 3353 str << buffer << std::endl << "Incoming:" << std::endl;
4797 U64_to_str(mTotalBytesIn, tmp_str, sizeof(tmp_str)); 3354 U64_to_str(mTotalBytesIn, tmp_str, sizeof(tmp_str));
4798 snprintf(buffer, MAX_STRING, "Total bytes received: %20s (%5.2f kbits per second)", tmp_str, ((F32)mTotalBytesIn * 0.008f) / run_time); /* Flawfinder: ignore */ 3355 snprintf(buffer, MAX_STRING, "Total bytes received: %20s (%5.2f kbits per second)", tmp_str, ((F32)mTotalBytesIn * 0.008f) / run_time); /* Flawfinder: ignore */
4799 str << buffer << std::endl; 3356 str << buffer << std::endl;
4800 U64_to_str(mPacketsIn, tmp_str, sizeof(tmp_str)); 3357 U64_to_str(mPacketsIn, tmp_str, sizeof(tmp_str));
4801 snprintf(buffer, MAX_STRING, "Total packets received: %20s (%5.2f packets per second)", tmp_str, ((F32) mPacketsIn / run_time)); /* Flawfinder: ignore */ 3358 snprintf(buffer, MAX_STRING, "Total packets received: %20s (%5.2f packets per second)", tmp_str, ((F32) mPacketsIn / run_time)); /* Flawfinder: ignore */
4802 str << buffer << std::endl; 3359 str << buffer << std::endl;
4803 snprintf(buffer, MAX_STRING, "Average packet size: %20.0f bytes", (F32)mTotalBytesIn / (F32)mPacketsIn); /* Flawfinder: ignore */ 3360 snprintf(buffer, MAX_STRING, "Average packet size: %20.0f bytes", (F32)mTotalBytesIn / (F32)mPacketsIn); /* Flawfinder: ignore */
4804 str << buffer << std::endl; 3361 str << buffer << std::endl;
4805 U64_to_str(mReliablePacketsIn, tmp_str, sizeof(tmp_str)); 3362 U64_to_str(mReliablePacketsIn, tmp_str, sizeof(tmp_str));
4806 snprintf(buffer, MAX_STRING, "Total reliable packets: %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mReliablePacketsIn)/((F32) mPacketsIn + 1)); /* Flawfinder: ignore */ 3363 snprintf(buffer, MAX_STRING, "Total reliable packets: %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mReliablePacketsIn)/((F32) mPacketsIn + 1)); /* Flawfinder: ignore */
4807 str << buffer << std::endl; 3364 str << buffer << std::endl;
4808 U64_to_str(mCompressedPacketsIn, tmp_str, sizeof(tmp_str)); 3365 U64_to_str(mCompressedPacketsIn, tmp_str, sizeof(tmp_str));
4809 snprintf(buffer, MAX_STRING, "Total compressed packets: %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mCompressedPacketsIn)/((F32) mPacketsIn + 1)); /* Flawfinder: ignore */ 3366 snprintf(buffer, MAX_STRING, "Total compressed packets: %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mCompressedPacketsIn)/((F32) mPacketsIn + 1)); /* Flawfinder: ignore */
4810 str << buffer << std::endl; 3367 str << buffer << std::endl;
4811 S64 savings = mUncompressedBytesIn - mCompressedBytesIn; 3368 S64 savings = mUncompressedBytesIn - mCompressedBytesIn;
4812 U64_to_str(savings, tmp_str, sizeof(tmp_str)); 3369 U64_to_str(savings, tmp_str, sizeof(tmp_str));
4813 snprintf(buffer, MAX_STRING, "Total compression savings: %20s bytes", tmp_str); /* Flawfinder: ignore */ 3370 snprintf(buffer, MAX_STRING, "Total compression savings: %20s bytes", tmp_str); /* Flawfinder: ignore */
4814 str << buffer << std::endl; 3371 str << buffer << std::endl;
4815 U64_to_str(savings/(mCompressedPacketsIn +1), tmp_str, sizeof(tmp_str)); 3372 U64_to_str(savings/(mCompressedPacketsIn +1), tmp_str, sizeof(tmp_str));
4816 snprintf(buffer, MAX_STRING, "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str, ((F32) mUncompressedBytesIn)/((F32) mCompressedBytesIn+1)); /* Flawfinder: ignore */ 3373 snprintf(buffer, MAX_STRING, "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str, ((F32) mUncompressedBytesIn)/((F32) mCompressedBytesIn+1)); /* Flawfinder: ignore */
4817 str << buffer << std::endl; 3374 str << buffer << std::endl;
4818 U64_to_str(savings/(mPacketsIn+1), tmp_str, sizeof(tmp_str)); 3375 U64_to_str(savings/(mPacketsIn+1), tmp_str, sizeof(tmp_str));
4819 snprintf(buffer, MAX_STRING, "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str, ((F32) mTotalBytesIn + (F32) savings)/((F32) mTotalBytesIn + 1.f)); /* Flawfinder: ignore */ 3376 snprintf(buffer, MAX_STRING, "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str, ((F32) mTotalBytesIn + (F32) savings)/((F32) mTotalBytesIn + 1.f)); /* Flawfinder: ignore */
4820 3377
4821 // Outgoing 3378 // Outgoing
4822 str << buffer << std::endl << std::endl << "Outgoing:" << std::endl; 3379 str << buffer << std::endl << std::endl << "Outgoing:" << std::endl;
4823 U64_to_str(mTotalBytesOut, tmp_str, sizeof(tmp_str)); 3380 U64_to_str(mTotalBytesOut, tmp_str, sizeof(tmp_str));
4824 snprintf(buffer, MAX_STRING, "Total bytes sent: %20s (%5.2f kbits per second)", tmp_str, ((F32)mTotalBytesOut * 0.008f) / run_time ); /* Flawfinder: ignore */ 3381 snprintf(buffer, MAX_STRING, "Total bytes sent: %20s (%5.2f kbits per second)", tmp_str, ((F32)mTotalBytesOut * 0.008f) / run_time ); /* Flawfinder: ignore */
4825 str << buffer << std::endl; 3382 str << buffer << std::endl;
4826 U64_to_str(mPacketsOut, tmp_str, sizeof(tmp_str)); 3383 U64_to_str(mPacketsOut, tmp_str, sizeof(tmp_str));
4827 snprintf(buffer, MAX_STRING, "Total packets sent: %20s (%5.2f packets per second)", tmp_str, ((F32)mPacketsOut / run_time)); /* Flawfinder: ignore */ 3384 snprintf(buffer, MAX_STRING, "Total packets sent: %20s (%5.2f packets per second)", tmp_str, ((F32)mPacketsOut / run_time)); /* Flawfinder: ignore */
4828 str << buffer << std::endl; 3385 str << buffer << std::endl;
4829 snprintf(buffer, MAX_STRING, "Average packet size: %20.0f bytes", (F32)mTotalBytesOut / (F32)mPacketsOut); /* Flawfinder: ignore */ 3386 snprintf(buffer, MAX_STRING, "Average packet size: %20.0f bytes", (F32)mTotalBytesOut / (F32)mPacketsOut); /* Flawfinder: ignore */
4830 str << buffer << std::endl; 3387 str << buffer << std::endl;
4831 U64_to_str(mReliablePacketsOut, tmp_str, sizeof(tmp_str)); 3388 U64_to_str(mReliablePacketsOut, tmp_str, sizeof(tmp_str));
4832 snprintf(buffer, MAX_STRING, "Total reliable packets: %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mReliablePacketsOut)/((F32) mPacketsOut + 1)); /* Flawfinder: ignore */ 3389 snprintf(buffer, MAX_STRING, "Total reliable packets: %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mReliablePacketsOut)/((F32) mPacketsOut + 1)); /* Flawfinder: ignore */
4833 str << buffer << std::endl; 3390 str << buffer << std::endl;
4834 U64_to_str(mCompressedPacketsOut, tmp_str, sizeof(tmp_str)); 3391 U64_to_str(mCompressedPacketsOut, tmp_str, sizeof(tmp_str));
4835 snprintf(buffer, MAX_STRING, "Total compressed packets: %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mCompressedPacketsOut)/((F32) mPacketsOut + 1)); /* Flawfinder: ignore */ 3392 snprintf(buffer, MAX_STRING, "Total compressed packets: %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mCompressedPacketsOut)/((F32) mPacketsOut + 1)); /* Flawfinder: ignore */
4836 str << buffer << std::endl; 3393 str << buffer << std::endl;
4837 savings = mUncompressedBytesOut - mCompressedBytesOut; 3394 savings = mUncompressedBytesOut - mCompressedBytesOut;
4838 U64_to_str(savings, tmp_str, sizeof(tmp_str)); 3395 U64_to_str(savings, tmp_str, sizeof(tmp_str));
4839 snprintf(buffer, MAX_STRING, "Total compression savings: %20s bytes", tmp_str); /* Flawfinder: ignore */ 3396 snprintf(buffer, MAX_STRING, "Total compression savings: %20s bytes", tmp_str); /* Flawfinder: ignore */
4840 str << buffer << std::endl; 3397 str << buffer << std::endl;
4841 U64_to_str(savings/(mCompressedPacketsOut +1), tmp_str, sizeof(tmp_str)); 3398 U64_to_str(savings/(mCompressedPacketsOut +1), tmp_str, sizeof(tmp_str));
4842 snprintf(buffer, MAX_STRING, "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str, ((F32) mUncompressedBytesOut)/((F32) mCompressedBytesOut+1)); /* Flawfinder: ignore */ 3399 snprintf(buffer, MAX_STRING, "Avg comp packet savings: %20s (%5.2f : 1)", tmp_str, ((F32) mUncompressedBytesOut)/((F32) mCompressedBytesOut+1)); /* Flawfinder: ignore */
4843 str << buffer << std::endl; 3400 str << buffer << std::endl;
4844 U64_to_str(savings/(mPacketsOut+1), tmp_str, sizeof(tmp_str)); 3401 U64_to_str(savings/(mPacketsOut+1), tmp_str, sizeof(tmp_str));
4845 snprintf(buffer, MAX_STRING, "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str, ((F32) mTotalBytesOut + (F32) savings)/((F32) mTotalBytesOut + 1.f)); /* Flawfinder: ignore */ 3402 snprintf(buffer, MAX_STRING, "Avg overall comp savings: %20s (%5.2f : 1)", tmp_str, ((F32) mTotalBytesOut + (F32) savings)/((F32) mTotalBytesOut + 1.f)); /* Flawfinder: ignore */
4846 str << buffer << std::endl << std::endl; 3403 str << buffer << std::endl << std::endl;
4847 snprintf(buffer, MAX_STRING, "SendPacket failures: %20d", mSendPacketFailureCount); /* Flawfinder: ignore */ 3404 snprintf(buffer, MAX_STRING, "SendPacket failures: %20d", mSendPacketFailureCount); /* Flawfinder: ignore */
4848 str << buffer << std::endl; 3405 str << buffer << std::endl;
4849 snprintf(buffer, MAX_STRING, "Dropped packets: %20d", mDroppedPackets); /* Flawfinder: ignore */ 3406 snprintf(buffer, MAX_STRING, "Dropped packets: %20d", mDroppedPackets); /* Flawfinder: ignore */
4850 str << buffer << std::endl; 3407 str << buffer << std::endl;
4851 snprintf(buffer, MAX_STRING, "Resent packets: %20d", mResentPackets); /* Flawfinder: ignore */ 3408 snprintf(buffer, MAX_STRING, "Resent packets: %20d", mResentPackets); /* Flawfinder: ignore */
4852 str << buffer << std::endl; 3409 str << buffer << std::endl;
4853 snprintf(buffer, MAX_STRING, "Failed reliable resends: %20d", mFailedResendPackets); /* Flawfinder: ignore */ 3410 snprintf(buffer, MAX_STRING, "Failed reliable resends: %20d", mFailedResendPackets); /* Flawfinder: ignore */
4854 str << buffer << std::endl; 3411 str << buffer << std::endl;
4855 snprintf(buffer, MAX_STRING, "Off-circuit rejected packets: %17d", mOffCircuitPackets); /* Flawfinder: ignore */ 3412 snprintf(buffer, MAX_STRING, "Off-circuit rejected packets: %17d", mOffCircuitPackets); /* Flawfinder: ignore */
4856 str << buffer << std::endl; 3413 str << buffer << std::endl;
4857 snprintf(buffer, MAX_STRING, "On-circuit invalid packets: %17d", mInvalidOnCircuitPackets); /* Flawfinder: ignore */ 3414 snprintf(buffer, MAX_STRING, "On-circuit invalid packets: %17d", mInvalidOnCircuitPackets); /* Flawfinder: ignore */
4858 str << buffer << std::endl << std::endl; 3415 str << buffer << std::endl << std::endl;
4859 3416
4860 str << "Decoding: " << std::endl; 3417 str << "Decoding: " << std::endl;
4861 snprintf(buffer, MAX_STRING, "%35s%10s%10s%10s%10s", "Message", "Count", "Time", "Max", "Avg"); /* Flawfinder: ignore */ 3418 snprintf(buffer, MAX_STRING, "%35s%10s%10s%10s%10s", "Message", "Count", "Time", "Max", "Avg"); /* Flawfinder: ignore */
4862 str << buffer << std:: endl; 3419 str << buffer << std:: endl;
4863 F32 avg; 3420 F32 avg;
4864 for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), 3421 for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(),
@@ -4869,7 +3426,7 @@ void LLMessageSystem::summarizeLogs(std::ostream& str)
4869 if(mt->mTotalDecoded > 0) 3426 if(mt->mTotalDecoded > 0)
4870 { 3427 {
4871 avg = mt->mTotalDecodeTime / (F32)mt->mTotalDecoded; 3428 avg = mt->mTotalDecodeTime / (F32)mt->mTotalDecoded;
4872 snprintf(buffer, MAX_STRING, "%35s%10u%10f%10f%10f", mt->mName, mt->mTotalDecoded, mt->mTotalDecodeTime, mt->mMaxDecodeTimePerMsg, avg); /* Flawfinder: ignore */ 3429 snprintf(buffer, MAX_STRING, "%35s%10u%10f%10f%10f", mt->mName, mt->mTotalDecoded, mt->mTotalDecodeTime, mt->mMaxDecodeTimePerMsg, avg); /* Flawfinder: ignore */
4873 str << buffer << std::endl; 3430 str << buffer << std::endl;
4874 } 3431 }
4875 } 3432 }
@@ -4957,13 +3514,13 @@ void LLMessageSystem::dumpReceiveCounts()
4957 3514
4958BOOL LLMessageSystem::isClear() const 3515BOOL LLMessageSystem::isClear() const
4959{ 3516{
4960 return mbSClear; 3517 return mMessageBuilder->isClear();
4961} 3518}
4962 3519
4963 3520
4964S32 LLMessageSystem::flush(const LLHost &host) 3521S32 LLMessageSystem::flush(const LLHost &host)
4965{ 3522{
4966 if (mCurrentSendTotal) 3523 if (mMessageBuilder->getMessageSize())
4967 { 3524 {
4968 S32 sentbytes = sendMessage(host); 3525 S32 sentbytes = sendMessage(host);
4969 clearMessage(); 3526 clearMessage();
@@ -4980,91 +3537,22 @@ U32 LLMessageSystem::getListenPort( void ) const
4980 return mPort; 3537 return mPort;
4981} 3538}
4982 3539
4983 3540// TODO: babbage: remove this horror!
4984S32 LLMessageSystem::zeroCode(U8 **data, S32 *data_size) 3541S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
4985{ 3542{
4986 S32 count = *data_size; 3543 if(mMessageBuilder == mLLSDMessageBuilder)
4987
4988 S32 net_gain = 0;
4989 U8 num_zeroes = 0;
4990
4991 U8 *inptr = (U8 *)*data;
4992 U8 *outptr = (U8 *)mEncodedSendBuffer;
4993
4994// skip the packet id field
4995
4996 for (U32 i=0;i<LL_PACKET_ID_SIZE;i++)
4997 {
4998 count--;
4999 *outptr++ = *inptr++;
5000 }
5001
5002// build encoded packet, keeping track of net size gain
5003
5004// sequential zero bytes are encoded as 0 [U8 count]
5005// with 0 0 [count] representing wrap (>256 zeroes)
5006
5007 while (count--)
5008 { 3544 {
5009 if (!(*inptr)) // in a zero count 3545 // babbage: don't compress LLSD messages, so delta is 0
5010 { 3546 return 0;
5011 if (num_zeroes)
5012 {
5013 if (++num_zeroes > 254)
5014 {
5015 *outptr++ = num_zeroes;
5016 num_zeroes = 0;
5017 }
5018 net_gain--; // subseqent zeroes save one
5019 }
5020 else
5021 {
5022 *outptr++ = 0;
5023 net_gain++; // starting a zero count adds one
5024 num_zeroes = 1;
5025 }
5026 inptr++;
5027 }
5028 else
5029 {
5030 if (num_zeroes)
5031 {
5032 *outptr++ = num_zeroes;
5033 num_zeroes = 0;
5034 }
5035 *outptr++ = *inptr++;
5036 }
5037 }
5038
5039 if (num_zeroes)
5040 {
5041 *outptr++ = num_zeroes;
5042 }
5043
5044 if (net_gain < 0)
5045 {
5046 mCompressedPacketsOut++;
5047 mUncompressedBytesOut += *data_size;
5048
5049 *data = mEncodedSendBuffer;
5050 *data_size += net_gain;
5051 mEncodedSendBuffer[0] |= LL_ZERO_CODE_FLAG; // set the head bit to indicate zero coding
5052
5053 mCompressedBytesOut += *data_size;
5054
5055 } 3547 }
5056 mTotalBytesOut += *data_size; 3548
5057 3549 if (! mMessageBuilder->isBuilt())
5058 return(net_gain);
5059}
5060
5061S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
5062{
5063 if (!mbSBuilt)
5064 { 3550 {
5065 buildMessage(); 3551 mSendSize = mMessageBuilder->buildMessage(mSendBuffer,
3552 MAX_BUFFER_SIZE);
5066 } 3553 }
5067 mbSBuilt = FALSE; 3554 // TODO: babbage: remove this horror
3555 mMessageBuilder->setBuilt(FALSE);
5068 3556
5069 S32 count = mSendSize; 3557 S32 count = mSendSize;
5070 3558
@@ -5244,7 +3732,6 @@ void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)(
5244 } 3732 }
5245} 3733}
5246 3734
5247
5248bool LLMessageSystem::callHandler(const char *name, 3735bool LLMessageSystem::callHandler(const char *name,
5249 bool trustedSource, LLMessageSystem* msg) 3736 bool trustedSource, LLMessageSystem* msg)
5250{ 3737{
@@ -5297,6 +3784,12 @@ BOOL LLMessageSystem::callExceptionFunc(EMessageException exception)
5297 return FALSE; 3784 return FALSE;
5298} 3785}
5299 3786
3787void LLMessageSystem::setTimingFunc(msg_timing_callback func, void* data)
3788{
3789 mTimingCallback = func;
3790 mTimingCallbackData = data;
3791}
3792
5300BOOL LLMessageSystem::isCircuitCodeKnown(U32 code) const 3793BOOL LLMessageSystem::isCircuitCodeKnown(U32 code) const
5301{ 3794{
5302 if(mCircuitCodes.find(code) == mCircuitCodes.end()) 3795 if(mCircuitCodes.find(code) == mCircuitCodes.end())
@@ -5306,27 +3799,14 @@ BOOL LLMessageSystem::isCircuitCodeKnown(U32 code) const
5306 3799
5307BOOL LLMessageSystem::isMessageFast(const char *msg) 3800BOOL LLMessageSystem::isMessageFast(const char *msg)
5308{ 3801{
5309 if (mCurrentRMessageTemplate) 3802 return(msg == mMessageReader->getMessageName());
5310 {
5311 return(msg == mCurrentRMessageTemplate->mName);
5312 }
5313 else
5314 {
5315 return FALSE;
5316 }
5317} 3803}
5318 3804
5319 3805
5320char* LLMessageSystem::getMessageName() 3806char* LLMessageSystem::getMessageName()
5321{ 3807{
5322 if (mCurrentRMessageTemplate) 3808 const char* name = mMessageReader->getMessageName();
5323 { 3809 return name[0] == '\0'? NULL : const_cast<char*>(name);
5324 return mCurrentRMessageTemplate->mName;
5325 }
5326 else
5327 {
5328 return NULL;
5329 }
5330} 3810}
5331 3811
5332const LLUUID& LLMessageSystem::getSenderID() const 3812const LLUUID& LLMessageSystem::getSenderID() const
@@ -5350,211 +3830,6 @@ const LLUUID& LLMessageSystem::getSenderSessionID() const
5350 return LLUUID::null; 3830 return LLUUID::null;
5351} 3831}
5352 3832
5353void LLMessageSystem::addVector3Fast(const char *varname, const LLVector3& vec)
5354{
5355 addDataFast(varname, vec.mV, MVT_LLVector3, sizeof(vec.mV));
5356}
5357
5358void LLMessageSystem::addVector3(const char *varname, const LLVector3& vec)
5359{
5360 addDataFast(gMessageStringTable.getString(varname), vec.mV, MVT_LLVector3, sizeof(vec.mV));
5361}
5362
5363void LLMessageSystem::addVector4Fast(const char *varname, const LLVector4& vec)
5364{
5365 addDataFast(varname, vec.mV, MVT_LLVector4, sizeof(vec.mV));
5366}
5367
5368void LLMessageSystem::addVector4(const char *varname, const LLVector4& vec)
5369{
5370 addDataFast(gMessageStringTable.getString(varname), vec.mV, MVT_LLVector4, sizeof(vec.mV));
5371}
5372
5373
5374void LLMessageSystem::addVector3dFast(const char *varname, const LLVector3d& vec)
5375{
5376 addDataFast(varname, vec.mdV, MVT_LLVector3d, sizeof(vec.mdV));
5377}
5378
5379void LLMessageSystem::addVector3d(const char *varname, const LLVector3d& vec)
5380{
5381 addDataFast(gMessageStringTable.getString(varname), vec.mdV, MVT_LLVector3d, sizeof(vec.mdV));
5382}
5383
5384
5385void LLMessageSystem::addQuatFast(const char *varname, const LLQuaternion& quat)
5386{
5387 addDataFast(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3));
5388}
5389
5390void LLMessageSystem::addQuat(const char *varname, const LLQuaternion& quat)
5391{
5392 addDataFast(gMessageStringTable.getString(varname), quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3));
5393}
5394
5395
5396void LLMessageSystem::addUUIDFast(const char *varname, const LLUUID& uuid)
5397{
5398 addDataFast(varname, uuid.mData, MVT_LLUUID, sizeof(uuid.mData));
5399}
5400
5401void LLMessageSystem::addUUID(const char *varname, const LLUUID& uuid)
5402{
5403 addDataFast(gMessageStringTable.getString(varname), uuid.mData, MVT_LLUUID, sizeof(uuid.mData));
5404}
5405
5406void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d, S32 blocknum)
5407{
5408 getDataFast(block, var, &d, sizeof(F32), blocknum);
5409
5410 if( !llfinite( d ) )
5411 {
5412 llwarns << "non-finite in getF32Fast " << block << " " << var << llendl;
5413 d = 0;
5414 }
5415}
5416
5417void LLMessageSystem::getF32(const char *block, const char *var, F32 &d, S32 blocknum)
5418{
5419 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(F32), blocknum);
5420
5421 if( !llfinite( d ) )
5422 {
5423 llwarns << "non-finite in getF32 " << block << " " << var << llendl;
5424 d = 0;
5425 }
5426}
5427
5428void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d, S32 blocknum)
5429{
5430 getDataFast(block, var, &d, sizeof(F64), blocknum);
5431
5432 if( !llfinite( d ) )
5433 {
5434 llwarns << "non-finite in getF64Fast " << block << " " << var << llendl;
5435 d = 0;
5436 }
5437}
5438
5439void LLMessageSystem::getF64(const char *block, const char *var, F64 &d, S32 blocknum)
5440{
5441 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(F64), blocknum);
5442
5443 if( !llfinite( d ) )
5444 {
5445 llwarns << "non-finite in getF64 " << block << " " << var << llendl;
5446 d = 0;
5447 }
5448}
5449
5450
5451void LLMessageSystem::getVector3Fast(const char *block, const char *var, LLVector3 &v, S32 blocknum )
5452{
5453 getDataFast(block, var, v.mV, sizeof(v.mV), blocknum);
5454
5455 if( !v.isFinite() )
5456 {
5457 llwarns << "non-finite in getVector3Fast " << block << " " << var << llendl;
5458 v.zeroVec();
5459 }
5460}
5461
5462void LLMessageSystem::getVector3(const char *block, const char *var, LLVector3 &v, S32 blocknum )
5463{
5464 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mV, sizeof(v.mV), blocknum);
5465
5466 if( !v.isFinite() )
5467 {
5468 llwarns << "non-finite in getVector4 " << block << " " << var << llendl;
5469 v.zeroVec();
5470 }
5471}
5472
5473void LLMessageSystem::getVector4Fast(const char *block, const char *var, LLVector4 &v, S32 blocknum )
5474{
5475 getDataFast(block, var, v.mV, sizeof(v.mV), blocknum);
5476
5477 if( !v.isFinite() )
5478 {
5479 llwarns << "non-finite in getVector4Fast " << block << " " << var << llendl;
5480 v.zeroVec();
5481 }
5482}
5483
5484void LLMessageSystem::getVector4(const char *block, const char *var, LLVector4 &v, S32 blocknum )
5485{
5486 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mV, sizeof(v.mV), blocknum);
5487
5488 if( !v.isFinite() )
5489 {
5490 llwarns << "non-finite in getVector3 " << block << " " << var << llendl;
5491 v.zeroVec();
5492 }
5493}
5494
5495void LLMessageSystem::getVector3dFast(const char *block, const char *var, LLVector3d &v, S32 blocknum )
5496{
5497 getDataFast(block, var, v.mdV, sizeof(v.mdV), blocknum);
5498
5499 if( !v.isFinite() )
5500 {
5501 llwarns << "non-finite in getVector3dFast " << block << " " << var << llendl;
5502 v.zeroVec();
5503 }
5504
5505}
5506
5507void LLMessageSystem::getVector3d(const char *block, const char *var, LLVector3d &v, S32 blocknum )
5508{
5509 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mdV, sizeof(v.mdV), blocknum);
5510
5511 if( !v.isFinite() )
5512 {
5513 llwarns << "non-finite in getVector3d " << block << " " << var << llendl;
5514 v.zeroVec();
5515 }
5516}
5517
5518void LLMessageSystem::getQuatFast(const char *block, const char *var, LLQuaternion &q, S32 blocknum )
5519{
5520 LLVector3 vec;
5521 getDataFast(block, var, vec.mV, sizeof(vec.mV), blocknum);
5522 if( vec.isFinite() )
5523 {
5524 q.unpackFromVector3( vec );
5525 }
5526 else
5527 {
5528 llwarns << "non-finite in getQuatFast " << block << " " << var << llendl;
5529 q.loadIdentity();
5530 }
5531}
5532
5533void LLMessageSystem::getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum )
5534{
5535 LLVector3 vec;
5536 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), vec.mV, sizeof(vec.mV), blocknum);
5537 if( vec.isFinite() )
5538 {
5539 q.unpackFromVector3( vec );
5540 }
5541 else
5542 {
5543 llwarns << "non-finite in getQuat " << block << " " << var << llendl;
5544 q.loadIdentity();
5545 }
5546}
5547
5548void LLMessageSystem::getUUIDFast(const char *block, const char *var, LLUUID &u, S32 blocknum )
5549{
5550 getDataFast(block, var, u.mData, sizeof(u.mData), blocknum);
5551}
5552
5553void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u, S32 blocknum )
5554{
5555 getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), u.mData, sizeof(u.mData), blocknum);
5556}
5557
5558bool LLMessageSystem::generateDigestForNumberAndUUIDs( 3833bool LLMessageSystem::generateDigestForNumberAndUUIDs(
5559 char* digest, 3834 char* digest,
5560 const U32 number, 3835 const U32 number,
@@ -5584,7 +3859,7 @@ bool LLMessageSystem::generateDigestForNumberAndUUIDs(
5584 3859
5585 d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ 3860 d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */
5586 3861
5587 snprintf(tbuf, sizeof(tbuf),"%i", number); /* Flawfinder: ignore */ 3862 snprintf(tbuf, sizeof(tbuf),"%i", number); /* Flawfinder: ignore */
5588 d.update((unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */ 3863 d.update((unsigned char *) tbuf, (U32)strlen(tbuf)); /* Flawfinder: ignore */
5589 3864
5590 d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */ 3865 d.update((const unsigned char *) colon, (U32)strlen(colon)); /* Flawfinder: ignore */
@@ -5843,7 +4118,7 @@ void LLMessageSystem::dumpPacketToLog()
5843 S32 cur_line = 0; 4118 S32 cur_line = 0;
5844 for (i = 0; i < mTrueReceiveSize; i++) 4119 for (i = 0; i < mTrueReceiveSize; i++)
5845 { 4120 {
5846 snprintf(line_buffer + cur_line_pos*3, sizeof(line_buffer),"%02x ", mTrueReceiveBuffer[i]); /* Flawfinder: ignore */ 4121 snprintf(line_buffer + cur_line_pos*3, sizeof(line_buffer),"%02x ", mTrueReceiveBuffer[i]); /* Flawfinder: ignore */
5847 cur_line_pos++; 4122 cur_line_pos++;
5848 if (cur_line_pos >= 16) 4123 if (cur_line_pos >= 16)
5849 { 4124 {
@@ -5859,6 +4134,121 @@ void LLMessageSystem::dumpPacketToLog()
5859} 4134}
5860 4135
5861//static 4136//static
4137BOOL LLMessageSystem::isTemplateConfirmed()
4138{
4139 return gMessageSystem->mTemplateConfirmed;
4140}
4141
4142//static
4143BOOL LLMessageSystem::doesTemplateMatch()
4144{
4145 if (!isTemplateConfirmed())
4146 {
4147 return FALSE;
4148 }
4149 return gMessageSystem->mTemplateMatches;
4150}
4151
4152//static
4153void LLMessageSystem::sendMessageTemplateChecksum(const LLHost &currentHost)
4154{
4155 gMessageSystem->mTemplateConfirmed = FALSE;
4156 gMessageSystem->mTemplateMatches = FALSE;
4157 gMessageSystem->newMessageFast(_PREHASH_TemplateChecksumRequest);
4158 // Don't use ping-based retry
4159 gMessageSystem->sendReliable(currentHost, 40, FALSE, 3, NULL, NULL);
4160}
4161
4162//static
4163void LLMessageSystem::processMessageTemplateChecksumReply(LLMessageSystem *msg,
4164 void** user_data)
4165{
4166 U32 remote_template_checksum = 0;
4167 msg->getU32Fast(_PREHASH_DataBlock, _PREHASH_Checksum, remote_template_checksum);
4168 msg->mTemplateConfirmed = TRUE;
4169 if ((remote_template_checksum) != msg->mMessageFileChecksum)
4170 {
4171 llwarns << "out of sync message template!" << llendl;
4172
4173 msg->mTemplateMatches = FALSE;
4174 msg->newMessageFast(_PREHASH_CloseCircuit);
4175 msg->sendMessage(msg->getSender());
4176 return;
4177 }
4178
4179 msg->mTemplateMatches = TRUE;
4180 llinfos << "According to " << msg->getSender()
4181 << " the message template is current!"
4182 << llendl;
4183}
4184
4185//static
4186void LLMessageSystem::sendSecureMessageTemplateChecksum(const LLHost& host)
4187{
4188 // generate an token for use during template checksum requests to
4189 // prevent DOS attacks from injected bad template checksum replies.
4190 LLUUID *template_tokenp = new LLUUID;
4191 template_tokenp->generate();
4192 lldebugs << "random token: " << *template_tokenp << llendl;
4193
4194 // register the handler for the reply while saving off template_token
4195 gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumReply,
4196 LLMessageSystem::processSecureTemplateChecksumReply,
4197 (void**)template_tokenp);
4198
4199 // send checksum request
4200 gMessageSystem->mTemplateConfirmed = FALSE;
4201 gMessageSystem->newMessageFast(_PREHASH_SecuredTemplateChecksumRequest);
4202 gMessageSystem->nextBlockFast(_PREHASH_TokenBlock);
4203 gMessageSystem->addUUIDFast(_PREHASH_Token, *template_tokenp);
4204 gMessageSystem->sendReliable(host);
4205}
4206
4207//static
4208void LLMessageSystem::processSecureTemplateChecksumReply(LLMessageSystem *msg,
4209 void** user_data)
4210{
4211 // copy the token out into the stack and delete allocated memory
4212 LLUUID template_token = *((LLUUID*)user_data);
4213 delete user_data;
4214
4215 LLUUID received_token;
4216 msg->getUUID("TokenBlock", "Token", received_token);
4217
4218 if(received_token != template_token)
4219 {
4220 llwarns << "Incorrect token in template checksum reply: "
4221 << received_token << llendl;
4222 //return do_normal_idle;
4223 return;
4224 }
4225
4226 U32 remote_template_checksum = 0;
4227 U8 major_version = 0;
4228 U8 minor_version = 0;
4229 U8 patch_version = 0;
4230 U8 server_version = 0;
4231 U32 flags = 0x0;
4232 msg->getU32("DataBlock", "Checksum", remote_template_checksum);
4233 msg->getU8 ("DataBlock", "MajorVersion", major_version);
4234 msg->getU8 ("DataBlock", "MinorVersion", minor_version);
4235 msg->getU8 ("DataBlock", "PatchVersion", patch_version);
4236 msg->getU8 ("DataBlock", "ServerVersion", server_version);
4237 msg->getU32("DataBlock", "Flags", flags);
4238
4239 msg->mTemplateConfirmed = TRUE;
4240 if (remote_template_checksum != gMessageSystem->mMessageFileChecksum)
4241 {
4242 llinfos << "Message template out of sync" << llendl;
4243 msg->mTemplateMatches = FALSE;
4244 }
4245 else
4246 {
4247 msg->mTemplateMatches = TRUE;
4248 }
4249}
4250
4251//static
5862U64 LLMessageSystem::getMessageTimeUsecs(const BOOL update) 4252U64 LLMessageSystem::getMessageTimeUsecs(const BOOL update)
5863{ 4253{
5864 if (gMessageSystem) 4254 if (gMessageSystem)
@@ -5903,3 +4293,558 @@ std::string get_shared_secret()
5903 return g_shared_secret; 4293 return g_shared_secret;
5904} 4294}
5905 4295
4296typedef std::map<const char*, LLMessageBuilder*> BuilderMap;
4297
4298static void setBuilder(BuilderMap& map, const char* name, LLMessageBuilder* builder)
4299{
4300 map[gMessageStringTable.getString(name)] = builder;
4301}
4302
4303void LLMessageSystem::newMessageFast(const char *name)
4304{
4305 if(LLMessageConfig::isMessageBuiltTemplate(name))
4306 {
4307 mMessageBuilder = mTemplateMessageBuilder;
4308 }
4309 else
4310 {
4311 mMessageBuilder = mLLSDMessageBuilder;
4312 }
4313 mSendReliable = FALSE;
4314 mMessageBuilder->newMessage(name);
4315}
4316
4317void LLMessageSystem::newMessage(const char *name)
4318{
4319 newMessageFast(gMessageStringTable.getString(name));
4320}
4321
4322void LLMessageSystem::addBinaryDataFast(const char *varname, const void *data, S32 size)
4323{
4324 mMessageBuilder->addBinaryData(varname, data, size);
4325}
4326
4327void LLMessageSystem::addBinaryData(const char *varname, const void *data, S32 size)
4328{
4329 mMessageBuilder->addBinaryData(gMessageStringTable.getString(varname),data, size);
4330}
4331
4332void LLMessageSystem::addS8Fast(const char *varname, S8 v)
4333{
4334 mMessageBuilder->addS8(varname, v);
4335}
4336
4337void LLMessageSystem::addS8(const char *varname, S8 v)
4338{
4339 mMessageBuilder->addS8(gMessageStringTable.getString(varname), v);
4340}
4341
4342void LLMessageSystem::addU8Fast(const char *varname, U8 v)
4343{
4344 mMessageBuilder->addU8(varname, v);
4345}
4346
4347void LLMessageSystem::addU8(const char *varname, U8 v)
4348{
4349 mMessageBuilder->addU8(gMessageStringTable.getString(varname), v);
4350}
4351
4352void LLMessageSystem::addS16Fast(const char *varname, S16 v)
4353{
4354 mMessageBuilder->addS16(varname, v);
4355}
4356
4357void LLMessageSystem::addS16(const char *varname, S16 v)
4358{
4359 mMessageBuilder->addS16(gMessageStringTable.getString(varname), v);
4360}
4361
4362void LLMessageSystem::addU16Fast(const char *varname, U16 v)
4363{
4364 mMessageBuilder->addU16(varname, v);
4365}
4366
4367void LLMessageSystem::addU16(const char *varname, U16 v)
4368{
4369 mMessageBuilder->addU16(gMessageStringTable.getString(varname), v);
4370}
4371
4372void LLMessageSystem::addF32Fast(const char *varname, F32 v)
4373{
4374 mMessageBuilder->addF32(varname, v);
4375}
4376
4377void LLMessageSystem::addF32(const char *varname, F32 v)
4378{
4379 mMessageBuilder->addF32(gMessageStringTable.getString(varname), v);
4380}
4381
4382void LLMessageSystem::addS32Fast(const char *varname, S32 v)
4383{
4384 mMessageBuilder->addS32(varname, v);
4385}
4386
4387void LLMessageSystem::addS32(const char *varname, S32 v)
4388{
4389 mMessageBuilder->addS32(gMessageStringTable.getString(varname), v);
4390}
4391
4392void LLMessageSystem::addU32Fast(const char *varname, U32 v)
4393{
4394 mMessageBuilder->addU32(varname, v);
4395}
4396
4397void LLMessageSystem::addU32(const char *varname, U32 v)
4398{
4399 mMessageBuilder->addU32(gMessageStringTable.getString(varname), v);
4400}
4401
4402void LLMessageSystem::addU64Fast(const char *varname, U64 v)
4403{
4404 mMessageBuilder->addU64(varname, v);
4405}
4406
4407void LLMessageSystem::addU64(const char *varname, U64 v)
4408{
4409 mMessageBuilder->addU64(gMessageStringTable.getString(varname), v);
4410}
4411
4412void LLMessageSystem::addF64Fast(const char *varname, F64 v)
4413{
4414 mMessageBuilder->addF64(varname, v);
4415}
4416
4417void LLMessageSystem::addF64(const char *varname, F64 v)
4418{
4419 mMessageBuilder->addF64(gMessageStringTable.getString(varname), v);
4420}
4421
4422void LLMessageSystem::addIPAddrFast(const char *varname, U32 v)
4423{
4424 mMessageBuilder->addIPAddr(varname, v);
4425}
4426
4427void LLMessageSystem::addIPAddr(const char *varname, U32 v)
4428{
4429 mMessageBuilder->addIPAddr(gMessageStringTable.getString(varname), v);
4430}
4431
4432void LLMessageSystem::addIPPortFast(const char *varname, U16 v)
4433{
4434 mMessageBuilder->addIPPort(varname, v);
4435}
4436
4437void LLMessageSystem::addIPPort(const char *varname, U16 v)
4438{
4439 mMessageBuilder->addIPPort(gMessageStringTable.getString(varname), v);
4440}
4441
4442void LLMessageSystem::addBOOLFast(const char* varname, BOOL v)
4443{
4444 mMessageBuilder->addBOOL(varname, v);
4445}
4446
4447void LLMessageSystem::addBOOL(const char* varname, BOOL v)
4448{
4449 mMessageBuilder->addBOOL(gMessageStringTable.getString(varname), v);
4450}
4451
4452void LLMessageSystem::addStringFast(const char* varname, const char* v)
4453{
4454 mMessageBuilder->addString(varname, v);
4455}
4456
4457void LLMessageSystem::addString(const char* varname, const char* v)
4458{
4459 mMessageBuilder->addString(gMessageStringTable.getString(varname), v);
4460}
4461
4462void LLMessageSystem::addStringFast(const char* varname, const std::string& v)
4463{
4464 mMessageBuilder->addString(varname, v);
4465}
4466
4467void LLMessageSystem::addString(const char* varname, const std::string& v)
4468{
4469 mMessageBuilder->addString(gMessageStringTable.getString(varname), v);
4470}
4471
4472void LLMessageSystem::addVector3Fast(const char *varname, const LLVector3& v)
4473{
4474 mMessageBuilder->addVector3(varname, v);
4475}
4476
4477void LLMessageSystem::addVector3(const char *varname, const LLVector3& v)
4478{
4479 mMessageBuilder->addVector3(gMessageStringTable.getString(varname), v);
4480}
4481
4482void LLMessageSystem::addVector4Fast(const char *varname, const LLVector4& v)
4483{
4484 mMessageBuilder->addVector4(varname, v);
4485}
4486
4487void LLMessageSystem::addVector4(const char *varname, const LLVector4& v)
4488{
4489 mMessageBuilder->addVector4(gMessageStringTable.getString(varname), v);
4490}
4491
4492void LLMessageSystem::addVector3dFast(const char *varname, const LLVector3d& v)
4493{
4494 mMessageBuilder->addVector3d(varname, v);
4495}
4496
4497void LLMessageSystem::addVector3d(const char *varname, const LLVector3d& v)
4498{
4499 mMessageBuilder->addVector3d(gMessageStringTable.getString(varname), v);
4500}
4501
4502void LLMessageSystem::addQuatFast(const char *varname, const LLQuaternion& v)
4503{
4504 mMessageBuilder->addQuat(varname, v);
4505}
4506
4507void LLMessageSystem::addQuat(const char *varname, const LLQuaternion& v)
4508{
4509 mMessageBuilder->addQuat(gMessageStringTable.getString(varname), v);
4510}
4511
4512
4513void LLMessageSystem::addUUIDFast(const char *varname, const LLUUID& v)
4514{
4515 mMessageBuilder->addUUID(varname, v);
4516}
4517
4518void LLMessageSystem::addUUID(const char *varname, const LLUUID& v)
4519{
4520 mMessageBuilder->addUUID(gMessageStringTable.getString(varname), v);
4521}
4522
4523S32 LLMessageSystem::getCurrentSendTotal() const
4524{
4525 return mMessageBuilder->getMessageSize();
4526}
4527
4528void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u,
4529 S32 blocknum)
4530{
4531 mMessageReader->getS8(block, var, u, blocknum);
4532}
4533
4534void LLMessageSystem::getS8(const char *block, const char *var, S8 &u,
4535 S32 blocknum)
4536{
4537 getS8Fast(gMessageStringTable.getString(block),
4538 gMessageStringTable.getString(var), u, blocknum);
4539}
4540
4541void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u,
4542 S32 blocknum)
4543{
4544 mMessageReader->getU8(block, var, u, blocknum);
4545}
4546
4547void LLMessageSystem::getU8(const char *block, const char *var, U8 &u,
4548 S32 blocknum)
4549{
4550 getU8Fast(gMessageStringTable.getString(block),
4551 gMessageStringTable.getString(var), u, blocknum);
4552}
4553
4554void LLMessageSystem::getBOOLFast(const char *block, const char *var, BOOL &b,
4555 S32 blocknum)
4556{
4557 mMessageReader->getBOOL(block, var, b, blocknum);
4558}
4559
4560void LLMessageSystem::getBOOL(const char *block, const char *var, BOOL &b,
4561 S32 blocknum)
4562{
4563 getBOOLFast(gMessageStringTable.getString(block),
4564 gMessageStringTable.getString(var), b, blocknum);
4565}
4566
4567void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d,
4568 S32 blocknum)
4569{
4570 mMessageReader->getS16(block, var, d, blocknum);
4571}
4572
4573void LLMessageSystem::getS16(const char *block, const char *var, S16 &d,
4574 S32 blocknum)
4575{
4576 getS16Fast(gMessageStringTable.getString(block),
4577 gMessageStringTable.getString(var), d, blocknum);
4578}
4579
4580void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d,
4581 S32 blocknum)
4582{
4583 mMessageReader->getU16(block, var, d, blocknum);
4584}
4585
4586void LLMessageSystem::getU16(const char *block, const char *var, U16 &d,
4587 S32 blocknum)
4588{
4589 getU16Fast(gMessageStringTable.getString(block),
4590 gMessageStringTable.getString(var), d, blocknum);
4591}
4592
4593void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d,
4594 S32 blocknum)
4595{
4596 mMessageReader->getS32(block, var, d, blocknum);
4597}
4598
4599void LLMessageSystem::getS32(const char *block, const char *var, S32 &d,
4600 S32 blocknum)
4601{
4602 getS32Fast(gMessageStringTable.getString(block),
4603 gMessageStringTable.getString(var), d, blocknum);
4604}
4605
4606void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d,
4607 S32 blocknum)
4608{
4609 mMessageReader->getU32(block, var, d, blocknum);
4610}
4611
4612void LLMessageSystem::getU32(const char *block, const char *var, U32 &d,
4613 S32 blocknum)
4614{
4615 getU32Fast(gMessageStringTable.getString(block),
4616 gMessageStringTable.getString(var), d, blocknum);
4617}
4618
4619void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d,
4620 S32 blocknum)
4621{
4622 mMessageReader->getU64(block, var, d, blocknum);
4623}
4624
4625void LLMessageSystem::getU64(const char *block, const char *var, U64 &d,
4626 S32 blocknum)
4627{
4628
4629 getU64Fast(gMessageStringTable.getString(block),
4630 gMessageStringTable.getString(var), d, blocknum);
4631}
4632
4633void LLMessageSystem::getBinaryDataFast(const char *blockname,
4634 const char *varname,
4635 void *datap, S32 size,
4636 S32 blocknum, S32 max_size)
4637{
4638 mMessageReader->getBinaryData(blockname, varname, datap, size, blocknum,
4639 max_size);
4640}
4641
4642void LLMessageSystem::getBinaryData(const char *blockname,
4643 const char *varname,
4644 void *datap, S32 size,
4645 S32 blocknum, S32 max_size)
4646{
4647 getBinaryDataFast(gMessageStringTable.getString(blockname),
4648 gMessageStringTable.getString(varname),
4649 datap, size, blocknum, max_size);
4650}
4651
4652void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d,
4653 S32 blocknum)
4654{
4655 mMessageReader->getF32(block, var, d, blocknum);
4656}
4657
4658void LLMessageSystem::getF32(const char *block, const char *var, F32 &d,
4659 S32 blocknum)
4660{
4661 getF32Fast(gMessageStringTable.getString(block),
4662 gMessageStringTable.getString(var), d, blocknum);
4663}
4664
4665void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d,
4666 S32 blocknum)
4667{
4668 mMessageReader->getF64(block, var, d, blocknum);
4669}
4670
4671void LLMessageSystem::getF64(const char *block, const char *var, F64 &d,
4672 S32 blocknum)
4673{
4674 getF64Fast(gMessageStringTable.getString(block),
4675 gMessageStringTable.getString(var), d, blocknum);
4676}
4677
4678
4679void LLMessageSystem::getVector3Fast(const char *block, const char *var,
4680 LLVector3 &v, S32 blocknum )
4681{
4682 mMessageReader->getVector3(block, var, v, blocknum);
4683}
4684
4685void LLMessageSystem::getVector3(const char *block, const char *var,
4686 LLVector3 &v, S32 blocknum )
4687{
4688 getVector3Fast(gMessageStringTable.getString(block),
4689 gMessageStringTable.getString(var), v, blocknum);
4690}
4691
4692void LLMessageSystem::getVector4Fast(const char *block, const char *var,
4693 LLVector4 &v, S32 blocknum )
4694{
4695 mMessageReader->getVector4(block, var, v, blocknum);
4696}
4697
4698void LLMessageSystem::getVector4(const char *block, const char *var,
4699 LLVector4 &v, S32 blocknum )
4700{
4701 getVector4Fast(gMessageStringTable.getString(block),
4702 gMessageStringTable.getString(var), v, blocknum);
4703}
4704
4705void LLMessageSystem::getVector3dFast(const char *block, const char *var,
4706 LLVector3d &v, S32 blocknum )
4707{
4708 mMessageReader->getVector3d(block, var, v, blocknum);
4709}
4710
4711void LLMessageSystem::getVector3d(const char *block, const char *var,
4712 LLVector3d &v, S32 blocknum )
4713{
4714 getVector3dFast(gMessageStringTable.getString(block),
4715 gMessageStringTable.getString(var), v, blocknum);
4716}
4717
4718void LLMessageSystem::getQuatFast(const char *block, const char *var,
4719 LLQuaternion &q, S32 blocknum )
4720{
4721 mMessageReader->getQuat(block, var, q, blocknum);
4722}
4723
4724void LLMessageSystem::getQuat(const char *block, const char *var,
4725 LLQuaternion &q, S32 blocknum)
4726{
4727 getQuatFast(gMessageStringTable.getString(block),
4728 gMessageStringTable.getString(var), q, blocknum);
4729}
4730
4731void LLMessageSystem::getUUIDFast(const char *block, const char *var,
4732 LLUUID &u, S32 blocknum )
4733{
4734 mMessageReader->getUUID(block, var, u, blocknum);
4735}
4736
4737void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u,
4738 S32 blocknum )
4739{
4740 getUUIDFast(gMessageStringTable.getString(block),
4741 gMessageStringTable.getString(var), u, blocknum);
4742}
4743
4744void LLMessageSystem::getIPAddrFast(const char *block, const char *var,
4745 U32 &u, S32 blocknum)
4746{
4747 mMessageReader->getIPAddr(block, var, u, blocknum);
4748}
4749
4750void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u,
4751 S32 blocknum)
4752{
4753 getIPAddrFast(gMessageStringTable.getString(block),
4754 gMessageStringTable.getString(var), u, blocknum);
4755}
4756
4757void LLMessageSystem::getIPPortFast(const char *block, const char *var,
4758 U16 &u, S32 blocknum)
4759{
4760 mMessageReader->getIPPort(block, var, u, blocknum);
4761}
4762
4763void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u,
4764 S32 blocknum)
4765{
4766 getIPPortFast(gMessageStringTable.getString(block),
4767 gMessageStringTable.getString(var), u,
4768 blocknum);
4769}
4770
4771
4772void LLMessageSystem::getStringFast(const char *block, const char *var,
4773 S32 buffer_size, char *s, S32 blocknum)
4774{
4775 mMessageReader->getString(block, var, buffer_size, s, blocknum);
4776}
4777
4778void LLMessageSystem::getString(const char *block, const char *var,
4779 S32 buffer_size, char *s, S32 blocknum )
4780{
4781 getStringFast(gMessageStringTable.getString(block),
4782 gMessageStringTable.getString(var), buffer_size, s,
4783 blocknum);
4784}
4785
4786S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname)
4787{
4788 return mMessageReader->getNumberOfBlocks(blockname);
4789}
4790
4791S32 LLMessageSystem::getNumberOfBlocks(const char *blockname)
4792{
4793 return getNumberOfBlocksFast(gMessageStringTable.getString(blockname));
4794}
4795
4796S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname)
4797{
4798 return mMessageReader->getSize(blockname, varname);
4799}
4800
4801S32 LLMessageSystem::getSize(const char *blockname, const char *varname)
4802{
4803 return getSizeFast(gMessageStringTable.getString(blockname),
4804 gMessageStringTable.getString(varname));
4805}
4806
4807// size in bytes of variable length data
4808S32 LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum,
4809 const char *varname)
4810{
4811 return mMessageReader->getSize(blockname, blocknum, varname);
4812}
4813
4814S32 LLMessageSystem::getSize(const char *blockname, S32 blocknum,
4815 const char *varname)
4816{
4817 return getSizeFast(gMessageStringTable.getString(blockname), blocknum,
4818 gMessageStringTable.getString(varname));
4819}
4820
4821S32 LLMessageSystem::getReceiveSize() const
4822{
4823 return mMessageReader->getMessageSize();
4824}
4825
4826//static
4827void LLMessageSystem::setTimeDecodes( BOOL b )
4828{
4829 LLMessageReader::setTimeDecodes(b);
4830}
4831
4832//static
4833void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds )
4834{
4835 LLMessageReader::setTimeDecodesSpamThreshold(seconds);
4836}
4837
4838// HACK! babbage: return true if message rxed via either UDP or HTTP
4839// TODO: babbage: move gServicePump in to LLMessageSystem?
4840bool LLMessageSystem::checkAllMessages(S64 frame_count, LLPumpIO* http_pump)
4841{
4842 if(checkMessages(frame_count))
4843 {
4844 return true;
4845 }
4846 U32 packetsIn = mPacketsIn;
4847 http_pump->pump();
4848 http_pump->callback();
4849 return (mPacketsIn - packetsIn) > 0;
4850}