aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmessage/message.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:02 -0500
committerJacek Antonelli2008-08-15 23:45:02 -0500
commitd644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd (patch)
tree7ed0c2c27d717801238a2e6b5749cd5bf88c3059 /linden/indra/llmessage/message.cpp
parentSecond Life viewer sources 1.17.3.0 (diff)
downloadmeta-impy-d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd.zip
meta-impy-d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd.tar.gz
meta-impy-d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd.tar.bz2
meta-impy-d644fc64407dcd14ffcee6a0e9fbe28ee3a4e9bd.tar.xz
Second Life viewer sources 1.18.0.6
Diffstat (limited to '')
-rw-r--r--linden/indra/llmessage/message.cpp1612
1 files changed, 349 insertions, 1263 deletions
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp
index d1c2875..01dce40 100644
--- a/linden/indra/llmessage/message.cpp
+++ b/linden/indra/llmessage/message.cpp
@@ -67,9 +67,12 @@
67#include "lltemplatemessagebuilder.h" 67#include "lltemplatemessagebuilder.h"
68#include "lltemplatemessagereader.h" 68#include "lltemplatemessagereader.h"
69#include "llmessagetemplate.h" 69#include "llmessagetemplate.h"
70#include "llmessagetemplateparser.h"
70#include "llsd.h" 71#include "llsd.h"
71#include "llsdmessagebuilder.h" 72#include "llsdmessagebuilder.h"
72#include "llsdmessagereader.h" 73#include "llsdmessagereader.h"
74#include "llsdserialize.h"
75#include "llstring.h"
73#include "lltransfermanager.h" 76#include "lltransfermanager.h"
74#include "lluuid.h" 77#include "lluuid.h"
75#include "llxfermanager.h" 78#include "llxfermanager.h"
@@ -100,220 +103,28 @@ public:
100 apr_pollfd_t mPollFD; 103 apr_pollfd_t mPollFD;
101}; 104};
102 105
103// Lets support a small subset of regular expressions here
104// Syntax is a string made up of:
105// a - checks against alphanumeric ([A-Za-z0-9])
106// c - checks against character ([A-Za-z])
107// f - checks against first variable character ([A-Za-z_])
108// v - checks against variable ([A-Za-z0-9_])
109// s - checks against sign of integer ([-0-9])
110// d - checks against integer digit ([0-9])
111// * - repeat last check
112
113// checks 'a'
114BOOL b_return_alphanumeric_ok(char c)
115{
116 if ( ( (c < 'A')
117 ||(c > 'Z'))
118 &&( (c < 'a')
119 ||(c > 'z'))
120 &&( (c < '0')
121 ||(c > '9')))
122 {
123 return FALSE;
124 }
125 return TRUE;
126}
127
128// checks 'c'
129BOOL b_return_character_ok(char c)
130{
131 if ( ( (c < 'A')
132 ||(c > 'Z'))
133 &&( (c < 'a')
134 ||(c > 'z')))
135 {
136 return FALSE;
137 }
138 return TRUE;
139}
140
141// checks 'f'
142BOOL b_return_first_variable_ok(char c)
143{
144 if ( ( (c < 'A')
145 ||(c > 'Z'))
146 &&( (c < 'a')
147 ||(c > 'z'))
148 &&(c != '_'))
149 {
150 return FALSE;
151 }
152 return TRUE;
153}
154
155// checks 'v'
156BOOL b_return_variable_ok(char c)
157{
158 if ( ( (c < 'A')
159 ||(c > 'Z'))
160 &&( (c < 'a')
161 ||(c > 'z'))
162 &&( (c < '0')
163 ||(c > '9'))
164 &&(c != '_'))
165 {
166 return FALSE;
167 }
168 return TRUE;
169}
170
171// checks 's'
172BOOL b_return_signed_integer_ok(char c)
173{
174 if ( ( (c < '0')
175 ||(c > '9'))
176 &&(c != '-'))
177 {
178 return FALSE;
179 }
180 return TRUE;
181}
182
183// checks 'd'
184BOOL b_return_integer_ok(char c)
185{
186 if ( (c < '0')
187 ||(c > '9'))
188 {
189 return FALSE;
190 }
191 return TRUE;
192}
193
194BOOL (*gParseCheckCharacters[])(char c) =
195{
196 b_return_alphanumeric_ok,
197 b_return_character_ok,
198 b_return_first_variable_ok,
199 b_return_variable_ok,
200 b_return_signed_integer_ok,
201 b_return_integer_ok
202};
203
204S32 get_checker_number(char checker)
205{
206 switch(checker)
207 {
208 case 'a':
209 return 0;
210 case 'c':
211 return 1;
212 case 'f':
213 return 2;
214 case 'v':
215 return 3;
216 case 's':
217 return 4;
218 case 'd':
219 return 5;
220 case '*':
221 return 9999;
222 default:
223 return -1;
224 }
225}
226
227// check token based on passed simplified regular expression
228BOOL b_check_token(char *token, char *regexp)
229{
230 S32 tptr, rptr = 0;
231 S32 current_checker, next_checker = 0;
232
233 current_checker = get_checker_number(regexp[rptr++]);
234
235 if (current_checker == -1)
236 {
237 llerrs << "Invalid regular expression value!" << llendl;
238 return FALSE;
239 }
240
241 if (current_checker == 9999)
242 {
243 llerrs << "Regular expression can't start with *!" << llendl;
244 return FALSE;
245 }
246
247 for (tptr = 0; token[tptr]; tptr++)
248 {
249 if (current_checker == -1)
250 {
251 llerrs << "Input exceeds regular expression!\nDid you forget a *?" << llendl;
252 return FALSE;
253 }
254
255 if (!gParseCheckCharacters[current_checker](token[tptr]))
256 {
257 return FALSE;
258 }
259 if (next_checker != 9999)
260 {
261 next_checker = get_checker_number(regexp[rptr++]);
262 if (next_checker != 9999)
263 {
264 current_checker = next_checker;
265 }
266 }
267 }
268 return TRUE;
269}
270
271// C variable can be made up of upper or lower case letters, underscores, or numbers, but can't start with a number
272BOOL b_variable_ok(char *token)
273{
274 if (!b_check_token(token, "fv*"))
275 {
276 llerrs << "Token '" << token << "' isn't a variable!" << llendl;
277 return FALSE;
278 }
279 return TRUE;
280}
281
282// An integer is made up of the digits 0-9 and may be preceded by a '-'
283BOOL b_integer_ok(char *token)
284{
285 if (!b_check_token(token, "sd*"))
286 {
287 llerrs << "Token isn't an integer!" << llendl;
288 return FALSE;
289 }
290 return TRUE;
291}
292
293// An integer is made up of the digits 0-9
294BOOL b_positive_integer_ok(char *token)
295{
296 if (!b_check_token(token, "d*"))
297 {
298 llerrs << "Token isn't an integer!" << llendl;
299 return FALSE;
300 }
301 return TRUE;
302}
303
304namespace 106namespace
305{ 107{
306 class LLFnPtrResponder : public LLHTTPClient::Responder 108 class LLFnPtrResponder : public LLHTTPClient::Responder
307 { 109 {
110 LOG_CLASS(LLFnPtrResponder);
308 public: 111 public:
309 LLFnPtrResponder(void (*callback)(void **,S32), void **callbackData) : 112 LLFnPtrResponder(void (*callback)(void **,S32), void **callbackData, const std::string& name) :
310 mCallback(callback), 113 mCallback(callback),
311 mCallbackData(callbackData) 114 mCallbackData(callbackData),
115 mMessageName(name)
312 { 116 {
313 } 117 }
314 118
315 virtual void error(U32 status, const std::string& reason) 119 virtual void error(U32 status, const std::string& reason)
316 { 120 {
121 // don't spam when agent communication disconnected already
122 if (status != 410)
123 {
124 llwarns << "error status " << status
125 << " for message " << mMessageName
126 << " reason " << reason << llendl;
127 }
317 // TODO: Map status in to useful error code. 128 // TODO: Map status in to useful error code.
318 if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT); 129 if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT);
319 } 130 }
@@ -327,6 +138,7 @@ namespace
327 138
328 void (*mCallback)(void **,S32); 139 void (*mCallback)(void **,S32);
329 void **mCallbackData; 140 void **mCallbackData;
141 std::string mMessageName;
330 }; 142 };
331} 143}
332 144
@@ -352,10 +164,28 @@ void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response,
352 ["x-secondlife-udp-listen-port"]; 164 ["x-secondlife-udp-listen-port"];
353 165
354 LLSD message_data; 166 LLSD message_data;
355 message_data["sender"] = senderIP + ":" + senderPort; 167 std::string sender = senderIP + ":" + senderPort;
168 message_data["sender"] = sender;
356 message_data["body"] = input; 169 message_data["body"] = input;
357 170
358 LLMessageSystem::dispatch(name, message_data, response); 171 // untrusted senders should not have access to the trusted message
172 // service, but this can happen in development, so check and warn
173 LLMessageConfig::SenderTrust trust =
174 LLMessageConfig::getSenderTrustedness(name);
175 if ((trust == LLMessageConfig::TRUSTED ||
176 (trust == LLMessageConfig::NOT_SET &&
177 gMessageSystem->isTrustedMessage(name)))
178 && !gMessageSystem->isTrustedSender(LLHost(sender)))
179 {
180 llwarns << "trusted message POST to /trusted-message/"
181 << name << " from unknown or untrusted sender "
182 << sender << llendl;
183 response->status(403, "Unknown or untrusted sender");
184 }
185 else
186 {
187 LLMessageSystem::dispatch(name, message_data, response);
188 }
359} 189}
360 190
361class LLMessageHandlerBridge : public LLHTTPNode 191class LLMessageHandlerBridge : public LLHTTPNode
@@ -372,14 +202,15 @@ void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,
372 const LLSD& context, const LLSD& input) const 202 const LLSD& context, const LLSD& input) const
373{ 203{
374 std::string name = context["request"]["wildcard"]["message-name"]; 204 std::string name = context["request"]["wildcard"]["message-name"];
375 205 char* namePtr = gMessageStringTable.getString(name.c_str());
206
376 lldebugs << "Setting mLastSender " << input["sender"].asString() << llendl; 207 lldebugs << "Setting mLastSender " << input["sender"].asString() << llendl;
377 gMessageSystem->mLastSender = LLHost(input["sender"].asString()); 208 gMessageSystem->mLastSender = LLHost(input["sender"].asString());
378 gMessageSystem->mPacketsIn += 1; 209 gMessageSystem->mPacketsIn += 1;
379 gMessageSystem->mLLSDMessageReader->setMessage(name, input["body"]); 210 gMessageSystem->mLLSDMessageReader->setMessage(namePtr, input["body"]);
380 gMessageSystem->mMessageReader = gMessageSystem->mLLSDMessageReader; 211 gMessageSystem->mMessageReader = gMessageSystem->mLLSDMessageReader;
381 212
382 if(gMessageSystem->callHandler(name.c_str(), false, gMessageSystem)) 213 if(gMessageSystem->callHandler(namePtr, false, gMessageSystem))
383 { 214 {
384 response->result(LLSD()); 215 response->result(LLSD());
385 } 216 }
@@ -401,6 +232,12 @@ LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder()
401 // even abstract base classes need a concrete destructor 232 // even abstract base classes need a concrete destructor
402} 233}
403 234
235static const char* nullToEmpty(const char* s)
236{
237 static char emptyString[] = "";
238 return s? s : emptyString;
239}
240
404void LLMessageSystem::init() 241void LLMessageSystem::init()
405{ 242{
406 // initialize member variables 243 // initialize member variables
@@ -440,7 +277,6 @@ void LLMessageSystem::init()
440 mIncomingCompressedSize = 0; 277 mIncomingCompressedSize = 0;
441 mCurrentRecvPacketID = 0; 278 mCurrentRecvPacketID = 0;
442 279
443 mMessageFileChecksum = 0;
444 mMessageFileVersionNumber = 0.f; 280 mMessageFileVersionNumber = 0.f;
445 281
446 mTimingCallback = NULL; 282 mTimingCallback = NULL;
@@ -454,9 +290,7 @@ void LLMessageSystem::init()
454LLMessageSystem::LLMessageSystem(const char *filename, U32 port, 290LLMessageSystem::LLMessageSystem(const char *filename, U32 port,
455 S32 version_major, 291 S32 version_major,
456 S32 version_minor, 292 S32 version_minor,
457 S32 version_patch) : 293 S32 version_patch)
458 mTemplateConfirmed(FALSE),
459 mTemplateMatches(FALSE)
460{ 294{
461 init(); 295 init();
462 296
@@ -529,6 +363,8 @@ LLMessageSystem::LLMessageSystem(const char *filename, U32 port,
529 mTrueReceiveSize = 0; 363 mTrueReceiveSize = 0;
530} 364}
531 365
366
367
532// Read file and build message templates 368// Read file and build message templates
533void LLMessageSystem::loadTemplateFile(const char* filename) 369void LLMessageSystem::loadTemplateFile(const char* filename)
534{ 370{
@@ -539,797 +375,23 @@ void LLMessageSystem::loadTemplateFile(const char* filename)
539 return; 375 return;
540 } 376 }
541 377
542 char token[MAX_MESSAGE_INTERNAL_NAME_SIZE]; /* Flawfinder: ignore */ 378 LLString template_body;
543 379 if(!LLString::read(template_body, filename))
544 // state variables
545 BOOL b_template_start = TRUE;
546 BOOL b_template_end = FALSE;
547 BOOL b_template = FALSE;
548 BOOL b_block_start = FALSE;
549 BOOL b_block_end = FALSE;
550 BOOL b_block = FALSE;
551 BOOL b_variable_start = FALSE;
552 BOOL b_variable_end = FALSE;
553 BOOL b_variable = FALSE;
554 //BOOL b_in_comment_block = FALSE; // not yet used
555
556 // working temp variables
557 LLMessageTemplate *templatep = NULL;
558 char template_name[MAX_MESSAGE_INTERNAL_NAME_SIZE]; /* Flawfinder: ignore */
559
560 LLMessageBlock *blockp = NULL;
561 char block_name[MAX_MESSAGE_INTERNAL_NAME_SIZE]; /* Flawfinder: ignore */
562
563 LLMessageVariable var;
564 char var_name[MAX_MESSAGE_INTERNAL_NAME_SIZE]; /* Flawfinder: ignore */
565 char formatString[MAX_MESSAGE_INTERNAL_NAME_SIZE]; /* Flawfinder: ignore */
566
567 FILE* messagefilep = NULL;
568 mMessageFileChecksum = 0;
569 mMessageFileVersionNumber = 0.f;
570 S32 checksum_offset = 0;
571 char* checkp = NULL;
572
573 // scanf needs 1 byte more than width, thus the MAX_... -1.
574 snprintf( /* Flawfinder: ignore */
575 formatString,
576 sizeof(formatString),
577 "%%%ds",
578 MAX_MESSAGE_INTERNAL_NAME_SIZE - 1);
579 messagefilep = LLFile::fopen(filename, "r"); /* Flawfinder: ignore */
580 if (messagefilep)
581 {
582// mName = gMessageStringTable.getString(filename);
583
584 fseek(messagefilep, 0L, SEEK_SET );
585 while(fscanf(messagefilep, formatString, token) != EOF) /* Flawfinder: ignore */
586 {
587 // skip comments
588 if (token[0] == '/')
589 {
590 // skip to end of line
591 while (token[0] != 10)
592 fscanf(messagefilep, "%c", token);
593 continue;
594 }
595
596 checkp = token;
597
598 while (*checkp)
599 {
600 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
601 checksum_offset = (checksum_offset + 8) % 32;
602 }
603
604 // what are we looking for
605 if (!strcmp(token, "{"))
606 {
607 // is that a legit option?
608 if (b_template_start)
609 {
610 // yup!
611 b_template_start = FALSE;
612
613 // remember that it could be only a signal message, so name is all that it contains
614 b_template_end = TRUE;
615
616 // start working on it!
617 b_template = TRUE;
618 }
619 else if (b_block_start)
620 {
621 // yup!
622 b_block_start = FALSE;
623 b_template_end = FALSE;
624
625 // start working on it!
626 b_block = TRUE;
627 }
628 else if (b_variable_start)
629 {
630 // yup!
631 b_variable_start = FALSE;
632 b_block_end = FALSE;
633
634 // start working on it!
635 b_variable = TRUE;
636 }
637 else
638 {
639 llerrs << "Detcted unexpected token '" << token
640 << "' while parsing template." << llendl;
641 mbError = TRUE;
642 fclose(messagefilep);
643 return;
644 }
645 }
646
647 if (!strcmp(token, "}"))
648 {
649 // is that a legit option?
650 if (b_template_end)
651 {
652 // yup!
653 b_template_end = FALSE;
654 b_template = FALSE;
655 b_block_start = FALSE;
656
657 // add data!
658 // we've gotten a complete variable! hooray!
659 // add it!
660 if (NULL == templatep)
661 {
662 llerrs << "Trying to addTemplate a NULL templatep during load." << llendl;
663 mbError = TRUE;
664 fclose(messagefilep);
665 return;
666 }
667 addTemplate(templatep);
668
669 //llinfos << "Read template: "templatep->mNametemp_str
670 // << llendl;
671
672 // look for next one!
673 b_template_start = TRUE;
674 }
675 else if (b_block_end)
676 {
677 // yup!
678 b_block_end = FALSE;
679 b_variable_start = FALSE;
680
681 // add data!
682 // we've gotten a complete variable! hooray!
683 // add it to template
684 if (NULL == templatep)
685 {
686 llerrs << "Trying to addBlock to NULL templatep during load." << llendl;
687 mbError = TRUE;
688 fclose(messagefilep);
689 return;
690 }
691 templatep->addBlock(blockp);
692
693 // start working on it!
694 b_template_end = TRUE;
695 b_block_start = TRUE;
696 }
697 else if (b_variable_end)
698 {
699 // yup!
700 b_variable_end = FALSE;
701
702 // add data!
703 // we've gotten a complete variable! hooray!
704 // add it to block
705 blockp->addVariable(var.getName(), var.getType(), var.getSize());
706
707 // start working on it!
708 b_variable_start = TRUE;
709 b_block_end = TRUE;
710 }
711 else
712 {
713 llerrs << "Detcted unexpected token '" << token
714 << "' while parsing template." << llendl;
715 mbError = TRUE;
716 fclose(messagefilep);
717 return;
718 }
719 }
720
721 // now, are we looking to start a template?
722 if (b_template)
723 {
724
725 b_template = FALSE;
726
727 // name first
728 if (fscanf(messagefilep, formatString, template_name) == EOF) /* Flawfinder: ignore */
729 {
730 // oops, file ended
731 llerrs << "Expected message template name, but file ended"
732 << llendl;
733 mbError = TRUE;
734 fclose(messagefilep);
735 return;
736 }
737
738 // debugging to help figure out busted templates
739 //llinfos << template_name << llendl;
740
741 // is name a legit C variable name
742 if (!b_variable_ok(template_name))
743 {
744 // nope!
745 llerrs << "Not legal message template name: "
746 << template_name << llendl;
747 mbError = TRUE;
748 fclose(messagefilep);
749 return;
750 }
751
752 checkp = template_name;
753 while (*checkp)
754 {
755 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
756 checksum_offset = (checksum_offset + 8) % 32;
757 }
758
759 // ok, now get Frequency ("High", "Medium", or "Low")
760 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
761 {
762 // oops, file ended
763 llerrs << "Expected message template frequency, found EOF."
764 << llendl;
765 mbError = TRUE;
766 fclose(messagefilep);
767 return;
768 }
769
770 checkp = token;
771 while (*checkp)
772 {
773 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
774 checksum_offset = (checksum_offset + 8) % 32;
775 }
776
777 // which one is it?
778 if (!strcmp(token, "High"))
779 {
780 if (++mNumberHighFreqMessages == 255)
781 {
782 // oops, too many High Frequency messages!!
783 llerrs << "Message " << template_name
784 << " exceeded 254 High frequency messages!"
785 << llendl;
786 mbError = TRUE;
787 fclose(messagefilep);
788 return;
789 }
790 // ok, we can create a template!
791 // message number is just mNumberHighFreqMessages
792 templatep = new LLMessageTemplate(template_name, mNumberHighFreqMessages, MFT_HIGH);
793 //lldebugs << "Template " << template_name << " # "
794 // << std::hex << mNumberHighFreqMessages
795 // << std::dec << " high"
796 // << llendl;
797 }
798 else if (!strcmp(token, "Medium"))
799 {
800 if (++mNumberMediumFreqMessages == 255)
801 {
802 // oops, too many Medium Frequency messages!!
803 llerrs << "Message " << template_name
804 << " exceeded 254 Medium frequency messages!"
805 << llendl;
806 mbError = TRUE;
807 fclose(messagefilep);
808 return;
809 }
810 // ok, we can create a template!
811 // message number is ((255 << 8) | mNumberMediumFreqMessages)
812 templatep = new LLMessageTemplate(template_name, (255 << 8) | mNumberMediumFreqMessages, MFT_MEDIUM);
813 //lldebugs << "Template " << template_name << " # "
814 // << std::hex << mNumberMediumFreqMessages
815 // << std::dec << " medium"
816 // << llendl;
817 }
818 else if (!strcmp(token, "Low"))
819 {
820 if (++mNumberLowFreqMessages == 65535)
821 {
822 // oops, too many High Frequency messages!!
823 llerrs << "Message " << template_name
824 << " exceeded 65534 Low frequency messages!"
825 << llendl;
826 mbError = TRUE;
827 fclose(messagefilep);
828 return;
829 }
830 // ok, we can create a template!
831 // message number is ((255 << 24) | (255 << 16) | mNumberLowFreqMessages)
832 templatep = new LLMessageTemplate(template_name, (255 << 24) | (255 << 16) | mNumberLowFreqMessages, MFT_LOW);
833 //lldebugs << "Template " << template_name << " # "
834 // << std::hex << mNumberLowFreqMessages
835 // << std::dec << " low"
836 // << llendl;
837 }
838 else if (!strcmp(token, "Fixed"))
839 {
840 U32 message_num = 0;
841 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
842 {
843 // oops, file ended
844 llerrs << "Expected message template number (fixed),"
845 << " found EOF." << llendl;
846 mbError = TRUE;
847 fclose(messagefilep);
848 return;
849 }
850
851 checkp = token;
852 while (*checkp)
853 {
854 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
855 checksum_offset = (checksum_offset + 8) % 32;
856 }
857
858 message_num = strtoul(token,NULL,0);
859
860 // ok, we can create a template!
861 // message number is ((255 << 24) | (255 << 16) | mNumberLowFreqMessages)
862 templatep = new LLMessageTemplate(template_name, message_num, MFT_LOW);
863 }
864 else
865 {
866 // oops, bad frequency line
867 llerrs << "Bad frequency! " << token
868 << " isn't High, Medium, or Low" << llendl
869 mbError = TRUE;
870 fclose(messagefilep);
871 return;
872 }
873
874 // Now get trust ("Trusted", "NotTrusted")
875 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
876 {
877 // File ended
878 llerrs << "Expected message template "
879 "trust, but file ended."
880 << llendl;
881 mbError = TRUE;
882 fclose(messagefilep);
883 return;
884 }
885 checkp = token;
886 while (*checkp)
887 {
888 mMessageFileChecksum += ((U32) *checkp++) << checksum_offset;
889 checksum_offset = (checksum_offset + 8) % 32;
890 }
891
892 if (strcmp(token, "Trusted") == 0)
893 {
894 if (NULL == templatep)
895 {
896 llerrs << "Trying to setTrust for NULL templatep during load." << llendl;
897 mbError = TRUE;
898 fclose(messagefilep);
899 return;
900 }
901 templatep->setTrust(MT_TRUST);
902 }
903 else if (strcmp(token, "NotTrusted") == 0)
904 {
905 if (NULL == templatep)
906 {
907 llerrs << "Trying to setTrust for NULL templatep during load." << llendl;
908 mbError = TRUE;
909 fclose(messagefilep);
910 return;
911 }
912 templatep->setTrust(MT_NOTRUST);
913 }
914 else
915 {
916 // bad trust token
917 llerrs << "bad trust: " << token
918 << " isn't Trusted or NotTrusted"
919 << llendl;
920 mbError = TRUE;
921 fclose(messagefilep);
922 return;
923 }
924
925 // get encoding
926 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
927 {
928 // File ended
929 llerrs << "Expected message encoding, but file ended."
930 << llendl;
931 mbError = TRUE;
932 fclose(messagefilep);
933 return;
934 }
935 checkp = token;
936 while(*checkp)
937 {
938 mMessageFileChecksum += ((U32) *checkp++) << checksum_offset;
939 checksum_offset = (checksum_offset + 8) % 32;
940 }
941
942 if(0 == strcmp(token, "Unencoded"))
943 {
944 if (NULL == templatep)
945 {
946 llerrs << "Trying to setEncoding for NULL templatep during load." << llendl;
947 mbError = TRUE;
948 fclose(messagefilep);
949 return;
950 }
951 templatep->setEncoding(ME_UNENCODED);
952 }
953 else if(0 == strcmp(token, "Zerocoded"))
954 {
955 if (NULL == templatep)
956 {
957 llerrs << "Trying to setEncoding for NULL templatep during load." << llendl;
958 mbError = TRUE;
959 fclose(messagefilep);
960 return;
961 }
962 templatep->setEncoding(ME_ZEROCODED);
963 }
964 else
965 {
966 // bad trust token
967 llerrs << "bad encoding: " << token
968 << " isn't Unencoded or Zerocoded" << llendl;
969 mbError = TRUE;
970 fclose(messagefilep);
971 return;
972 }
973
974 // ok, now we need to look for a block
975 b_block_start = TRUE;
976 continue;
977 }
978
979 // now, are we looking to start a template?
980 if (b_block)
981 {
982 b_block = FALSE;
983 // ok, need to pull header info
984
985 // name first
986 if (fscanf(messagefilep, formatString, block_name) == EOF) /* Flawfinder: ignore */
987 {
988 // oops, file ended
989 llerrs << "Expected block name, but file ended" << llendl;
990 mbError = TRUE;
991 fclose(messagefilep);
992 return;
993 }
994
995 checkp = block_name;
996 while (*checkp)
997 {
998 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
999 checksum_offset = (checksum_offset + 8) % 32;
1000 }
1001
1002 // is name a legit C variable name
1003 if (!b_variable_ok(block_name))
1004 {
1005 // nope!
1006 llerrs << block_name << "is not a legal block name"
1007 << llendl;
1008 mbError = TRUE;
1009 fclose(messagefilep);
1010 return;
1011 }
1012
1013 // now, block type ("Single", "Multiple", or "Variable")
1014 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
1015 {
1016 // oops, file ended
1017 llerrs << "Expected block type, but file ended." << llendl;
1018 mbError = TRUE;
1019 fclose(messagefilep);
1020 return;
1021 }
1022
1023 checkp = token;
1024 while (*checkp)
1025 {
1026 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
1027 checksum_offset = (checksum_offset + 8) % 32;
1028 }
1029
1030 // which one is it?
1031 if (!strcmp(token, "Single"))
1032 {
1033 // ok, we can create a block
1034 blockp = new LLMessageBlock(block_name, MBT_SINGLE);
1035 }
1036 else if (!strcmp(token, "Multiple"))
1037 {
1038 // need to get the number of repeats
1039 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
1040 {
1041 // oops, file ended
1042 llerrs << "Expected block multiple count,"
1043 " but file ended." << llendl;
1044 mbError = TRUE;
1045 fclose(messagefilep);
1046 return;
1047 }
1048
1049 checkp = token;
1050 while (*checkp)
1051 {
1052 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
1053 checksum_offset = (checksum_offset + 8) % 32;
1054 }
1055
1056 // is it a legal integer
1057 if (!b_positive_integer_ok(token))
1058 {
1059 // nope!
1060 llerrs << token << "is not a legal integer for"
1061 " block multiple count" << llendl;
1062 mbError = TRUE;
1063 fclose(messagefilep);
1064 return;
1065 }
1066 // ok, we can create a block
1067 blockp = new LLMessageBlock(block_name, MBT_MULTIPLE, atoi(token));
1068 }
1069 else if (!strcmp(token, "Variable"))
1070 {
1071 // ok, we can create a block
1072 blockp = new LLMessageBlock(block_name, MBT_VARIABLE);
1073 }
1074 else
1075 {
1076 // oops, bad block type
1077 llerrs << "Bad block type! " << token
1078 << " isn't Single, Multiple, or Variable" << llendl;
1079 mbError = TRUE;
1080 fclose(messagefilep);
1081 return;
1082 }
1083 // ok, now we need to look for a variable
1084 b_variable_start = TRUE;
1085 continue;
1086 }
1087
1088 // now, are we looking to start a template?
1089 if (b_variable)
1090 {
1091 b_variable = FALSE;
1092 // ok, need to pull header info
1093
1094 // name first
1095 if (fscanf(messagefilep, formatString, var_name) == EOF) /* Flawfinder: ignore */
1096 {
1097 // oops, file ended
1098 llerrs << "Expected variable name, but file ended."
1099 << llendl;
1100 mbError = TRUE;
1101 fclose(messagefilep);
1102 return;
1103 }
1104
1105 checkp = var_name;
1106 while (*checkp)
1107 {
1108 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
1109 checksum_offset = (checksum_offset + 8) % 32;
1110 }
1111
1112 // is name a legit C variable name
1113 if (!b_variable_ok(var_name))
1114 {
1115 // nope!
1116 llerrs << var_name << " is not a legal variable name"
1117 << llendl;
1118 mbError = TRUE;
1119 fclose(messagefilep);
1120 return;
1121 }
1122
1123 // now, variable type ("Fixed" or "Variable")
1124 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
1125 {
1126 // oops, file ended
1127 llerrs << "Expected variable type, but file ended"
1128 << llendl;
1129 mbError = TRUE;
1130 fclose(messagefilep);
1131 return;
1132 }
1133
1134 checkp = token;
1135 while (*checkp)
1136 {
1137 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
1138 checksum_offset = (checksum_offset + 8) % 32;
1139 }
1140
1141
1142 // which one is it?
1143 if (!strcmp(token, "U8"))
1144 {
1145 var = LLMessageVariable(var_name, MVT_U8, 1);
1146 }
1147 else if (!strcmp(token, "U16"))
1148 {
1149 var = LLMessageVariable(var_name, MVT_U16, 2);
1150 }
1151 else if (!strcmp(token, "U32"))
1152 {
1153 var = LLMessageVariable(var_name, MVT_U32, 4);
1154 }
1155 else if (!strcmp(token, "U64"))
1156 {
1157 var = LLMessageVariable(var_name, MVT_U64, 8);
1158 }
1159 else if (!strcmp(token, "S8"))
1160 {
1161 var = LLMessageVariable(var_name, MVT_S8, 1);
1162 }
1163 else if (!strcmp(token, "S16"))
1164 {
1165 var = LLMessageVariable(var_name, MVT_S16, 2);
1166 }
1167 else if (!strcmp(token, "S32"))
1168 {
1169 var = LLMessageVariable(var_name, MVT_S32, 4);
1170 }
1171 else if (!strcmp(token, "S64"))
1172 {
1173 var = LLMessageVariable(var_name, MVT_S64, 8);
1174 }
1175 else if (!strcmp(token, "F32"))
1176 {
1177 var = LLMessageVariable(var_name, MVT_F32, 4);
1178 }
1179 else if (!strcmp(token, "F64"))
1180 {
1181 var = LLMessageVariable(var_name, MVT_F64, 8);
1182 }
1183 else if (!strcmp(token, "LLVector3"))
1184 {
1185 var = LLMessageVariable(var_name, MVT_LLVector3, 12);
1186 }
1187 else if (!strcmp(token, "LLVector3d"))
1188 {
1189 var = LLMessageVariable(var_name, MVT_LLVector3d, 24);
1190 }
1191 else if (!strcmp(token, "LLVector4"))
1192 {
1193 var = LLMessageVariable(var_name, MVT_LLVector4, 16);
1194 }
1195 else if (!strcmp(token, "LLQuaternion"))
1196 {
1197 var = LLMessageVariable(var_name, MVT_LLQuaternion, 12);
1198 }
1199 else if (!strcmp(token, "LLUUID"))
1200 {
1201 var = LLMessageVariable(var_name, MVT_LLUUID, 16);
1202 }
1203 else if (!strcmp(token, "BOOL"))
1204 {
1205 var = LLMessageVariable(var_name, MVT_BOOL, 1);
1206 }
1207 else if (!strcmp(token, "IPADDR"))
1208 {
1209 var = LLMessageVariable(var_name, MVT_IP_ADDR, 4);
1210 }
1211 else if (!strcmp(token, "IPPORT"))
1212 {
1213 var = LLMessageVariable(var_name, MVT_IP_PORT, 2);
1214 }
1215 else if (!strcmp(token, "Fixed"))
1216 {
1217 // need to get the variable size
1218 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
1219 {
1220 // oops, file ended
1221 llerrs << "Expected variable size, but file ended"
1222 << llendl;
1223 mbError = TRUE;
1224 fclose(messagefilep);
1225 return;
1226 }
1227
1228 checkp = token;
1229 while (*checkp)
1230 {
1231 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
1232 checksum_offset = (checksum_offset + 8) % 32;
1233 }
1234
1235 // is it a legal integer
1236 if (!b_positive_integer_ok(token))
1237 {
1238 // nope!
1239 llerrs << token << " is not a legal integer for"
1240 " variable size" << llendl;
1241 mbError = TRUE;
1242 fclose(messagefilep);
1243 return;
1244 }
1245 // ok, we can create a block
1246 var = LLMessageVariable(var_name, MVT_FIXED, atoi(token));
1247 }
1248 else if (!strcmp(token, "Variable"))
1249 {
1250 // need to get the variable size
1251 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
1252 {
1253 // oops, file ended
1254 llerrs << "Expected variable size, but file ended"
1255 << llendl;
1256 mbError = TRUE;
1257 fclose(messagefilep);
1258 return;
1259 }
1260
1261 checkp = token;
1262 while (*checkp)
1263 {
1264 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
1265 checksum_offset = (checksum_offset + 8) % 32;
1266 }
1267
1268 // is it a legal integer
1269 if (!b_positive_integer_ok(token))
1270 {
1271 // nope!
1272 llerrs << token << "is not a legal integer"
1273 " for variable size" << llendl;
1274 mbError = TRUE;
1275 fclose(messagefilep);
1276 return;
1277 }
1278 // ok, we can create a block
1279 var = LLMessageVariable(var_name, MVT_VARIABLE, atoi(token));
1280 }
1281 else
1282 {
1283 // oops, bad variable type
1284 llerrs << "Bad variable type! " << token
1285 << " isn't Fixed or Variable" << llendl;
1286 mbError = TRUE;
1287 fclose(messagefilep);
1288 return;
1289 }
1290
1291 // we got us a variable!
1292 b_variable_end = TRUE;
1293 continue;
1294 }
1295
1296 // do we have a version number stuck in the file?
1297 if (!strcmp(token, "version"))
1298 {
1299 // version number
1300 if (fscanf(messagefilep, formatString, token) == EOF) /* Flawfinder: ignore */
1301 {
1302 // oops, file ended
1303 llerrs << "Expected version number, but file ended"
1304 << llendl;
1305 mbError = TRUE;
1306 fclose(messagefilep);
1307 return;
1308 }
1309
1310 checkp = token;
1311 while (*checkp)
1312 {
1313 mMessageFileChecksum += ((U32)*checkp++) << checksum_offset;
1314 checksum_offset = (checksum_offset + 8) % 32;
1315 }
1316
1317 mMessageFileVersionNumber = (F32)atof(token);
1318
1319// llinfos << "### Message template version " << mMessageFileVersionNumber << " ###" << llendl;
1320 continue;
1321 }
1322 }
1323
1324 llinfos << "Message template checksum = " << std::hex << mMessageFileChecksum << std::dec << llendl;
1325 }
1326 else
1327 { 380 {
1328 llwarns << "Failed to open template: " << filename << llendl; 381 llwarns << "Failed to open template: " << filename << llendl;
1329 mbError = TRUE; 382 mbError = TRUE;
1330 return; 383 return;
1331 } 384 }
1332 fclose(messagefilep); 385
386 LLTemplateTokenizer tokens(template_body);
387 LLTemplateParser parsed(tokens);
388 mMessageFileVersionNumber = parsed.getVersion();
389 for(LLTemplateParser::message_iterator iter = parsed.getMessagesBegin();
390 iter != parsed.getMessagesEnd();
391 iter++)
392 {
393 addTemplate(*iter);
394 }
1333} 395}
1334 396
1335 397
@@ -1393,6 +455,94 @@ BOOL LLMessageSystem::poll(F32 seconds)
1393 } 455 }
1394} 456}
1395 457
458bool LLMessageSystem::isTrustedSender(const LLHost& host) const
459{
460 LLCircuitData* cdp = mCircuitInfo.findCircuit(host);
461 if(NULL == cdp)
462 {
463 return false;
464 }
465 return cdp->getTrusted();
466}
467
468static LLMessageSystem::message_template_name_map_t::const_iterator
469findTemplate(const LLMessageSystem::message_template_name_map_t& templates,
470 std::string name)
471{
472 const char* namePrehash = gMessageStringTable.getString(name.c_str());
473 if(NULL == namePrehash) {return templates.end();}
474 return templates.find(namePrehash);
475}
476
477bool LLMessageSystem::isTrustedMessage(const std::string& name) const
478{
479 message_template_name_map_t::const_iterator iter =
480 findTemplate(mMessageTemplates, name);
481 if(iter == mMessageTemplates.end()) {return false;}
482 return iter->second->getTrust() == MT_TRUST;
483}
484
485bool LLMessageSystem::isUntrustedMessage(const std::string& name) const
486{
487 message_template_name_map_t::const_iterator iter =
488 findTemplate(mMessageTemplates, name);
489 if(iter == mMessageTemplates.end()) {return false;}
490 return iter->second->getTrust() == MT_NOTRUST;
491}
492
493LLCircuitData* LLMessageSystem::findCircuit(const LLHost& host,
494 bool resetPacketId)
495{
496 LLCircuitData* cdp = mCircuitInfo.findCircuit(host);
497 if (!cdp)
498 {
499 // This packet comes from a circuit we don't know about.
500
501 // Are we rejecting off-circuit packets?
502 if (mbProtected)
503 {
504 // cdp is already NULL, so we don't need to unset it.
505 }
506 else
507 {
508 // nope, open the new circuit
509 cdp = mCircuitInfo.addCircuitData(host, mCurrentRecvPacketID);
510
511 if(resetPacketId)
512 {
513 // I added this - I think it's correct - DJS
514 // reset packet in ID
515 cdp->setPacketInID(mCurrentRecvPacketID);
516 }
517 // And claim the packet is on the circuit we just added.
518 }
519 }
520 else
521 {
522 // this is an old circuit. . . is it still alive?
523 if (!cdp->isAlive())
524 {
525 // nope. don't accept if we're protected
526 if (mbProtected)
527 {
528 // don't accept packets from unexpected sources
529 cdp = NULL;
530 }
531 else
532 {
533 // wake up the circuit
534 cdp->setAlive(TRUE);
535
536 if(resetPacketId)
537 {
538 // reset packet in ID
539 cdp->setPacketInID(mCurrentRecvPacketID);
540 }
541 }
542 }
543 }
544 return cdp;
545}
1396 546
1397// Returns TRUE if a valid, on-circuit message has been received. 547// Returns TRUE if a valid, on-circuit message has been received.
1398BOOL LLMessageSystem::checkMessages( S64 frame_count ) 548BOOL LLMessageSystem::checkMessages( S64 frame_count )
@@ -1471,71 +621,12 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
1471 } 621 }
1472 622
1473 // process the message as normal 623 // process the message as normal
1474 624 mIncomingCompressedSize = zeroCodeExpand(&buffer, &receive_size);
1475 mIncomingCompressedSize = zeroCodeExpand(&buffer,&receive_size); 625 mCurrentRecvPacketID = ntohl(*((U32*)(&buffer[1])));
1476 mCurrentRecvPacketID = buffer[1] + ((buffer[0] & 0x0f ) * 256);
1477 if (sizeof(TPACKETID) == 4)
1478 {
1479 mCurrentRecvPacketID *= 256;
1480 mCurrentRecvPacketID += buffer[2];
1481 mCurrentRecvPacketID *= 256;
1482 mCurrentRecvPacketID += buffer[3];
1483 }
1484
1485 host = getSender(); 626 host = getSender();
1486 //llinfos << host << ":" << mCurrentRecvPacketID << llendl;
1487 627
1488 // For testing the weird case we're having in the office where the first few packets 628 const bool resetPacketId = true;
1489 // on a connection get dropped 629 cdp = findCircuit(host, resetPacketId);
1490 //if ((mCurrentRecvPacketID < 8) && !(buffer[0] & LL_RESENT_FLAG))
1491 //{
1492 // llinfos << "Evil! Dropping " << mCurrentRecvPacketID << " from " << host << " for fun!" << llendl;
1493 // continue;
1494 //}
1495
1496 cdp = mCircuitInfo.findCircuit(host);
1497 if (!cdp)
1498 {
1499 // This packet comes from a circuit we don't know about.
1500
1501 // Are we rejecting off-circuit packets?
1502 if (mbProtected)
1503 {
1504 // cdp is already NULL, so we don't need to unset it.
1505 }
1506 else
1507 {
1508 // nope, open the new circuit
1509 cdp = mCircuitInfo.addCircuitData(host, mCurrentRecvPacketID);
1510
1511 // I added this - I think it's correct - DJS
1512 // reset packet in ID
1513 cdp->setPacketInID(mCurrentRecvPacketID);
1514
1515 // And claim the packet is on the circuit we just added.
1516 }
1517 }
1518 else
1519 {
1520 // this is an old circuit. . . is it still alive?
1521 if (!cdp->isAlive())
1522 {
1523 // nope. don't accept if we're protected
1524 if (mbProtected)
1525 {
1526 // don't accept packets from unexpected sources
1527 cdp = NULL;
1528 }
1529 else
1530 {
1531 // wake up the circuit
1532 cdp->setAlive(TRUE);
1533
1534 // reset packet in ID
1535 cdp->setPacketInID(mCurrentRecvPacketID);
1536 }
1537 }
1538 }
1539 630
1540 // At this point, cdp is now a pointer to the circuit that 631 // At this point, cdp is now a pointer to the circuit that
1541 // this message came in on if it's valid, and NULL if the 632 // this message came in on if it's valid, and NULL if the
@@ -1664,6 +755,10 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
1664 755
1665 if (valid_packet) 756 if (valid_packet)
1666 { 757 {
758 // enable this for output of message names
759 //llinfos << "< \"" << mTemplateMessageReader->getMessageName()
760 //<< "\"" << llendl;
761
1667 /* Code for dumping the complete contents of a message. Keep for future use in optimizing messages. 762 /* Code for dumping the complete contents of a message. Keep for future use in optimizing messages.
1668 if( 1 ) 763 if( 1 )
1669 { 764 {
@@ -1768,9 +863,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )
1768 { 863 {
1769 if (mbProtected && (!cdp)) 864 if (mbProtected && (!cdp))
1770 { 865 {
1771 llwarns << "Packet " 866 llwarns << "Invalid Packet from invalid circuit " << host << llendl;
1772 << mTemplateMessageReader->getMessageName()
1773 << " from invalid circuit " << host << llendl;
1774 mOffCircuitPackets++; 867 mOffCircuitPackets++;
1775 } 868 }
1776 else 869 else
@@ -2051,15 +1144,34 @@ S32 LLMessageSystem::flushReliable(const LLHost &host)
2051 return send_bytes; 1144 return send_bytes;
2052} 1145}
2053 1146
2054 1147LLHTTPClient::ResponderPtr LLMessageSystem::createResponder(const std::string& name)
1148{
1149 if(mSendReliable)
1150 {
1151 return new LLFnPtrResponder(mReliablePacketParams.mCallback,
1152 mReliablePacketParams.mCallbackData,
1153 name);
1154 }
1155 else
1156 {
1157 llwarns << "LLMessageSystem::sendMessage: Sending unreliable "
1158 << mMessageBuilder->getMessageName() << " message via HTTP"
1159 << llendl;
1160 return new LLFnPtrResponder(NULL, NULL,
1161 mMessageBuilder->getMessageName());
1162 }
1163}
1164
2055// This can be called from signal handlers, 1165// This can be called from signal handlers,
2056// so should should not use llinfos. 1166// so should should not use llinfos.
2057S32 LLMessageSystem::sendMessage(const LLHost &host) 1167S32 LLMessageSystem::sendMessage(const LLHost &host)
2058{ 1168{
2059 if (! mMessageBuilder->isBuilt()) 1169 if (! mMessageBuilder->isBuilt())
2060 { 1170 {
2061 mSendSize = mMessageBuilder->buildMessage(mSendBuffer, 1171 mSendSize = mMessageBuilder->buildMessage(
2062 MAX_BUFFER_SIZE); 1172 mSendBuffer,
1173 MAX_BUFFER_SIZE,
1174 0);
2063 } 1175 }
2064 1176
2065 if (!(host.isOk())) // if port and ip are zero, don't bother trying to send the message 1177 if (!(host.isOk())) // if port and ip are zero, don't bother trying to send the message
@@ -2088,6 +1200,7 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
2088 else 1200 else
2089 { 1201 {
2090 // nope, open the new circuit 1202 // nope, open the new circuit
1203
2091 cdp = mCircuitInfo.addCircuitData(host, 0); 1204 cdp = mCircuitInfo.addCircuitData(host, 0);
2092 } 1205 }
2093 } 1206 }
@@ -2115,33 +1228,23 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)
2115 LLSD message = mLLSDMessageBuilder->getMessage(); 1228 LLSD message = mLLSDMessageBuilder->getMessage();
2116 1229
2117 const LLHTTPSender& sender = LLHTTPSender::getSender(host); 1230 const LLHTTPSender& sender = LLHTTPSender::getSender(host);
2118 LLHTTPClient::ResponderPtr responder = NULL;
2119 if(mSendReliable)
2120 {
2121 responder =
2122 new LLFnPtrResponder(mReliablePacketParams.mCallback,
2123 mReliablePacketParams.mCallbackData);
2124 }
2125 else
2126 {
2127 llwarns << "LLMessageSystem::sendMessage: Sending unreliable " << mMessageBuilder->getMessageName() << " message via HTTP" << llendl;
2128 responder = new LLFnPtrResponder(NULL, NULL);
2129 }
2130 sender.send(host, mLLSDMessageBuilder->getMessageName(), 1231 sender.send(host, mLLSDMessageBuilder->getMessageName(),
2131 message, responder); 1232 message, createResponder(mLLSDMessageBuilder->getMessageName()));
2132 1233
2133 mSendReliable = FALSE; 1234 mSendReliable = FALSE;
2134 mReliablePacketParams.clear(); 1235 mReliablePacketParams.clear();
2135 return 1; 1236 return 1;
2136 } 1237 }
2137 1238
2138 memset(mSendBuffer,0,LL_PACKET_ID_SIZE); // zero out the packet ID field 1239 // zero out the flags and packetid. Subtract 1 here so that we do
1240 // not overwrite the offset if it was set set in buildMessage().
1241 memset(mSendBuffer, 0, LL_PACKET_ID_SIZE - 1);
2139 1242
2140 // add the send id to the front of the message 1243 // add the send id to the front of the message
2141 cdp->nextPacketOutID(); 1244 cdp->nextPacketOutID();
2142 1245
2143 // Packet ID size is always 4 1246 // Packet ID size is always 4
2144 *((S32*)&mSendBuffer[0]) = htonl(cdp->getPacketOutID()); 1247 *((S32*)&mSendBuffer[PHL_PACKET_ID]) = htonl(cdp->getPacketOutID());
2145 1248
2146 // Compress the message, which will usually reduce its size. 1249 // Compress the message, which will usually reduce its size.
2147 U8 * buf_ptr = (U8 *)mSendBuffer; 1250 U8 * buf_ptr = (U8 *)mSendBuffer;
@@ -2284,7 +1387,7 @@ void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_re
2284 char buffer[MAX_STRING]; /* Flawfinder: ignore */ 1387 char buffer[MAX_STRING]; /* Flawfinder: ignore */
2285 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID); /* Flawfinder: ignore */ 1388 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID); /* Flawfinder: ignore */
2286 str << buffer 1389 str << buffer
2287 << mMessageReader->getMessageName() 1390 << nullToEmpty(mMessageReader->getMessageName())
2288 << (recv_reliable ? " reliable" : "") 1391 << (recv_reliable ? " reliable" : "")
2289 << " REJECTED"; 1392 << " REJECTED";
2290 llinfos << str.str() << llendl; 1393 llinfos << str.str() << llendl;
@@ -2307,6 +1410,27 @@ void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_re
2307 } 1410 }
2308} 1411}
2309 1412
1413S32 LLMessageSystem::sendMessage(const LLHost &host, const char* name,
1414 const LLSD& message)
1415{
1416 if (!(host.isOk()))
1417 {
1418 llwarns << "trying to send message to invalid host" << llendl;
1419 return 0;
1420 }
1421 newMessage(name);
1422 if (mMessageBuilder != mLLSDMessageBuilder)
1423 {
1424 llwarns << "trying to send llsd message when builder is not LLSD!"
1425 << llendl;
1426 return 0;
1427 }
1428
1429 const LLHTTPSender& sender = LLHTTPSender::getSender(host);
1430 sender.send(host, name, message, createResponder(name));
1431 return 1;
1432}
1433
2310void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host ) 1434void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )
2311{ 1435{
2312 // RequestTrustedCircuit is how we establish trust, so don't spam 1436 // RequestTrustedCircuit is how we establish trust, so don't spam
@@ -2314,9 +1438,9 @@ void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )
2314 if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit")) 1438 if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit"))
2315 { 1439 {
2316 llwarns << "Received trusted message on untrusted circuit. " 1440 llwarns << "Received trusted message on untrusted circuit. "
2317 << "Will reply with deny. " 1441 << "Will reply with deny. "
2318 << "Message: " << mMessageReader->getMessageName() 1442 << "Message: " << nullToEmpty(mMessageReader->getMessageName())
2319 << " Host: " << host << llendl; 1443 << " Host: " << host << llendl;
2320 } 1444 }
2321 1445
2322 if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM) 1446 if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM)
@@ -2366,7 +1490,7 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r
2366 char buffer[MAX_STRING]; /* Flawfinder: ignore */ 1490 char buffer[MAX_STRING]; /* Flawfinder: ignore */
2367 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID); /* Flawfinder: ignore */ 1491 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID); /* Flawfinder: ignore */
2368 str << buffer 1492 str << buffer
2369 << mMessageReader->getMessageName() 1493 << nullToEmpty(mMessageReader->getMessageName())
2370 << (recv_reliable ? " reliable" : "") 1494 << (recv_reliable ? " reliable" : "")
2371 << (recv_resent ? " resent" : "") 1495 << (recv_resent ? " resent" : "")
2372 << (recv_acks ? " acks" : ""); 1496 << (recv_acks ? " acks" : "");
@@ -2506,16 +1630,16 @@ void LLMessageSystem::disableCircuit(const LLHost &host)
2506 llinfos << "Host " << LLHost(old_ip, old_port) << " circuit " << code << " removed from lookup table" << llendl; 1630 llinfos << "Host " << LLHost(old_ip, old_port) << " circuit " << code << " removed from lookup table" << llendl;
2507 gMessageSystem->mIPPortToCircuitCode.erase(ip_port); 1631 gMessageSystem->mIPPortToCircuitCode.erase(ip_port);
2508 } 1632 }
1633 mCircuitInfo.removeCircuitData(host);
2509 } 1634 }
2510 else 1635 else
2511 { 1636 {
2512 // Sigh, since we can open circuits which don't have circuit 1637 // Sigh, since we can open circuits which don't have circuit
2513 // codes, it's possible for this to happen... 1638 // codes, it's possible for this to happen...
2514 1639
2515 //llwarns << "Couldn't find circuit code for " << host << llendl; 1640 llwarns << "Couldn't find circuit code for " << host << llendl;
2516 } 1641 }
2517 1642
2518 mCircuitInfo.removeCircuitData(host);
2519} 1643}
2520 1644
2521 1645
@@ -2937,6 +2061,30 @@ void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg,
2937 } 2061 }
2938} 2062}
2939 2063
2064// static
2065void LLMessageSystem::processError(LLMessageSystem* msg, void**)
2066{
2067 char buffer[MTUBYTES];
2068 S32 error_code = 0;
2069 msg->getS32("Data", "Code", error_code);
2070 std::string error_token;
2071 msg->getString("Data", "Token", MTUBYTES, buffer);
2072 error_token.assign(buffer);
2073 LLUUID error_id;
2074 msg->getUUID("Data", "ID", error_id);
2075 std::string error_system;
2076 msg->getString("Data", "System", MTUBYTES, buffer);
2077 error_system.assign(buffer);
2078 std::string error_message;
2079 msg->getString("Data", "Message", MTUBYTES, buffer);
2080 error_message.assign(buffer);
2081
2082 llwarns << "Message error from " << msg->getSender() << " - "
2083 << error_code << " " << error_token << " " << error_id << " \""
2084 << error_system << "\" \"" << error_message << "\"" << llendl;
2085}
2086
2087
2940static LLHTTPNode& messageRootNode() 2088static LLHTTPNode& messageRootNode()
2941{ 2089{
2942 static LLHTTPNode root_node; 2090 static LLHTTPNode root_node;
@@ -2964,10 +2112,13 @@ void LLMessageSystem::dispatch(
2964 const LLSD& message, 2112 const LLSD& message,
2965 LLHTTPNode::ResponsePtr responsep) 2113 LLHTTPNode::ResponsePtr responsep)
2966{ 2114{
2967 if (msg_name.empty()) 2115 if ((gMessageSystem->mMessageTemplates.find
2116 (gMessageStringTable.getString(msg_name.c_str())) ==
2117 gMessageSystem->mMessageTemplates.end()) &&
2118 !LLMessageConfig::isValidMessage(msg_name))
2968 { 2119 {
2969 llwarns << "LLMessageService::dispatch called with no message name" 2120 llwarns << "Ignoring unknown message " << msg_name << llendl;
2970 << llendl; 2121 responsep->notFound("Invalid message name");
2971 return; 2122 return;
2972 } 2123 }
2973 2124
@@ -2980,6 +2131,9 @@ void LLMessageSystem::dispatch(
2980 << path << llendl; 2131 << path << llendl;
2981 return; 2132 return;
2982 } 2133 }
2134 // enable this for output of message names
2135 //llinfos << "< \"" << msg_name << "\"" << llendl;
2136 //lldebugs << "data: " << LLSDXMLStreamer(message) << llendl;
2983 2137
2984 handler->post(responsep, context, message); 2138 handler->post(responsep, context, message);
2985} 2139}
@@ -3044,6 +2198,56 @@ void LLMessageSystem::setMessageBans(
3044 check_for_unrecognized_messages("untrusted", untrusted, mMessageTemplates); 2198 check_for_unrecognized_messages("untrusted", untrusted, mMessageTemplates);
3045} 2199}
3046 2200
2201S32 LLMessageSystem::sendError(
2202 const LLHost& host,
2203 const LLUUID& agent_id,
2204 S32 code,
2205 const std::string& token,
2206 const LLUUID& id,
2207 const std::string& system,
2208 const std::string& message,
2209 const LLSD& data)
2210{
2211 newMessage("Error");
2212 nextBlockFast(_PREHASH_AgentData);
2213 addUUIDFast(_PREHASH_AgentID, agent_id);
2214 nextBlockFast(_PREHASH_Data);
2215 addS32("Code", code);
2216 addString("Token", token);
2217 addUUID("ID", id);
2218 addString("System", system);
2219 std::string temp;
2220 temp = message;
2221 if(temp.size() > (size_t)MTUBYTES) temp.resize((size_t)MTUBYTES);
2222 addString("Message", message);
2223 LLPointer<LLSDBinaryFormatter> formatter = new LLSDBinaryFormatter;
2224 std::ostringstream ostr;
2225 formatter->format(data, ostr);
2226 temp = ostr.str();
2227 bool pack_data = true;
2228 static const std::string ERROR_MESSAGE_NAME("Error");
2229 if (LLMessageConfig::getMessageFlavor(ERROR_MESSAGE_NAME) ==
2230 LLMessageConfig::TEMPLATE_FLAVOR)
2231 {
2232 S32 msg_size = temp.size() + mMessageBuilder->getMessageSize();
2233 if(msg_size >= ETHERNET_MTU_BYTES)
2234 {
2235 pack_data = false;
2236 }
2237 }
2238 if(pack_data)
2239 {
2240 addBinaryData("Data", (void*)temp.c_str(), temp.size());
2241 }
2242 else
2243 {
2244 llwarns << "Data and message were too large -- data removed."
2245 << llendl;
2246 addBinaryData("Data", NULL, 0);
2247 }
2248 return sendReliable(host);
2249}
2250
3047void process_packet_ack(LLMessageSystem *msgsystem, void** /*user_data*/) 2251void process_packet_ack(LLMessageSystem *msgsystem, void** /*user_data*/)
3048{ 2252{
3049 TPACKETID packet_id; 2253 TPACKETID packet_id;
@@ -3069,37 +2273,8 @@ void process_packet_ack(LLMessageSystem *msgsystem, void** /*user_data*/)
3069 } 2273 }
3070} 2274}
3071 2275
3072void send_template_reply(LLMessageSystem* msg, const LLUUID& token)
3073{
3074 msg->newMessageFast(_PREHASH_TemplateChecksumReply);
3075 msg->nextBlockFast(_PREHASH_DataBlock);
3076 msg->addU32Fast(_PREHASH_Checksum, msg->mMessageFileChecksum);
3077 msg->addU8Fast(_PREHASH_MajorVersion, U8(msg->mSystemVersionMajor) );
3078 msg->addU8Fast(_PREHASH_MinorVersion, U8(msg->mSystemVersionMinor) );
3079 msg->addU8Fast(_PREHASH_PatchVersion, U8(msg->mSystemVersionPatch) );
3080 msg->addU8Fast(_PREHASH_ServerVersion, U8(msg->mSystemVersionServer) );
3081 msg->addU32Fast(_PREHASH_Flags, msg->mVersionFlags);
3082 msg->nextBlockFast(_PREHASH_TokenBlock);
3083 msg->addUUIDFast(_PREHASH_Token, token);
3084 msg->sendMessage(msg->getSender());
3085}
3086
3087void process_template_checksum_request(LLMessageSystem* msg, void**)
3088{
3089 llinfos << "Message template checksum request received from "
3090 << msg->getSender() << llendl;
3091 send_template_reply(msg, LLUUID::null);
3092}
3093
3094void process_secured_template_checksum_request(LLMessageSystem* msg, void**)
3095{
3096 llinfos << "Secured message template checksum request received from "
3097 << msg->getSender() << llendl;
3098 LLUUID token;
3099 msg->getUUIDFast(_PREHASH_TokenBlock, _PREHASH_Token, token);
3100 send_template_reply(msg, token);
3101}
3102 2276
2277/*
3103void process_log_messages(LLMessageSystem* msg, void**) 2278void process_log_messages(LLMessageSystem* msg, void**)
3104{ 2279{
3105 U8 log_message; 2280 U8 log_message;
@@ -3116,7 +2291,7 @@ void process_log_messages(LLMessageSystem* msg, void**)
3116 llinfos << "Stopping logging via message" << llendl; 2291 llinfos << "Stopping logging via message" << llendl;
3117 msg->stopLogging(); 2292 msg->stopLogging();
3118 } 2293 }
3119} 2294}*/
3120 2295
3121// Make circuit trusted if the MD5 Digest matches, otherwise 2296// Make circuit trusted if the MD5 Digest matches, otherwise
3122// notify remote end that they are not trusted. 2297// notify remote end that they are not trusted.
@@ -3349,15 +2524,14 @@ BOOL start_messaging_system(
3349 //gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode, ack_add_circuit_code, NULL); 2524 //gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode, ack_add_circuit_code, NULL);
3350 gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder); 2525 gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder);
3351 gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck, process_packet_ack, NULL); 2526 gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck, process_packet_ack, NULL);
3352 gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumRequest, process_template_checksum_request, NULL); 2527 //gMessageSystem->setHandlerFuncFast(_PREHASH_LogMessages, process_log_messages, NULL);
3353 gMessageSystem->setHandlerFuncFast(_PREHASH_SecuredTemplateChecksumRequest, process_secured_template_checksum_request, NULL);
3354 gMessageSystem->setHandlerFuncFast(_PREHASH_LogMessages, process_log_messages, NULL);
3355 gMessageSystem->setHandlerFuncFast(_PREHASH_CreateTrustedCircuit, 2528 gMessageSystem->setHandlerFuncFast(_PREHASH_CreateTrustedCircuit,
3356 process_create_trusted_circuit, 2529 process_create_trusted_circuit,
3357 NULL); 2530 NULL);
3358 gMessageSystem->setHandlerFuncFast(_PREHASH_DenyTrustedCircuit, 2531 gMessageSystem->setHandlerFuncFast(_PREHASH_DenyTrustedCircuit,
3359 process_deny_trusted_circuit, 2532 process_deny_trusted_circuit,
3360 NULL); 2533 NULL);
2534 gMessageSystem->setHandlerFunc("Error", LLMessageSystem::processError);
3361 2535
3362 // We can hand this to the null_message_callback since it is a 2536 // We can hand this to the null_message_callback since it is a
3363 // trusted message, so it will automatically be denied if it isn't 2537 // trusted message, so it will automatically be denied if it isn't
@@ -3471,11 +2645,11 @@ void LLMessageSystem::summarizeLogs(std::ostream& str)
3471 snprintf(buffer, MAX_STRING, "%35s%10s%10s%10s%10s", "Message", "Count", "Time", "Max", "Avg"); /* Flawfinder: ignore */ 2645 snprintf(buffer, MAX_STRING, "%35s%10s%10s%10s%10s", "Message", "Count", "Time", "Max", "Avg"); /* Flawfinder: ignore */
3472 str << buffer << std:: endl; 2646 str << buffer << std:: endl;
3473 F32 avg; 2647 F32 avg;
3474 for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), 2648 for (message_template_name_map_t::const_iterator iter = mMessageTemplates.begin(),
3475 end = mMessageTemplates.end(); 2649 end = mMessageTemplates.end();
3476 iter != end; iter++) 2650 iter != end; iter++)
3477 { 2651 {
3478 LLMessageTemplate* mt = iter->second; 2652 const LLMessageTemplate* mt = iter->second;
3479 if(mt->mTotalDecoded > 0) 2653 if(mt->mTotalDecoded > 0)
3480 { 2654 {
3481 avg = mt->mTotalDecodeTime / (F32)mt->mTotalDecoded; 2655 avg = mt->mTotalDecodeTime / (F32)mt->mTotalDecoded;
@@ -3549,11 +2723,11 @@ void LLMessageSystem::dumpReceiveCounts()
3549 if(mNumMessageCounts > 0) 2723 if(mNumMessageCounts > 0)
3550 { 2724 {
3551 llinfos << "Dump: " << mNumMessageCounts << " messages processed in " << mReceiveTime << " seconds" << llendl; 2725 llinfos << "Dump: " << mNumMessageCounts << " messages processed in " << mReceiveTime << " seconds" << llendl;
3552 for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(), 2726 for (message_template_name_map_t::const_iterator iter = mMessageTemplates.begin(),
3553 end = mMessageTemplates.end(); 2727 end = mMessageTemplates.end();
3554 iter != end; iter++) 2728 iter != end; iter++)
3555 { 2729 {
3556 LLMessageTemplate* mt = iter->second; 2730 const LLMessageTemplate* mt = iter->second;
3557 if (mt->mReceiveCount > 0) 2731 if (mt->mReceiveCount > 0)
3558 { 2732 {
3559 llinfos << "Num: " << std::setw(3) << mt->mReceiveCount << " Bytes: " << std::setw(6) << mt->mReceiveBytes 2733 llinfos << "Num: " << std::setw(3) << mt->mReceiveCount << " Bytes: " << std::setw(6) << mt->mReceiveBytes
@@ -3601,8 +2775,10 @@ S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
3601 2775
3602 if (! mMessageBuilder->isBuilt()) 2776 if (! mMessageBuilder->isBuilt())
3603 { 2777 {
3604 mSendSize = mMessageBuilder->buildMessage(mSendBuffer, 2778 mSendSize = mMessageBuilder->buildMessage(
3605 MAX_BUFFER_SIZE); 2779 mSendBuffer,
2780 MAX_BUFFER_SIZE,
2781 0);
3606 } 2782 }
3607 // TODO: babbage: remove this horror 2783 // TODO: babbage: remove this horror
3608 mMessageBuilder->setBuilt(FALSE); 2784 mMessageBuilder->setBuilt(FALSE);
@@ -3616,7 +2792,7 @@ S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
3616 2792
3617// skip the packet id field 2793// skip the packet id field
3618 2794
3619 for (U32 i=0;i<LL_PACKET_ID_SIZE;i++) 2795 for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii)
3620 { 2796 {
3621 count--; 2797 count--;
3622 inptr++; 2798 inptr++;
@@ -3667,19 +2843,20 @@ S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
3667 2843
3668 2844
3669 2845
3670S32 LLMessageSystem::zeroCodeExpand(U8 **data, S32 *data_size) 2846S32 LLMessageSystem::zeroCodeExpand(U8** data, S32* data_size)
3671{ 2847{
3672 2848 if ((*data_size ) < LL_MINIMUM_VALID_PACKET_SIZE)
3673 if ((*data_size ) < LL_PACKET_ID_SIZE)
3674 { 2849 {
3675 llwarns << "zeroCodeExpand() called with data_size of " << *data_size << llendl; 2850 llwarns << "zeroCodeExpand() called with data_size of " << *data_size
2851 << llendl;
3676 } 2852 }
3677 2853
3678 mTotalBytesIn += *data_size; 2854 mTotalBytesIn += *data_size;
3679 2855
3680 if (!(*data[0] & LL_ZERO_CODE_FLAG)) // if we're not zero-coded, just go 'way 2856 // if we're not zero-coded, simply return.
2857 if (!(*data[0] & LL_ZERO_CODE_FLAG))
3681 { 2858 {
3682 return(0); 2859 return 0;
3683 } 2860 }
3684 2861
3685 S32 in_size = *data_size; 2862 S32 in_size = *data_size;
@@ -3695,7 +2872,7 @@ S32 LLMessageSystem::zeroCodeExpand(U8 **data, S32 *data_size)
3695 2872
3696// skip the packet id field 2873// skip the packet id field
3697 2874
3698 for (U32 i=0;i<LL_PACKET_ID_SIZE;i++) 2875 for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii)
3699 { 2876 {
3700 count--; 2877 count--;
3701 *outptr++ = *inptr++; 2878 *outptr++ = *inptr++;
@@ -3789,14 +2966,16 @@ bool LLMessageSystem::callHandler(const char *name,
3789 bool trustedSource, LLMessageSystem* msg) 2966 bool trustedSource, LLMessageSystem* msg)
3790{ 2967{
3791 name = gMessageStringTable.getString(name); 2968 name = gMessageStringTable.getString(name);
3792 LLMessageTemplate* msg_template = mMessageTemplates[(char*)name]; 2969 message_template_name_map_t::const_iterator iter;
3793 if (!msg_template) 2970 iter = mMessageTemplates.find(name);
2971 if(iter == mMessageTemplates.end())
3794 { 2972 {
3795 llwarns << "LLMessageSystem::callHandler: unknown message " 2973 llwarns << "LLMessageSystem::callHandler: unknown message "
3796 << name << llendl; 2974 << name << llendl;
3797 return false; 2975 return false;
3798 } 2976 }
3799 2977
2978 const LLMessageTemplate* msg_template = iter->second;
3800 if (msg_template->isBanned(trustedSource)) 2979 if (msg_template->isBanned(trustedSource))
3801 { 2980 {
3802 llwarns << "LLMessageSystem::callHandler: banned message " 2981 llwarns << "LLMessageSystem::callHandler: banned message "
@@ -3852,14 +3031,13 @@ BOOL LLMessageSystem::isCircuitCodeKnown(U32 code) const
3852 3031
3853BOOL LLMessageSystem::isMessageFast(const char *msg) 3032BOOL LLMessageSystem::isMessageFast(const char *msg)
3854{ 3033{
3855 return(msg == mMessageReader->getMessageName()); 3034 return msg == mMessageReader->getMessageName();
3856} 3035}
3857 3036
3858 3037
3859char* LLMessageSystem::getMessageName() 3038char* LLMessageSystem::getMessageName()
3860{ 3039{
3861 const char* name = mMessageReader->getMessageName(); 3040 return const_cast<char*>(mMessageReader->getMessageName());
3862 return name[0] == '\0'? NULL : const_cast<char*>(name);
3863} 3041}
3864 3042
3865const LLUUID& LLMessageSystem::getSenderID() const 3043const LLUUID& LLMessageSystem::getSenderID() const
@@ -4188,120 +3366,6 @@ void LLMessageSystem::dumpPacketToLog()
4188 } 3366 }
4189} 3367}
4190 3368
4191//static
4192BOOL LLMessageSystem::isTemplateConfirmed()
4193{
4194 return gMessageSystem->mTemplateConfirmed;
4195}
4196
4197//static
4198BOOL LLMessageSystem::doesTemplateMatch()
4199{
4200 if (!isTemplateConfirmed())
4201 {
4202 return FALSE;
4203 }
4204 return gMessageSystem->mTemplateMatches;
4205}
4206
4207//static
4208void LLMessageSystem::sendMessageTemplateChecksum(const LLHost &currentHost)
4209{
4210 gMessageSystem->mTemplateConfirmed = FALSE;
4211 gMessageSystem->mTemplateMatches = FALSE;
4212 gMessageSystem->newMessageFast(_PREHASH_TemplateChecksumRequest);
4213 // Don't use ping-based retry
4214 gMessageSystem->sendReliable(currentHost, 40, FALSE, 3, NULL, NULL);
4215}
4216
4217//static
4218void LLMessageSystem::processMessageTemplateChecksumReply(LLMessageSystem *msg,
4219 void** user_data)
4220{
4221 U32 remote_template_checksum = 0;
4222 msg->getU32Fast(_PREHASH_DataBlock, _PREHASH_Checksum, remote_template_checksum);
4223 msg->mTemplateConfirmed = TRUE;
4224 if ((remote_template_checksum) != msg->mMessageFileChecksum)
4225 {
4226 llwarns << "out of sync message template!" << llendl;
4227
4228 msg->mTemplateMatches = FALSE;
4229 msg->newMessageFast(_PREHASH_CloseCircuit);
4230 msg->sendMessage(msg->getSender());
4231 return;
4232 }
4233
4234 msg->mTemplateMatches = TRUE;
4235 llinfos << "According to " << msg->getSender()
4236 << " the message template is current!"
4237 << llendl;
4238}
4239
4240//static
4241void LLMessageSystem::sendSecureMessageTemplateChecksum(const LLHost& host)
4242{
4243 // generate an token for use during template checksum requests to
4244 // prevent DOS attacks from injected bad template checksum replies.
4245 LLUUID *template_tokenp = new LLUUID;
4246 template_tokenp->generate();
4247 lldebugs << "random token: " << *template_tokenp << llendl;
4248
4249 // register the handler for the reply while saving off template_token
4250 gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumReply,
4251 LLMessageSystem::processSecureTemplateChecksumReply,
4252 (void**)template_tokenp);
4253
4254 // send checksum request
4255 gMessageSystem->mTemplateConfirmed = FALSE;
4256 gMessageSystem->newMessageFast(_PREHASH_SecuredTemplateChecksumRequest);
4257 gMessageSystem->nextBlockFast(_PREHASH_TokenBlock);
4258 gMessageSystem->addUUIDFast(_PREHASH_Token, *template_tokenp);
4259 gMessageSystem->sendReliable(host);
4260}
4261
4262//static
4263void LLMessageSystem::processSecureTemplateChecksumReply(LLMessageSystem *msg,
4264 void** user_data)
4265{
4266 // copy the token out into the stack and delete allocated memory
4267 LLUUID template_token = *((LLUUID*)user_data);
4268 delete user_data;
4269
4270 LLUUID received_token;
4271 msg->getUUID("TokenBlock", "Token", received_token);
4272
4273 if(received_token != template_token)
4274 {
4275 llwarns << "Incorrect token in template checksum reply: "
4276 << received_token << llendl;
4277 //return do_normal_idle;
4278 return;
4279 }
4280
4281 U32 remote_template_checksum = 0;
4282 U8 major_version = 0;
4283 U8 minor_version = 0;
4284 U8 patch_version = 0;
4285 U8 server_version = 0;
4286 U32 flags = 0x0;
4287 msg->getU32("DataBlock", "Checksum", remote_template_checksum);
4288 msg->getU8 ("DataBlock", "MajorVersion", major_version);
4289 msg->getU8 ("DataBlock", "MinorVersion", minor_version);
4290 msg->getU8 ("DataBlock", "PatchVersion", patch_version);
4291 msg->getU8 ("DataBlock", "ServerVersion", server_version);
4292 msg->getU32("DataBlock", "Flags", flags);
4293
4294 msg->mTemplateConfirmed = TRUE;
4295 if (remote_template_checksum != gMessageSystem->mMessageFileChecksum)
4296 {
4297 llinfos << "Message template out of sync" << llendl;
4298 msg->mTemplateMatches = FALSE;
4299 }
4300 else
4301 {
4302 msg->mTemplateMatches = TRUE;
4303 }
4304}
4305 3369
4306//static 3370//static
4307U64 LLMessageSystem::getMessageTimeUsecs(const BOOL update) 3371U64 LLMessageSystem::getMessageTimeUsecs(const BOOL update)
@@ -4352,14 +3416,32 @@ typedef std::map<const char*, LLMessageBuilder*> BuilderMap;
4352 3416
4353void LLMessageSystem::newMessageFast(const char *name) 3417void LLMessageSystem::newMessageFast(const char *name)
4354{ 3418{
4355 if(LLMessageConfig::isMessageBuiltTemplate(name)) 3419 LLMessageConfig::Flavor message_flavor =
3420 LLMessageConfig::getMessageFlavor(name);
3421 LLMessageConfig::Flavor server_flavor =
3422 LLMessageConfig::getServerDefaultFlavor();
3423
3424 if(message_flavor == LLMessageConfig::TEMPLATE_FLAVOR)
4356 { 3425 {
4357 mMessageBuilder = mTemplateMessageBuilder; 3426 mMessageBuilder = mTemplateMessageBuilder;
4358 } 3427 }
4359 else 3428 else if (message_flavor == LLMessageConfig::LLSD_FLAVOR)
4360 { 3429 {
4361 mMessageBuilder = mLLSDMessageBuilder; 3430 mMessageBuilder = mLLSDMessageBuilder;
4362 } 3431 }
3432 // NO_FLAVOR
3433 else
3434 {
3435 if (server_flavor == LLMessageConfig::LLSD_FLAVOR)
3436 {
3437 mMessageBuilder = mLLSDMessageBuilder;
3438 }
3439 // TEMPLATE_FLAVOR or NO_FLAVOR
3440 else
3441 {
3442 mMessageBuilder = mTemplateMessageBuilder;
3443 }
3444 }
4363 mSendReliable = FALSE; 3445 mSendReliable = FALSE;
4364 mMessageBuilder->newMessage(name); 3446 mMessageBuilder->newMessage(name);
4365} 3447}
@@ -4822,6 +3904,10 @@ void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u,
4822void LLMessageSystem::getStringFast(const char *block, const char *var, 3904void LLMessageSystem::getStringFast(const char *block, const char *var,
4823 S32 buffer_size, char *s, S32 blocknum) 3905 S32 buffer_size, char *s, S32 blocknum)
4824{ 3906{
3907 if(buffer_size <= 0)
3908 {
3909 llwarns << "buffer_size <= 0" << llendl;
3910 }
4825 mMessageReader->getString(block, var, buffer_size, s, blocknum); 3911 mMessageReader->getString(block, var, buffer_size, s, blocknum);
4826} 3912}
4827 3913