message.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "message.h"
00035 
00036 // system library includes
00037 #if !LL_WINDOWS
00038 // following header files required for inet_addr()
00039 #include <sys/types.h>
00040 #include <sys/socket.h>
00041 #include <netinet/in.h>
00042 #include <arpa/inet.h>
00043 #endif
00044 #include <iomanip>
00045 #include <iterator>
00046 #include <sstream>
00047 
00048 #include "llapr.h"
00049 #include "apr-1/apr_portable.h"
00050 #include "apr-1/apr_network_io.h"
00051 #include "apr-1/apr_poll.h"
00052 
00053 // linden library headers
00054 #include "indra_constants.h"
00055 #include "lldarray.h"
00056 #include "lldir.h"
00057 #include "llerror.h"
00058 #include "llerrorlegacy.h"
00059 #include "llfasttimer.h"
00060 #include "llhttpclient.h"
00061 #include "llhttpsender.h"
00062 #include "llmd5.h"
00063 #include "llmessagebuilder.h"
00064 #include "llmessageconfig.h"
00065 #include "llpumpio.h"
00066 #include "lltemplatemessagebuilder.h"
00067 #include "lltemplatemessagereader.h"
00068 #include "llmessagetemplate.h"
00069 #include "llmessagetemplateparser.h"
00070 #include "llsd.h"
00071 #include "llsdmessagebuilder.h"
00072 #include "llsdmessagereader.h"
00073 #include "llsdserialize.h"
00074 #include "llstring.h"
00075 #include "lltransfermanager.h"
00076 #include "lluuid.h"
00077 #include "llxfermanager.h"
00078 #include "timing.h"
00079 #include "llquaternion.h"
00080 #include "u64.h"
00081 #include "v3dmath.h"
00082 #include "v3math.h"
00083 #include "v4math.h"
00084 #include "lltransfertargetvfile.h"
00085 
00086 // Constants
00087 //const char* MESSAGE_LOG_FILENAME = "message.log";
00088 static const F32 CIRCUIT_DUMP_TIMEOUT = 30.f;
00089 static const S32 TRUST_TIME_WINDOW = 3;
00090 
00091 // *NOTE: This needs to be moved into a seperate file so that it never gets
00092 // included in the viewer.  30 Sep 2002 mark
00093 // *NOTE: I don't think it's important that the messgage system tracks
00094 // this since it must get set externally. 2004.08.25 Phoenix.
00095 static std::string g_shared_secret;
00096 std::string get_shared_secret();
00097 
00098 class LLMessagePollInfo
00099 {
00100 public:
00101         apr_socket_t *mAPRSocketp;
00102         apr_pollfd_t mPollFD;
00103 };
00104 
00105 namespace
00106 {
00107         class LLFnPtrResponder : public LLHTTPClient::Responder
00108         {
00109                 LOG_CLASS(LLFnPtrResponder);
00110         public:
00111                 LLFnPtrResponder(void (*callback)(void **,S32), void **callbackData, const std::string& name) :
00112                         mCallback(callback),
00113                         mCallbackData(callbackData),
00114                         mMessageName(name)
00115                 {
00116                 }
00117 
00118                 virtual void error(U32 status, const std::string& reason)
00119                 {
00120                         // don't spam when agent communication disconnected already
00121                         if (status != 410)
00122                         {
00123                                 LL_WARNS("Messaging") << "error status " << status
00124                                                 << " for message " << mMessageName
00125                                                 << " reason " << reason << llendl;
00126                         }
00127                         // TODO: Map status in to useful error code.
00128                         if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT);
00129                 }
00130                 
00131                 virtual void result(const LLSD& content)
00132                 {
00133                         if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_NOERR);
00134                 }
00135 
00136         private:
00137 
00138                 void (*mCallback)(void **,S32);    
00139                 void **mCallbackData;
00140                 std::string mMessageName;
00141         };
00142 }
00143 
00144 
00145 class LLTrustedMessageService : public LLHTTPNode
00146 {
00147         virtual bool validate(const std::string& name, LLSD& context) const
00148                 { return true; }
00149 
00150         virtual void post(LLHTTPNode::ResponsePtr response,
00151                                           const LLSD& context,
00152                                           const LLSD& input) const;
00153 };
00154 
00155 //virtual
00156 void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response,
00157                                                                    const LLSD& context,
00158                                                                    const LLSD& input) const
00159 {
00160         std::string name = context["request"]["wildcard"]["message-name"];
00161         std::string senderIP = context["request"]["remote-host"];
00162         std::string senderPort = context["request"]["headers"]
00163                 ["x-secondlife-udp-listen-port"];
00164 
00165         LLSD message_data;
00166         std::string sender = senderIP + ":" + senderPort;
00167         message_data["sender"] = sender;
00168         message_data["body"] = input;
00169         
00170         // untrusted senders should not have access to the trusted message
00171         // service, but this can happen in development, so check and warn
00172         LLMessageConfig::SenderTrust trust =
00173                 LLMessageConfig::getSenderTrustedness(name);
00174         if ((trust == LLMessageConfig::TRUSTED ||
00175                  (trust == LLMessageConfig::NOT_SET &&
00176                   gMessageSystem->isTrustedMessage(name)))
00177                  && !gMessageSystem->isTrustedSender(LLHost(sender)))
00178         {
00179                 LL_WARNS("Messaging") << "trusted message POST to /trusted-message/" 
00180                                 << name << " from unknown or untrusted sender "
00181                                 << sender << llendl;
00182                 response->status(403, "Unknown or untrusted sender");
00183         }
00184         else
00185         {
00186                 LLMessageSystem::dispatch(name, message_data, response);
00187         }
00188 }
00189 
00190 class LLMessageHandlerBridge : public LLHTTPNode
00191 {
00192         virtual bool validate(const std::string& name, LLSD& context) const
00193                 { return true; }
00194 
00195         virtual void post(LLHTTPNode::ResponsePtr response, const LLSD& context, 
00196                                           const LLSD& input) const;
00197 };
00198 
00199 //virtual 
00200 void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response, 
00201                                                         const LLSD& context, const LLSD& input) const
00202 {
00203         std::string name = context["request"]["wildcard"]["message-name"];
00204         char* namePtr = LLMessageStringTable::getInstance()->getString(name.c_str());
00205         
00206         lldebugs << "Setting mLastSender " << input["sender"].asString() << llendl;
00207         gMessageSystem->mLastSender = LLHost(input["sender"].asString());
00208         gMessageSystem->mPacketsIn += 1;
00209         gMessageSystem->mLLSDMessageReader->setMessage(namePtr, input["body"]);
00210         gMessageSystem->mMessageReader = gMessageSystem->mLLSDMessageReader;
00211         
00212         if(gMessageSystem->callHandler(namePtr, false, gMessageSystem))
00213         {
00214                 response->result(LLSD());
00215         }
00216         else
00217         {
00218                 response->notFound();
00219         }
00220 }
00221 
00222 LLHTTPRegistration<LLMessageHandlerBridge>
00223         gHTTPRegistrationMessageWildcard("/message/<message-name>");
00224 
00225 LLHTTPRegistration<LLTrustedMessageService>
00226         gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>");
00227 
00228 //virtual
00229 LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder()
00230 {
00231         // even abstract base classes need a concrete destructor
00232 }
00233 
00234 static const char* nullToEmpty(const char* s)
00235 {
00236         static char emptyString[] = "";
00237         return s? s : emptyString;
00238 }
00239 
00240 void LLMessageSystem::init()
00241 {
00242         // initialize member variables
00243         mVerboseLog = FALSE;
00244 
00245         mbError = FALSE;
00246         mErrorCode = 0;
00247         mSendReliable = FALSE;
00248 
00249         mUnackedListDepth = 0;
00250         mUnackedListSize = 0;
00251         mDSMaxListDepth = 0;
00252 
00253         mNumberHighFreqMessages = 0;
00254         mNumberMediumFreqMessages = 0;
00255         mNumberLowFreqMessages = 0;
00256         mPacketsIn = mPacketsOut = 0;
00257         mBytesIn = mBytesOut = 0;
00258         mCompressedPacketsIn = mCompressedPacketsOut = 0;
00259         mReliablePacketsIn = mReliablePacketsOut = 0;
00260 
00261         mCompressedBytesIn = 0;
00262         mCompressedBytesOut = 0;
00263         mUncompressedBytesIn = 0;
00264         mUncompressedBytesOut = 0;
00265         mTotalBytesIn = 0;
00266         mTotalBytesOut = 0;
00267 
00268     mDroppedPackets = 0;            // total dropped packets in
00269     mResentPackets = 0;             // total resent packets out
00270     mFailedResendPackets = 0;       // total resend failure packets out
00271     mOffCircuitPackets = 0;         // total # of off-circuit packets rejected
00272     mInvalidOnCircuitPackets = 0;   // total # of on-circuit packets rejected
00273 
00274         mOurCircuitCode = 0;
00275 
00276         mIncomingCompressedSize = 0;
00277         mCurrentRecvPacketID = 0;
00278 
00279         mMessageFileVersionNumber = 0.f;
00280 
00281         mTimingCallback = NULL;
00282         mTimingCallbackData = NULL;
00283 
00284         mMessageBuilder = NULL;
00285         mMessageReader = NULL;
00286 }
00287 
00288 // Read file and build message templates
00289 LLMessageSystem::LLMessageSystem(const char *filename, U32 port, 
00290                                                                  S32 version_major,
00291                                                                  S32 version_minor,
00292                                                                  S32 version_patch)
00293 {
00294         init();
00295 
00296         mSystemVersionMajor = version_major;
00297         mSystemVersionMinor = version_minor;
00298         mSystemVersionPatch = version_patch;
00299         mSystemVersionServer = 0;
00300         mVersionFlags = 0x0;
00301 
00302         // default to not accepting packets from not alive circuits
00303         mbProtected = TRUE;
00304 
00305         mSendPacketFailureCount = 0;
00306 
00307         mCircuitPrintFreq = 60.f;               // seconds
00308 
00309         loadTemplateFile(filename);
00310 
00311         mTemplateMessageBuilder = new LLTemplateMessageBuilder(mMessageTemplates);
00312         mLLSDMessageBuilder = new LLSDMessageBuilder();
00313         mMessageBuilder = NULL;
00314 
00315         mTemplateMessageReader = new LLTemplateMessageReader(mMessageNumbers);
00316         mLLSDMessageReader = new LLSDMessageReader();
00317         mMessageReader = NULL;
00318 
00319         // initialize various bits of net info
00320         mSocket = 0;
00321         mPort = port;
00322 
00323         S32 error = start_net(mSocket, mPort);
00324         if (error != 0)
00325         {
00326                 mbError = TRUE;
00327                 mErrorCode = error;
00328         }
00329 //      LL_DEBUGS("Messaging") <<  << "*** port: " << mPort << llendl;
00330 
00331         //
00332         // Create the data structure that we can poll on
00333         //
00334         if (!gAPRPoolp)
00335         {
00336                 LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl;
00337                 ll_init_apr();
00338         }
00339         apr_socket_t *aprSocketp = NULL;
00340         apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp);
00341 
00342         mPollInfop = new LLMessagePollInfo;
00343         mPollInfop->mAPRSocketp = aprSocketp;
00344         mPollInfop->mPollFD.p = gAPRPoolp;
00345         mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET;
00346         mPollInfop->mPollFD.reqevents = APR_POLLIN;
00347         mPollInfop->mPollFD.rtnevents = 0;
00348         mPollInfop->mPollFD.desc.s = aprSocketp;
00349         mPollInfop->mPollFD.client_data = NULL;
00350 
00351         F64 mt_sec = getMessageTimeSeconds();
00352         mResendDumpTime = mt_sec;
00353         mMessageCountTime = mt_sec;
00354         mCircuitPrintTime = mt_sec;
00355         mCurrentMessageTimeSeconds = mt_sec;
00356 
00357         // Constants for dumping output based on message processing time/count
00358         mNumMessageCounts = 0;
00359         mMaxMessageCounts = 200; // >= 0 means dump warnings
00360         mMaxMessageTime   = 1.f;
00361 
00362         mTrueReceiveSize = 0;
00363 }
00364 
00365 
00366 
00367 // Read file and build message templates
00368 void LLMessageSystem::loadTemplateFile(const char* filename)
00369 {
00370         if(!filename)
00371         {
00372                 LL_ERRS("Messaging") << "No template filename specified" << llendl;
00373                 mbError = TRUE;
00374                 return;
00375         }
00376 
00377         std::string template_body;
00378         if(!_read_file_into_string(template_body, filename))
00379         {
00380                 LL_WARNS("Messaging") << "Failed to open template: " << filename << llendl;
00381                 mbError = TRUE;
00382                 return;
00383         }
00384         
00385         LLTemplateTokenizer tokens(template_body);
00386         LLTemplateParser parsed(tokens);
00387         mMessageFileVersionNumber = parsed.getVersion();
00388         for(LLTemplateParser::message_iterator iter = parsed.getMessagesBegin();
00389                 iter != parsed.getMessagesEnd();
00390                 iter++)
00391         {
00392                 addTemplate(*iter);
00393         }
00394 }
00395 
00396 
00397 LLMessageSystem::~LLMessageSystem()
00398 {
00399         mMessageTemplates.clear(); // don't delete templates.
00400         for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer());
00401         mMessageNumbers.clear();
00402         
00403         if (!mbError)
00404         {
00405                 end_net(mSocket);
00406         }
00407         mSocket = 0;
00408         
00409         delete mTemplateMessageReader;
00410         mTemplateMessageReader = NULL;
00411         mMessageReader = NULL;
00412 
00413         delete mTemplateMessageBuilder;
00414         mTemplateMessageBuilder = NULL;
00415         mMessageBuilder = NULL;
00416 
00417         delete mLLSDMessageReader;
00418         mLLSDMessageReader = NULL;
00419 
00420         delete mLLSDMessageBuilder;
00421         mLLSDMessageBuilder = NULL;
00422 
00423         delete mPollInfop;
00424         mPollInfop = NULL;
00425 
00426         mIncomingCompressedSize = 0;
00427         mCurrentRecvPacketID = 0;
00428 }
00429 
00430 void LLMessageSystem::clearReceiveState()
00431 {
00432         mCurrentRecvPacketID = 0;
00433         mIncomingCompressedSize = 0;
00434         mLastSender.invalidate();
00435         mMessageReader->clearMessage();
00436 }
00437 
00438 
00439 BOOL LLMessageSystem::poll(F32 seconds)
00440 {
00441         S32 num_socks;
00442         apr_status_t status;
00443         status = apr_poll(&(mPollInfop->mPollFD), 1, &num_socks,(U64)(seconds*1000000.f));
00444         if (status != APR_TIMEUP)
00445         {
00446                 ll_apr_warn_status(status);
00447         }
00448         if (num_socks)
00449         {
00450                 return TRUE;
00451         }
00452         else
00453         {
00454                 return FALSE;
00455         }
00456 }
00457 
00458 bool LLMessageSystem::isTrustedSender(const LLHost& host) const
00459 {
00460         LLCircuitData* cdp = mCircuitInfo.findCircuit(host);
00461         if(NULL == cdp)
00462         {
00463                 return false;
00464         }
00465         return cdp->getTrusted();
00466 }
00467 
00468 static LLMessageSystem::message_template_name_map_t::const_iterator 
00469 findTemplate(const LLMessageSystem::message_template_name_map_t& templates, 
00470                          std::string name)
00471 {
00472         const char* namePrehash = LLMessageStringTable::getInstance()->getString(name.c_str());
00473         if(NULL == namePrehash) {return templates.end();}
00474         return templates.find(namePrehash);
00475 }
00476 
00477 bool LLMessageSystem::isTrustedMessage(const std::string& name) const
00478 {
00479         message_template_name_map_t::const_iterator iter = 
00480                 findTemplate(mMessageTemplates, name);
00481         if(iter == mMessageTemplates.end()) {return false;}
00482         return iter->second->getTrust() == MT_TRUST;
00483 }
00484 
00485 bool LLMessageSystem::isUntrustedMessage(const std::string& name) const
00486 {
00487         message_template_name_map_t::const_iterator iter = 
00488                 findTemplate(mMessageTemplates, name);
00489         if(iter == mMessageTemplates.end()) {return false;}
00490         return iter->second->getTrust() == MT_NOTRUST;
00491 }
00492 
00493 LLCircuitData* LLMessageSystem::findCircuit(const LLHost& host,
00494                                                                                         bool resetPacketId)
00495 {
00496         LLCircuitData* cdp = mCircuitInfo.findCircuit(host);
00497         if (!cdp)
00498         {
00499                 // This packet comes from a circuit we don't know about.
00500                 
00501                 // Are we rejecting off-circuit packets?
00502                 if (mbProtected)
00503                 {
00504                         // cdp is already NULL, so we don't need to unset it.
00505                 }
00506                 else
00507                 {
00508                         // nope, open the new circuit
00509                         cdp = mCircuitInfo.addCircuitData(host, mCurrentRecvPacketID);
00510 
00511                         if(resetPacketId)
00512                         {
00513                                 // I added this - I think it's correct - DJS
00514                                 // reset packet in ID
00515                                 cdp->setPacketInID(mCurrentRecvPacketID);
00516                         }
00517                         // And claim the packet is on the circuit we just added.
00518                 }
00519         }
00520         else
00521         {
00522                 // this is an old circuit. . . is it still alive?
00523                 if (!cdp->isAlive())
00524                 {
00525                         // nope. don't accept if we're protected
00526                         if (mbProtected)
00527                         {
00528                                 // don't accept packets from unexpected sources
00529                                 cdp = NULL;
00530                         }
00531                         else
00532                         {
00533                                 // wake up the circuit
00534                                 cdp->setAlive(TRUE);
00535                                 
00536                                 if(resetPacketId)
00537                                 {
00538                                         // reset packet in ID
00539                                         cdp->setPacketInID(mCurrentRecvPacketID);
00540                                 }
00541                         }
00542                 }
00543         }
00544         return cdp;
00545 }
00546 
00547 // Returns TRUE if a valid, on-circuit message has been received.
00548 BOOL LLMessageSystem::checkMessages( S64 frame_count )
00549 {
00550         // Pump 
00551         BOOL    valid_packet = FALSE;
00552         mMessageReader = mTemplateMessageReader;
00553 
00554         LLTransferTargetVFile::updateQueue();
00555         
00556         if (!mNumMessageCounts)
00557         {
00558                 // This is the first message being handled after a resetReceiveCounts,
00559                 // we must be starting the message processing loop.  Reset the timers.
00560                 mCurrentMessageTimeSeconds = totalTime() * SEC_PER_USEC;
00561                 mMessageCountTime = getMessageTimeSeconds();
00562         }
00563 
00564         // loop until either no packets or a valid packet
00565         // i.e., burn through packets from unregistered circuits
00566         S32 receive_size = 0;
00567         do
00568         {
00569                 clearReceiveState();
00570                 
00571                 BOOL recv_reliable = FALSE;
00572                 BOOL recv_resent = FALSE;
00573                 S32 acks = 0;
00574                 S32 true_rcv_size = 0;
00575 
00576                 U8* buffer = mTrueReceiveBuffer;
00577                 
00578                 mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer);
00579                 // If you want to dump all received packets into SecondLife.log, uncomment this
00580                 //dumpPacketToLog();
00581                 
00582                 receive_size = mTrueReceiveSize;
00583                 mLastSender = mPacketRing.getLastSender();
00584                 
00585                 if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE)
00586                 {
00587                         // A receive size of zero is OK, that means that there are no more packets available.
00588                         // Ones that are non-zero but below the minimum packet size are worrisome.
00589                         if (receive_size > 0)
00590                         {
00591                                 LL_WARNS("Messaging") << "Invalid (too short) packet discarded " << receive_size << llendl;
00592                                 callExceptionFunc(MX_PACKET_TOO_SHORT);
00593                         }
00594                         // no data in packet receive buffer
00595                         valid_packet = FALSE;
00596                 }
00597                 else
00598                 {
00599                         LLHost host;
00600                         LLCircuitData* cdp;
00601                         
00602                         // note if packet acks are appended.
00603                         if(buffer[0] & LL_ACK_FLAG)
00604                         {
00605                                 acks += buffer[--receive_size];
00606                                 true_rcv_size = receive_size;
00607                                 if(receive_size >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE)))
00608                                 {
00609                                         receive_size -= acks * sizeof(TPACKETID);
00610                                 }
00611                                 else
00612                                 {
00613                                         // mal-formed packet. ignore it and continue with
00614                                         // the next one
00615                                         LL_WARNS("Messaging") << "Malformed packet received. Packet size "
00616                                                 << receive_size << " with invalid no. of acks " << acks
00617                                                 << llendl;
00618                                         valid_packet = FALSE;
00619                                         continue;
00620                                 }
00621                         }
00622 
00623                         // process the message as normal
00624                         mIncomingCompressedSize = zeroCodeExpand(&buffer, &receive_size);
00625                         mCurrentRecvPacketID = ntohl(*((U32*)(&buffer[1])));
00626                         host = getSender();
00627 
00628                         const bool resetPacketId = true;
00629                         cdp = findCircuit(host, resetPacketId);
00630 
00631                         // At this point, cdp is now a pointer to the circuit that
00632                         // this message came in on if it's valid, and NULL if the
00633                         // circuit was bogus.
00634 
00635                         if(cdp && (acks > 0) && ((S32)(acks * sizeof(TPACKETID)) < (true_rcv_size)))
00636                         {
00637                                 TPACKETID packet_id;
00638                                 U32 mem_id=0;
00639                                 for(S32 i = 0; i < acks; ++i)
00640                                 {
00641                                         true_rcv_size -= sizeof(TPACKETID);
00642                                         memcpy(&mem_id, &mTrueReceiveBuffer[true_rcv_size], /* Flawfinder: ignore*/
00643                                              sizeof(TPACKETID));
00644                                         packet_id = ntohl(mem_id);
00645                                         //LL_INFOS("Messaging") << "got ack: " << packet_id << llendl;
00646                                         cdp->ackReliablePacket(packet_id);
00647                                 }
00648                                 if (!cdp->getUnackedPacketCount())
00649                                 {
00650                                         // Remove this circuit from the list of circuits with unacked packets
00651                                         mCircuitInfo.mUnackedCircuitMap.erase(cdp->mHost);
00652                                 }
00653                         }
00654 
00655                         if (buffer[0] & LL_RELIABLE_FLAG)
00656                         {
00657                                 recv_reliable = TRUE;
00658                         }
00659                         if (buffer[0] & LL_RESENT_FLAG)
00660                         {
00661                                 recv_resent = TRUE;
00662                                 if (cdp && cdp->isDuplicateResend(mCurrentRecvPacketID))
00663                                 {
00664                                         // We need to ACK here to suppress
00665                                         // further resends of packets we've
00666                                         // already seen.
00667                                         if (recv_reliable)
00668                                         {
00669                                                 //mAckList.addData(new LLPacketAck(host, mCurrentRecvPacketID));
00670                                                 // ***************************************
00671                                                 // TESTING CODE
00672                                                 //if(mCircuitInfo.mCurrentCircuit->mHost != host)
00673                                                 //{
00674                                                 //      LL_WARNS("Messaging") << "DISCARDED PACKET HOST MISMATCH! HOST: "
00675                                                 //                      << host << " CIRCUIT: "
00676                                                 //                      << mCircuitInfo.mCurrentCircuit->mHost
00677                                                 //                      << llendl;
00678                                                 //}
00679                                                 // ***************************************
00680                                                 //mCircuitInfo.mCurrentCircuit->mAcks.put(mCurrentRecvPacketID);
00681                                                 cdp->collectRAck(mCurrentRecvPacketID);
00682                                         }
00683                                                                  
00684                                         LL_DEBUGS("Messaging") << "Discarding duplicate resend from " << host << llendl;
00685                                         if(mVerboseLog)
00686                                         {
00687                                                 std::ostringstream str;
00688                                                 str << "MSG: <- " << host;
00689                                                 char buffer[MAX_STRING]; /* Flawfinder: ignore*/
00690                                                 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", receive_size, (mIncomingCompressedSize ? mIncomingCompressedSize : receive_size), mCurrentRecvPacketID);       /* Flawfinder: ignore */
00691                                                 str << buffer << "(unknown)"
00692                                                         << (recv_reliable ? " reliable" : "")
00693                                                         << " resent "
00694                                                         << ((acks > 0) ? "acks" : "")
00695                                                         << " DISCARD DUPLICATE";
00696                                                 LL_INFOS("Messaging") << str.str() << llendl;
00697                                         }
00698                                         mPacketsIn++;
00699                                         valid_packet = FALSE;
00700                                         continue;
00701                                 }
00702                         }
00703 
00704                         // UseCircuitCode can be a valid, off-circuit packet.
00705                         // But we don't want to acknowledge UseCircuitCode until the circuit is
00706                         // available, which is why the acknowledgement test is done above.  JC
00707 
00708                         valid_packet = mTemplateMessageReader->validateMessage(
00709                                 buffer,
00710                                 receive_size,
00711                                 host);
00712 
00713                         // UseCircuitCode is allowed in even from an invalid circuit, so that
00714                         // we can toss circuits around.
00715                         if(
00716                                 valid_packet &&
00717                                 !cdp && 
00718                                 (mTemplateMessageReader->getMessageName() !=
00719                                  _PREHASH_UseCircuitCode))
00720                         {
00721                                 logMsgFromInvalidCircuit( host, recv_reliable );
00722                                 clearReceiveState();
00723                                 valid_packet = FALSE;
00724                         }
00725 
00726                         if(
00727                                 valid_packet &&
00728                                 cdp &&
00729                                 !cdp->getTrusted() && 
00730                                 mTemplateMessageReader->isTrusted())
00731                         {
00732                                 logTrustedMsgFromUntrustedCircuit( host );
00733                                 clearReceiveState();
00734 
00735                                 sendDenyTrustedCircuit(host);
00736                                 valid_packet = FALSE;
00737                         }
00738 
00739                         if (
00740                                 valid_packet &&
00741                                 mTemplateMessageReader->isBanned(cdp && cdp->getTrusted()))
00742                         {
00743                                 LL_WARNS("Messaging") << "LLMessageSystem::checkMessages "
00744                                         << "received banned message "
00745                                         << mTemplateMessageReader->getMessageName()
00746                                         << " from "
00747                                         << ((cdp && cdp->getTrusted()) ? "trusted " : "untrusted ")
00748                                         << host << llendl;
00749                                 clearReceiveState();
00750                                 valid_packet = FALSE;
00751                         }
00752                         
00753                         if( valid_packet )
00754                         {
00755                                 logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) );
00756 
00757                                 valid_packet = mTemplateMessageReader->readMessage(buffer, host);
00758                         }
00759 
00760                         // It's possible that the circuit went away, because ANY message can disable the circuit
00761                         // (for example, UseCircuit, CloseCircuit, DisableSimulator).  Find it again.
00762                         cdp = mCircuitInfo.findCircuit(host);
00763 
00764                         if (valid_packet)
00765                         {
00766                                 // enable this for output of message names
00767                                 //LL_INFOS("Messaging") << "< \"" << mTemplateMessageReader->getMessageName()
00768                                                 //<< "\"" << llendl;
00769 
00770                                 /* Code for dumping the complete contents of a message.  Keep for future use in optimizing messages.
00771                                 if( 1 )
00772                                 {
00773                                         static char* object_update = LLMessageStringTable::getInstance()->getString("ObjectUpdate");
00774                                         if(object_update == mTemplateMessageReader->getMessageName() )
00775                                         {
00776                                                 LL_INFOS("Messaging") << "ObjectUpdate:" << llendl;
00777                                                 U32 i;
00778                                                 LL_INFOS("Messaging") << "    Zero Encoded: " << zero_unexpanded_size << llendl;
00779                                                 for( i = 0; i<zero_unexpanded_size; i++ )
00780                                                 {
00781                                                         LL_INFOS("Messaging") << "     " << i << ": " << (U32) zero_unexpanded_buffer[i] << llendl;
00782                                                 }
00783                                                 LL_INFOS("Messaging") << "" << llendl;
00784 
00785                                                 LL_INFOS("Messaging") << "    Zero Unencoded: " << receive_size << llendl;
00786                                                 for( i = 0; i<receive_size; i++ )
00787                                                 {
00788                                                         LL_INFOS("Messaging") << "     " << i << ": " << (U32) buffer[i] << llendl;
00789                                                 }
00790                                                 LL_INFOS("Messaging") << "" << llendl;
00791 
00792                                                 LL_INFOS("Messaging") << "    Blocks and variables: " << llendl;
00793                                                 S32 byte_count = 0;
00794                                                 for (LLMessageTemplate::message_block_map_t::iterator
00795                                                                  iter = mCurrentRMessageTemplate->mMemberBlocks.begin(),
00796                                                                  end = mCurrentRMessageTemplate->mMemberBlocks.end();
00797                                                          iter != end; iter++)
00798                                                 {
00799                                                         LLMessageBlock* block = iter->second;
00800                                                         const char* block_name = block->mName;
00801                                                         for (LLMsgBlkData::msg_var_data_map_t::iterator
00802                                                                          iter = block->mMemberVariables.begin(),
00803                                                                          end = block->mMemberVariables.end();
00804                                                                  iter != end; iter++)
00805                                                         {
00806                                                                 const char* var_name = iter->first;
00807                                                                 
00808                                                                 if( getNumberOfBlocksFast( block_name ) < 1 )
00809                                                                 {
00810                                                                         LL_INFOS("Messaging") << var_name << " has no blocks" << llendl;
00811                                                                 }
00812                                                                 for( S32 blocknum = 0; blocknum < getNumberOfBlocksFast( block_name ); blocknum++ )
00813                                                                 {
00814                                                                         char *bnamep = (char *)block_name + blocknum; // this works because it's just a hash.  The bnamep is never derefference
00815                                                                         char *vnamep = (char *)var_name; 
00816 
00817                                                                         LLMsgBlkData *msg_block_data = mCurrentRMessageData->mMemberBlocks[bnamep];
00818 
00819                                                                         char errmsg[1024];
00820                                                                         if (!msg_block_data)
00821                                                                         {
00822                                                                                 sprintf(errmsg, "Block %s #%d not in message %s", block_name, blocknum, mCurrentRMessageData->mName);
00823                                                                                 LL_ERRS("Messaging") << errmsg << llendl;
00824                                                                         }
00825 
00826                                                                         LLMsgVarData vardata = msg_block_data->mMemberVarData[vnamep];
00827 
00828                                                                         if (!vardata.getName())
00829                                                                         {
00830                                                                                 sprintf(errmsg, "Variable %s not in message %s block %s", vnamep, mCurrentRMessageData->mName, bnamep);
00831                                                                                 LL_ERRS("Messaging") << errmsg << llendl;
00832                                                                         }
00833 
00834                                                                         const S32 vardata_size = vardata.getSize();
00835                                                                         if( vardata_size )
00836                                                                         {
00837                                                                                 for( i = 0; i < vardata_size; i++ )
00838                                                                                 {
00839                                                                                         byte_count++;
00840                                                                                         LL_INFOS("Messaging") << block_name << " " << var_name << " [" << blocknum << "][" << i << "]= " << (U32)(((U8*)vardata.getData())[i]) << llendl;
00841                                                                                 }
00842                                                                         }
00843                                                                         else
00844                                                                         {
00845                                                                                 LL_INFOS("Messaging") << block_name << " " << var_name << " [" << blocknum << "] 0 bytes" << llendl;
00846                                                                         }
00847                                                                 }
00848                                                         }
00849                                                 }
00850                                                 LL_INFOS("Messaging") << "Byte count =" << byte_count << llendl;
00851                                         }
00852                                 }
00853                                 */
00854 
00855                                 mPacketsIn++;
00856                                 mBytesIn += mTrueReceiveSize;
00857                                 
00858                                 // ACK here for valid packets that we've seen
00859                                 // for the first time.
00860                                 if (cdp && recv_reliable)
00861                                 {
00862                                         // Add to the recently received list for duplicate suppression
00863                                         cdp->mRecentlyReceivedReliablePackets[mCurrentRecvPacketID] = getMessageTimeUsecs();
00864 
00865                                         // Put it onto the list of packets to be acked
00866                                         cdp->collectRAck(mCurrentRecvPacketID);
00867                                         mReliablePacketsIn++;
00868                                 }
00869                         }
00870                         else
00871                         {
00872                                 if (mbProtected  && (!cdp))
00873                                 {
00874                                         LL_WARNS("Messaging") << "Invalid Packet from invalid circuit " << host << llendl;
00875                                         mOffCircuitPackets++;
00876                                 }
00877                                 else
00878                                 {
00879                                         mInvalidOnCircuitPackets++;
00880                                 }
00881                         }
00882 
00883                         // Code for dumping the complete contents of a message 
00884                         // delete [] zero_unexpanded_buffer;
00885                 }
00886         } while (!valid_packet && receive_size > 0);
00887 
00888         F64 mt_sec = getMessageTimeSeconds();
00889         // Check to see if we need to print debug info
00890         if ((mt_sec - mCircuitPrintTime) > mCircuitPrintFreq)
00891         {
00892                 dumpCircuitInfo();
00893                 mCircuitPrintTime = mt_sec;
00894         }
00895 
00896         if( !valid_packet )
00897         {
00898                 clearReceiveState();
00899         }
00900 
00901         return valid_packet;
00902 }
00903 
00904 S32     LLMessageSystem::getReceiveBytes() const
00905 {
00906         if (getReceiveCompressedSize())
00907         {
00908                 return getReceiveCompressedSize() * 8;
00909         }
00910         else
00911         {
00912                 return getReceiveSize() * 8;
00913         }
00914 }
00915 
00916 
00917 void LLMessageSystem::processAcks()
00918 {
00919         F64 mt_sec = getMessageTimeSeconds();
00920         {
00921                 gTransferManager.updateTransfers();
00922 
00923                 if (gXferManager)
00924                 {
00925                         gXferManager->retransmitUnackedPackets();
00926                 }
00927 
00928                 if (gAssetStorage)
00929                 {
00930                         gAssetStorage->checkForTimeouts();
00931                 }
00932         }
00933 
00934         BOOL dump = FALSE;
00935         {
00936                 // Check the status of circuits
00937                 mCircuitInfo.updateWatchDogTimers(this);
00938 
00939                 //resend any necessary packets
00940                 mCircuitInfo.resendUnackedPackets(mUnackedListDepth, mUnackedListSize);
00941 
00942                 //cycle through ack list for each host we need to send acks to
00943                 mCircuitInfo.sendAcks();
00944 
00945                 if (!mDenyTrustedCircuitSet.empty())
00946                 {
00947                         LL_INFOS("Messaging") << "Sending queued DenyTrustedCircuit messages." << llendl;
00948                         for (host_set_t::iterator hostit = mDenyTrustedCircuitSet.begin(); hostit != mDenyTrustedCircuitSet.end(); ++hostit)
00949                         {
00950                                 reallySendDenyTrustedCircuit(*hostit);
00951                         }
00952                         mDenyTrustedCircuitSet.clear();
00953                 }
00954 
00955                 if (mMaxMessageCounts >= 0)
00956                 {
00957                         if (mNumMessageCounts >= mMaxMessageCounts)
00958                         {
00959                                 dump = TRUE;
00960                         }
00961                 }
00962 
00963                 if (mMaxMessageTime >= 0.f)
00964                 {
00965                         // This is one of the only places where we're required to get REAL message system time.
00966                         mReceiveTime = (F32)(getMessageTimeSeconds(TRUE) - mMessageCountTime);
00967                         if (mReceiveTime > mMaxMessageTime)
00968                         {
00969                                 dump = TRUE;
00970                         }
00971                 }
00972         }
00973 
00974         if (dump)
00975         {
00976                 dumpReceiveCounts();
00977         }
00978         resetReceiveCounts();
00979 
00980         if ((mt_sec - mResendDumpTime) > CIRCUIT_DUMP_TIMEOUT)
00981         {
00982                 mResendDumpTime = mt_sec;
00983                 mCircuitInfo.dumpResends();
00984         }
00985 }
00986 
00987 void LLMessageSystem::copyMessageRtoS()
00988 {
00989         // NOTE: babbage: switch builder to match reader to avoid
00990         // converting message format
00991         if(mMessageReader == mTemplateMessageReader)
00992         {
00993                 mMessageBuilder = mTemplateMessageBuilder;
00994         }
00995         else
00996         {
00997                 mMessageBuilder = mLLSDMessageBuilder;
00998         }
00999         mSendReliable = FALSE;
01000         mMessageBuilder->newMessage(mMessageReader->getMessageName());
01001         mMessageReader->copyToBuilder(*mMessageBuilder);
01002 }
01003 
01004 void LLMessageSystem::clearMessage()
01005 {
01006         mSendReliable = FALSE;
01007         mMessageBuilder->clearMessage();
01008 }
01009 
01010 // set block to add data to within current message
01011 void LLMessageSystem::nextBlockFast(const char *blockname)
01012 {
01013         mMessageBuilder->nextBlock(blockname);
01014 }
01015 
01016 BOOL LLMessageSystem::isSendFull(const char* blockname)
01017 {
01018         char* stringTableName = NULL;
01019         if(NULL != blockname)
01020         {
01021                 stringTableName = LLMessageStringTable::getInstance()->getString(blockname);
01022         }
01023         return isSendFullFast(stringTableName);
01024 }
01025 
01026 BOOL LLMessageSystem::isSendFullFast(const char* blockname)
01027 {
01028         return mMessageBuilder->isMessageFull(blockname);
01029 }
01030 
01031 
01032 // blow away the last block of a message, return FALSE if that leaves no blocks or there wasn't a block to remove
01033 // TODO: Babbage: Remove this horror.
01034 BOOL LLMessageSystem::removeLastBlock()
01035 {
01036         return mMessageBuilder->removeLastBlock();
01037 }
01038 
01039 S32 LLMessageSystem::sendReliable(const LLHost &host)
01040 {
01041         return sendReliable(host, LL_DEFAULT_RELIABLE_RETRIES, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
01042 }
01043 
01044 
01045 S32 LLMessageSystem::sendSemiReliable(const LLHost &host, void (*callback)(void **,S32), void ** callback_data)
01046 {
01047         F32 timeout;
01048 
01049         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01050         if (cdp)
01051         {
01052                 timeout = llmax(LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS,
01053                                                 LL_SEMIRELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged());
01054         }
01055         else
01056         {
01057                 timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX;
01058         }
01059 
01060         const S32 retries = 0;
01061         const BOOL ping_based_timeout = FALSE;
01062         return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);
01063 }
01064 
01065 // send the message via a UDP packet
01066 S32 LLMessageSystem::sendReliable(      const LLHost &host, 
01067                                                                         S32 retries, 
01068                                                                         BOOL ping_based_timeout,
01069                                                                         F32 timeout, 
01070                                                                         void (*callback)(void **,S32), 
01071                                                                         void ** callback_data)
01072 {
01073         if (ping_based_timeout)
01074         {
01075             LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01076             if (cdp)
01077             {
01078                     timeout = llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, LL_RELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged());
01079             }
01080             else
01081             {
01082                     timeout = llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, LL_RELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX);
01083             }
01084         }
01085 
01086         mSendReliable = TRUE;
01087         mReliablePacketParams.set(host, retries, ping_based_timeout, timeout, 
01088                 callback, callback_data, 
01089                 const_cast<char*>(mMessageBuilder->getMessageName()));
01090         return sendMessage(host);
01091 }
01092 
01093 void LLMessageSystem::forwardMessage(const LLHost &host)
01094 {
01095         copyMessageRtoS();
01096         sendMessage(host);
01097 }
01098 
01099 void LLMessageSystem::forwardReliable(const LLHost &host)
01100 {
01101         copyMessageRtoS();
01102         sendReliable(host);
01103 }
01104 
01105 void LLMessageSystem::forwardReliable(const U32 circuit_code)
01106 {
01107         copyMessageRtoS();
01108         sendReliable(findHost(circuit_code));
01109 }
01110 
01111 S32 LLMessageSystem::forwardReliable(   const LLHost &host, 
01112                                                                                 S32 retries, 
01113                                                                                 BOOL ping_based_timeout,
01114                                                                                 F32 timeout, 
01115                                                                                 void (*callback)(void **,S32), 
01116                                                                                 void ** callback_data)
01117 {
01118         copyMessageRtoS();
01119         return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);
01120 }
01121 
01122 S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void **,S32), void ** callback_data)
01123 {
01124         F32 timeout; 
01125 
01126         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01127         if (cdp)
01128         {
01129                 timeout = llmax(LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS,
01130                                                 LL_SEMIRELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged());
01131         }
01132         else
01133         {
01134                 timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX;
01135         }
01136 
01137         S32 send_bytes = 0;
01138         if (mMessageBuilder->getMessageSize())
01139         {
01140                 mSendReliable = TRUE;
01141                 // No need for ping-based retry as not going to retry
01142                 mReliablePacketParams.set(host, 0, FALSE, timeout, callback, 
01143                                                                   callback_data, 
01144                                                                   const_cast<char*>(mMessageBuilder->getMessageName()));
01145                 send_bytes = sendMessage(host);
01146                 clearMessage();
01147         }
01148         else
01149         {
01150                 delete callback_data;
01151         }
01152         return send_bytes;
01153 }
01154 
01155 S32 LLMessageSystem::flushReliable(const LLHost &host)
01156 {
01157         S32 send_bytes = 0;
01158         if (mMessageBuilder->getMessageSize())
01159         {
01160                 send_bytes = sendReliable(host);
01161         }
01162         clearMessage();
01163         return send_bytes;
01164 }
01165 
01166 LLHTTPClient::ResponderPtr LLMessageSystem::createResponder(const std::string& name)
01167 {
01168         if(mSendReliable)
01169         {
01170                 return new LLFnPtrResponder(
01171                         mReliablePacketParams.mCallback,
01172                         mReliablePacketParams.mCallbackData,
01173                         name);
01174         }
01175         else
01176         {
01177                 // These messages aren't really unreliable, they just weren't
01178                 // explicitly sent as reliable, so they don't have a callback
01179 //              LL_WARNS("Messaging") << "LLMessageSystem::sendMessage: Sending unreliable "
01180 //                              << mMessageBuilder->getMessageName() << " message via HTTP"
01181 //                              << llendl;
01182                 return new LLFnPtrResponder(
01183                         NULL,
01184                         NULL,
01185                         mMessageBuilder->getMessageName());
01186         }
01187 }
01188 
01189 // This can be called from signal handlers,
01190 // so should should not use llinfos.
01191 S32 LLMessageSystem::sendMessage(const LLHost &host)
01192 {
01193         if (! mMessageBuilder->isBuilt())
01194         {
01195                 mSendSize = mMessageBuilder->buildMessage(
01196                         mSendBuffer,
01197                         MAX_BUFFER_SIZE,
01198                         0);
01199         }
01200 
01201         if (!(host.isOk()))    // if port and ip are zero, don't bother trying to send the message
01202         {
01203                 return 0;
01204         }
01205 
01206         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01207         if (!cdp)
01208         {
01209                 // this is a new circuit!
01210                 // are we protected?
01211                 if (mbProtected)
01212                 {
01213                         // yup! don't send packets to an unknown circuit
01214                         if(mVerboseLog)
01215                         {
01216                                 LL_INFOS_ONCE("Messaging") << "MSG: -> " << host << "\tUNKNOWN CIRCUIT:\t"
01217                                                 << mMessageBuilder->getMessageName() << llendl;
01218                         }
01219                         LL_WARNS_ONCE("Messaging") << "sendMessage - Trying to send "
01220                                         << mMessageBuilder->getMessageName() << " on unknown circuit "
01221                                         << host << llendl;
01222                         return 0;
01223                 }
01224                 else
01225                 {
01226                         // nope, open the new circuit
01227 
01228                         cdp = mCircuitInfo.addCircuitData(host, 0);
01229                 }
01230         }
01231         else
01232         {
01233                 // this is an old circuit. . . is it still alive?
01234                 if (!cdp->isAlive())
01235                 {
01236                         // nope. don't send to dead circuits
01237                         if(mVerboseLog)
01238                         {
01239                                 LL_INFOS("Messaging") << "MSG: -> " << host << "\tDEAD CIRCUIT\t\t"
01240                                                 << mMessageBuilder->getMessageName() << llendl;
01241                         }
01242                         LL_WARNS("Messaging") << "sendMessage - Trying to send message "
01243                                         << mMessageBuilder->getMessageName() << " to dead circuit "
01244                                         << host << llendl;
01245                         return 0;
01246                 }
01247         }
01248 
01249         // NOTE: babbage: LLSD message -> HTTP, template message -> UDP
01250         if(mMessageBuilder == mLLSDMessageBuilder)
01251         {
01252                 LLSD message = mLLSDMessageBuilder->getMessage();
01253                 
01254                 const LLHTTPSender& sender = LLHTTPSender::getSender(host);
01255                 sender.send(
01256                         host,
01257                         mLLSDMessageBuilder->getMessageName(),
01258                         message,
01259                         createResponder(mLLSDMessageBuilder->getMessageName()));
01260 
01261                 mSendReliable = FALSE;
01262                 mReliablePacketParams.clear();
01263                 return 1;
01264         }
01265 
01266         // zero out the flags and packetid. Subtract 1 here so that we do
01267         // not overwrite the offset if it was set set in buildMessage().
01268         memset(mSendBuffer, 0, LL_PACKET_ID_SIZE - 1); 
01269 
01270         // add the send id to the front of the message
01271         cdp->nextPacketOutID();
01272 
01273         // Packet ID size is always 4
01274         *((S32*)&mSendBuffer[PHL_PACKET_ID]) = htonl(cdp->getPacketOutID());
01275 
01276         // Compress the message, which will usually reduce its size.
01277         U8 * buf_ptr = (U8 *)mSendBuffer;
01278         U32 buffer_length = mSendSize;
01279         mMessageBuilder->compressMessage(buf_ptr, buffer_length);
01280 
01281         if (buffer_length > 1500)
01282         {
01283                 if((mMessageBuilder->getMessageName() != _PREHASH_ChildAgentUpdate)
01284                    && (mMessageBuilder->getMessageName() != _PREHASH_SendXferPacket))
01285                 {
01286                         LL_WARNS("Messaging") << "sendMessage - Trying to send "
01287                                         << ((buffer_length > 4000) ? "EXTRA " : "")
01288                                         << "BIG message " << mMessageBuilder->getMessageName() << " - "
01289                                         << buffer_length << llendl;
01290                 }
01291         }
01292         if (mSendReliable)
01293         {
01294                 buf_ptr[0] |= LL_RELIABLE_FLAG;
01295 
01296                 if (!cdp->getUnackedPacketCount())
01297                 {
01298                         // We are adding the first packed onto the unacked packet list(s)
01299                         // Add this circuit to the list of circuits with unacked packets
01300                         mCircuitInfo.mUnackedCircuitMap[cdp->mHost] = cdp;
01301                 }
01302 
01303                 cdp->addReliablePacket(mSocket,buf_ptr,buffer_length, &mReliablePacketParams);
01304                 mReliablePacketsOut++;
01305         }
01306 
01307         // tack packet acks onto the end of this message
01308         S32 space_left = (MTUBYTES - buffer_length) / sizeof(TPACKETID); // space left for packet ids
01309         S32 ack_count = (S32)cdp->mAcks.size();
01310         BOOL is_ack_appended = FALSE;
01311         std::vector<TPACKETID> acks;
01312         if((space_left > 0) && (ack_count > 0) && 
01313            (mMessageBuilder->getMessageName() != _PREHASH_PacketAck))
01314         {
01315                 buf_ptr[0] |= LL_ACK_FLAG;
01316                 S32 append_ack_count = llmin(space_left, ack_count);
01317                 const S32 MAX_ACKS = 250;
01318                 append_ack_count = llmin(append_ack_count, MAX_ACKS);
01319                 std::vector<TPACKETID>::iterator iter = cdp->mAcks.begin();
01320                 std::vector<TPACKETID>::iterator last = cdp->mAcks.begin();
01321                 last += append_ack_count;
01322                 TPACKETID packet_id;
01323                 for( ; iter != last ; ++iter)
01324                 {
01325                         // grab the next packet id.
01326                         packet_id = (*iter);
01327                         if(mVerboseLog)
01328                         {
01329                                 acks.push_back(packet_id);
01330                         }
01331 
01332                         // put it on the end of the buffer
01333                         packet_id = htonl(packet_id);
01334 
01335                         if((S32)(buffer_length + sizeof(TPACKETID)) < MAX_BUFFER_SIZE)
01336                         {
01337                             memcpy(&buf_ptr[buffer_length], &packet_id, sizeof(TPACKETID));     /* Flawfinder: ignore */
01338                             // Do the accounting
01339                             buffer_length += sizeof(TPACKETID);
01340                         }
01341                         else
01342                         {
01343                             // Just reporting error is likely not enough.  Need to
01344                             // check how to abort or error out gracefully from
01345                             // this function. XXXTBD
01346                                 // *NOTE: Actually hitting this error would indicate
01347                                 // the calculation above for space_left, ack_count,
01348                                 // append_acout_count is incorrect or that
01349                                 // MAX_BUFFER_SIZE has fallen below MTU which is bad
01350                                 // and probably programmer error.
01351                             LL_ERRS("Messaging") << "Buffer packing failed due to size.." << llendl;
01352                         }
01353                 }
01354 
01355                 // clean up the source
01356                 cdp->mAcks.erase(cdp->mAcks.begin(), last);
01357 
01358                 // tack the count in the final byte
01359                 U8 count = (U8)append_ack_count;
01360                 buf_ptr[buffer_length++] = count;
01361                 is_ack_appended = TRUE;
01362         }
01363 
01364         BOOL success;
01365         success = mPacketRing.sendPacket(mSocket, (char *)buf_ptr, buffer_length, host);
01366 
01367         if (!success)
01368         {
01369                 mSendPacketFailureCount++;
01370         }
01371         else
01372         {
01373                 // mCircuitInfo already points to the correct circuit data
01374                 cdp->addBytesOut( buffer_length );
01375         }
01376 
01377         if(mVerboseLog)
01378         {
01379                 std::ostringstream str;
01380                 str << "MSG: -> " << host;
01381                 char buffer[MAX_STRING];                        /* Flawfinder: ignore */
01382                 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID());              /* Flawfinder: ignore */
01383                 str << buffer
01384                         << mMessageBuilder->getMessageName()
01385                         << (mSendReliable ? " reliable " : "");
01386                 if(is_ack_appended)
01387                 {
01388                         str << "\tACKS:\t";
01389                         std::ostream_iterator<TPACKETID> append(str, " ");
01390                         std::copy(acks.begin(), acks.end(), append);
01391                 }
01392                 LL_INFOS("Messaging") << str.str() << llendl;
01393         }
01394 
01395 
01396         mPacketsOut++;
01397         mBytesOut += buffer_length;
01398         
01399         mSendReliable = FALSE;
01400         mReliablePacketParams.clear();
01401         return buffer_length;
01402 }
01403 
01404 void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_reliable )
01405 {
01406         if(mVerboseLog)
01407         {
01408                 std::ostringstream str;
01409                 str << "MSG: <- " << host;
01410                 char buffer[MAX_STRING];                        /* Flawfinder: ignore */
01411                 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID);                /* Flawfinder: ignore */
01412                 str << buffer
01413                         << nullToEmpty(mMessageReader->getMessageName())
01414                         << (recv_reliable ? " reliable" : "")
01415                         << " REJECTED";
01416                 LL_INFOS("Messaging") << str.str() << llendl;
01417         }
01418         // nope!
01419         // cout << "Rejecting unexpected message " << mCurrentMessageTemplate->mName << " from " << hex << ip << " , " << dec << port << endl;
01420 
01421         // Keep track of rejected messages as well
01422         if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM)
01423         {
01424                 LL_WARNS("Messaging") << "Got more than " << MAX_MESSAGE_COUNT_NUM << " packets without clearing counts" << llendl;
01425         }
01426         else
01427         {
01428                 // TODO: babbage: work out if we need these
01429                 // mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
01430                 mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
01431                 mMessageCountList[mNumMessageCounts].mInvalid = TRUE;
01432                 mNumMessageCounts++;
01433         }
01434 }
01435 
01436 S32 LLMessageSystem::sendMessage(
01437         const LLHost &host,
01438         const char* name,
01439         const LLSD& message)
01440 {
01441         if (!(host.isOk()))
01442         {
01443                 LL_WARNS("Messaging") << "trying to send message to invalid host"       << llendl;
01444                 return 0;
01445         }
01446         newMessage(name);       
01447         if (mMessageBuilder != mLLSDMessageBuilder)
01448         {
01449                 LL_WARNS("Messaging") << "trying to send llsd message when builder is not LLSD!"
01450                                 << llendl;
01451                 return 0;
01452         }
01453 
01454         const LLHTTPSender& sender = LLHTTPSender::getSender(host);
01455         sender.send(host, name, message, createResponder(name));
01456         return 1;
01457 }
01458 
01459 void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )
01460 {
01461         // RequestTrustedCircuit is how we establish trust, so don't spam
01462         // if it's received on a trusted circuit. JC
01463         if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit"))
01464         {
01465                 LL_WARNS("Messaging") << "Received trusted message on untrusted circuit. "
01466                                 << "Will reply with deny. "
01467                                 << "Message: " << nullToEmpty(mMessageReader->getMessageName())
01468                                 << " Host: " << host << llendl;
01469         }
01470 
01471         if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM)
01472         {
01473                 LL_WARNS("Messaging") << "got more than " << MAX_MESSAGE_COUNT_NUM
01474                         << " packets without clearing counts"
01475                         << llendl;
01476         }
01477         else
01478         {
01479                 // TODO: babbage: work out if we need these
01480                 //mMessageCountList[mNumMessageCounts].mMessageNum
01481                 //      = mCurrentRMessageTemplate->mMessageNumber;
01482                 mMessageCountList[mNumMessageCounts].mMessageBytes
01483                         = mMessageReader->getMessageSize();
01484                 mMessageCountList[mNumMessageCounts].mInvalid = TRUE;
01485                 mNumMessageCounts++;
01486         }
01487 }
01488 
01489 void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL recv_reliable, BOOL recv_resent, BOOL recv_acks )
01490 {
01491         if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM)
01492         {
01493                 LL_WARNS("Messaging") << "Got more than " << MAX_MESSAGE_COUNT_NUM << " packets without clearing counts" << llendl;
01494         }
01495         else
01496         {
01497                 // TODO: babbage: work out if we need these
01498                 //mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
01499                 mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
01500                 mMessageCountList[mNumMessageCounts].mInvalid = FALSE;
01501                 mNumMessageCounts++;
01502         }
01503 
01504         if (cdp)
01505         {
01506                 // update circuit packet ID tracking (missing/out of order packets)
01507                 cdp->checkPacketInID( mCurrentRecvPacketID, recv_resent );
01508                 cdp->addBytesIn( mTrueReceiveSize );
01509         }
01510 
01511         if(mVerboseLog)
01512         {
01513                 std::ostringstream str;
01514                 str << "MSG: <- " << host;
01515                 char buffer[MAX_STRING];                        /* Flawfinder: ignore */
01516                 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID);               /* Flawfinder: ignore */
01517                 str << buffer
01518                         << nullToEmpty(mMessageReader->getMessageName())
01519                         << (recv_reliable ? " reliable" : "")
01520                         << (recv_resent ? " resent" : "")
01521                         << (recv_acks ? " acks" : "");
01522                 LL_INFOS("Messaging") << str.str() << llendl;
01523         }
01524 }
01525 
01526 void LLMessageSystem::sanityCheck()
01527 {
01528 // TODO: babbage: reinstate
01529 
01530 //      if (!mCurrentRMessageData)
01531 //      {
01532 //              LL_ERRS("Messaging") << "mCurrentRMessageData is NULL" << llendl;
01533 //      }
01534 
01535 //      if (!mCurrentRMessageTemplate)
01536 //      {
01537 //              LL_ERRS("Messaging") << "mCurrentRMessageTemplate is NULL" << llendl;
01538 //      }
01539 
01540 //      if (!mCurrentRTemplateBlock)
01541 //      {
01542 //              LL_ERRS("Messaging") << "mCurrentRTemplateBlock is NULL" << llendl;
01543 //      }
01544 
01545 //      if (!mCurrentRDataBlock)
01546 //      {
01547 //              LL_ERRS("Messaging") << "mCurrentRDataBlock is NULL" << llendl;
01548 //      }
01549 
01550 //      if (!mCurrentSMessageData)
01551 //      {
01552 //              LL_ERRS("Messaging") << "mCurrentSMessageData is NULL" << llendl;
01553 //      }
01554 
01555 //      if (!mCurrentSMessageTemplate)
01556 //      {
01557 //              LL_ERRS("Messaging") << "mCurrentSMessageTemplate is NULL" << llendl;
01558 //      }
01559 
01560 //      if (!mCurrentSTemplateBlock)
01561 //      {
01562 //              LL_ERRS("Messaging") << "mCurrentSTemplateBlock is NULL" << llendl;
01563 //      }
01564 
01565 //      if (!mCurrentSDataBlock)
01566 //      {
01567 //              LL_ERRS("Messaging") << "mCurrentSDataBlock is NULL" << llendl;
01568 //      }
01569 }
01570 
01571 void LLMessageSystem::showCircuitInfo()
01572 {
01573         LL_INFOS("Messaging") << mCircuitInfo << llendl;
01574 }
01575 
01576 
01577 void LLMessageSystem::dumpCircuitInfo()
01578 {
01579         lldebugst(LLERR_CIRCUIT_INFO) << mCircuitInfo << llendl;
01580 }
01581 
01582 /* virtual */
01583 U32 LLMessageSystem::getOurCircuitCode()
01584 {
01585         return mOurCircuitCode;
01586 }
01587 
01588 void LLMessageSystem::getCircuitInfo(LLSD& info) const
01589 {
01590         mCircuitInfo.getInfo(info);
01591 }
01592 
01593 // returns whether the given host is on a trusted circuit
01594 BOOL    LLMessageSystem::getCircuitTrust(const LLHost &host)
01595 {
01596         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01597         if (cdp)
01598         {
01599                 return cdp->getTrusted();
01600         }
01601 
01602         return FALSE;
01603 }
01604 
01605 // Activate a circuit, and set its trust level (TRUE if trusted,
01606 // FALSE if not).
01607 void LLMessageSystem::enableCircuit(const LLHost &host, BOOL trusted)
01608 {
01609         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01610         if (!cdp)
01611         {
01612                 cdp = mCircuitInfo.addCircuitData(host, 0);
01613         }
01614         else
01615         {
01616                 cdp->setAlive(TRUE);
01617         }
01618         cdp->setTrusted(trusted);
01619 }
01620 
01621 void LLMessageSystem::disableCircuit(const LLHost &host)
01622 {
01623         LL_INFOS("Messaging") << "LLMessageSystem::disableCircuit for " << host << llendl;
01624         U32 code = gMessageSystem->findCircuitCode( host );
01625 
01626         // Don't need to do this, as we're removing the circuit info anyway - djs 01/28/03
01627 
01628         // don't clean up 0 circuit code entries
01629         // because many hosts (neighbor sims, etc) can have the 0 circuit
01630         if (code)
01631         {
01632                 //if (mCircuitCodes.checkKey(code))
01633                 code_session_map_t::iterator it = mCircuitCodes.find(code);
01634                 if(it != mCircuitCodes.end())
01635                 {
01636                         LL_INFOS("Messaging") << "Circuit " << code << " removed from list" << llendl;
01637                         //mCircuitCodes.removeData(code);
01638                         mCircuitCodes.erase(it);
01639                 }
01640 
01641                 U64 ip_port = 0;
01642                 std::map<U32, U64>::iterator iter = gMessageSystem->mCircuitCodeToIPPort.find(code);
01643                 if (iter != gMessageSystem->mCircuitCodeToIPPort.end())
01644                 {
01645                         ip_port = iter->second;
01646 
01647                         gMessageSystem->mCircuitCodeToIPPort.erase(iter);
01648 
01649                         U32 old_port = (U32)(ip_port & (U64)0xFFFFFFFF);
01650                         U32 old_ip = (U32)(ip_port >> 32);
01651 
01652                         LL_INFOS("Messaging") << "Host " << LLHost(old_ip, old_port) << " circuit " << code << " removed from lookup table" << llendl;
01653                         gMessageSystem->mIPPortToCircuitCode.erase(ip_port);
01654                 }
01655                 mCircuitInfo.removeCircuitData(host);
01656         }
01657         else
01658         {
01659                 // Sigh, since we can open circuits which don't have circuit
01660                 // codes, it's possible for this to happen...
01661                 
01662                 LL_WARNS("Messaging") << "Couldn't find circuit code for " << host << llendl;
01663         }
01664 
01665 }
01666 
01667 
01668 void LLMessageSystem::setCircuitAllowTimeout(const LLHost &host, BOOL allow)
01669 {
01670         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01671         if (cdp)
01672         {
01673                 cdp->setAllowTimeout(allow);
01674         }
01675 }
01676 
01677 void LLMessageSystem::setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost & host, void *user_data), void *user_data)
01678 {
01679         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01680         if (cdp)
01681         {
01682                 cdp->setTimeoutCallback(callback_func, user_data);
01683         }
01684 }
01685 
01686 
01687 BOOL LLMessageSystem::checkCircuitBlocked(const U32 circuit)
01688 {
01689         LLHost host = findHost(circuit);
01690 
01691         if (!host.isOk())
01692         {
01693                 LL_DEBUGS("Messaging") << "checkCircuitBlocked: Unknown circuit " << circuit << llendl;
01694                 return TRUE;
01695         }
01696 
01697         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01698         if (cdp)
01699         {
01700                 return cdp->isBlocked();
01701         }
01702         else
01703         {
01704                 LL_INFOS("Messaging") << "checkCircuitBlocked(circuit): Unknown host - " << host << llendl;
01705                 return FALSE;
01706         }
01707 }
01708 
01709 BOOL LLMessageSystem::checkCircuitAlive(const U32 circuit)
01710 {
01711         LLHost host = findHost(circuit);
01712 
01713         if (!host.isOk())
01714         {
01715                 LL_DEBUGS("Messaging") << "checkCircuitAlive: Unknown circuit " << circuit << llendl;
01716                 return FALSE;
01717         }
01718 
01719         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01720         if (cdp)
01721         {
01722                 return cdp->isAlive();
01723         }
01724         else
01725         {
01726                 LL_INFOS("Messaging") << "checkCircuitAlive(circuit): Unknown host - " << host << llendl;
01727                 return FALSE;
01728         }
01729 }
01730 
01731 BOOL LLMessageSystem::checkCircuitAlive(const LLHost &host)
01732 {
01733         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01734         if (cdp)
01735         {
01736                 return cdp->isAlive();
01737         }
01738         else
01739         {
01740                 LL_DEBUGS("Messaging") << "checkCircuitAlive(host): Unknown host - " << host << llendl;
01741                 return FALSE;
01742         }
01743 }
01744 
01745 
01746 void LLMessageSystem::setCircuitProtection(BOOL b_protect)
01747 {
01748         mbProtected = b_protect;
01749 }
01750 
01751 
01752 U32 LLMessageSystem::findCircuitCode(const LLHost &host)
01753 {
01754         U64 ip64 = (U64) host.getAddress();
01755         U64 port64 = (U64) host.getPort();
01756         U64 ip_port = (ip64 << 32) | port64;
01757 
01758         return get_if_there(mIPPortToCircuitCode, ip_port, U32(0));
01759 }
01760 
01761 LLHost LLMessageSystem::findHost(const U32 circuit_code)
01762 {
01763         if (mCircuitCodeToIPPort.count(circuit_code) > 0)
01764         {
01765                 return LLHost(mCircuitCodeToIPPort[circuit_code]);
01766         }
01767         else
01768         {
01769                 return LLHost::invalid;
01770         }
01771 }
01772 
01773 void LLMessageSystem::setMaxMessageTime(const F32 seconds)
01774 {
01775         mMaxMessageTime = seconds;
01776 }
01777 
01778 void LLMessageSystem::setMaxMessageCounts(const S32 num)
01779 {
01780         mMaxMessageCounts = num;
01781 }
01782 
01783 
01784 std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg)
01785 {
01786         U32 i;
01787         if (msg.mbError)
01788         {
01789                 s << "Message system not correctly initialized";
01790         }
01791         else
01792         {
01793                 s << "Message system open on port " << msg.mPort << " and socket " << msg.mSocket << "\n";
01794 //              s << "Message template file " << msg.mName << " loaded\n";
01795                 
01796                 s << "\nHigh frequency messages:\n";
01797 
01798                 for (i = 1; msg.mMessageNumbers[i] && (i < 255); i++)
01799                 {
01800                         s << *(msg.mMessageNumbers[i]);
01801                 }
01802                 
01803                 s << "\nMedium frequency messages:\n";
01804 
01805                 for (i = (255 << 8) + 1; msg.mMessageNumbers[i] && (i < (255 << 8) + 255); i++)
01806                 {
01807                         s << *msg.mMessageNumbers[i];
01808                 }
01809                 
01810                 s << "\nLow frequency messages:\n";
01811 
01812                 for (i = (0xFFFF0000) + 1; msg.mMessageNumbers[i] && (i < 0xFFFFFFFF); i++)
01813                 {
01814                         s << *msg.mMessageNumbers[i];
01815                 }
01816         }
01817         return s;
01818 }
01819 
01820 LLMessageSystem *gMessageSystem = NULL;
01821 
01822 // update appropriate ping info
01823 void    process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/)
01824 {
01825         U8 ping_id;
01826         msgsystem->getU8Fast(_PREHASH_PingID, _PREHASH_PingID, ping_id);
01827 
01828         LLCircuitData *cdp;
01829         cdp = msgsystem->mCircuitInfo.findCircuit(msgsystem->getSender());
01830 
01831         // stop the appropriate timer
01832         if (cdp)
01833         {
01834                 cdp->pingTimerStop(ping_id);
01835         }
01836 }
01837 
01838 void    process_start_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/)
01839 {
01840         U8 ping_id;
01841         msgsystem->getU8Fast(_PREHASH_PingID, _PREHASH_PingID, ping_id);
01842 
01843         LLCircuitData *cdp;
01844         cdp = msgsystem->mCircuitInfo.findCircuit(msgsystem->getSender());
01845         if (cdp)
01846         {
01847                 // Grab the packet id of the oldest unacked packet
01848                 U32 packet_id;
01849                 msgsystem->getU32Fast(_PREHASH_PingID, _PREHASH_OldestUnacked, packet_id);
01850                 cdp->clearDuplicateList(packet_id);
01851         }
01852 
01853         // Send off the response
01854         msgsystem->newMessageFast(_PREHASH_CompletePingCheck);
01855         msgsystem->nextBlockFast(_PREHASH_PingID);
01856         msgsystem->addU8(_PREHASH_PingID, ping_id);
01857         msgsystem->sendMessage(msgsystem->getSender());
01858 }
01859 
01860 
01861 
01862 // Note: this is currently unused. --mark
01863 void    open_circuit(LLMessageSystem *msgsystem, void** /*user_data*/)
01864 {
01865         U32  ip;
01866         U16      port;
01867 
01868         msgsystem->getIPAddrFast(_PREHASH_CircuitInfo, _PREHASH_IP, ip);
01869         msgsystem->getIPPortFast(_PREHASH_CircuitInfo, _PREHASH_Port, port);
01870 
01871         // By default, OpenCircuit's are untrusted
01872         msgsystem->enableCircuit(LLHost(ip, port), FALSE);
01873 }
01874 
01875 void    close_circuit(LLMessageSystem *msgsystem, void** /*user_data*/)
01876 {
01877         msgsystem->disableCircuit(msgsystem->getSender());
01878 }
01879 
01880 // static
01881 /*
01882 void LLMessageSystem::processAssignCircuitCode(LLMessageSystem* msg, void**)
01883 {
01884         // if we already have a circuit code, we can bail
01885         if(msg->mOurCircuitCode) return;
01886         LLUUID session_id;
01887         msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id);
01888         if(session_id != msg->getMySessionID())
01889         {
01890                 LL_WARNS("Messaging") << "AssignCircuitCode, bad session id. Expecting "
01891                                 << msg->getMySessionID() << " but got " << session_id
01892                                 << llendl;
01893                 return;
01894         }
01895         U32 code;
01896         msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, code);
01897         if (!code)
01898         {
01899                 LL_ERRS("Messaging") << "Assigning circuit code of zero!" << llendl;
01900         }
01901         
01902         msg->mOurCircuitCode = code;
01903         LL_INFOS("Messaging") << "Circuit code " << code << " assigned." << llendl;
01904 }
01905 */
01906 
01907 // static
01908 void LLMessageSystem::processAddCircuitCode(LLMessageSystem* msg, void**)
01909 {
01910         U32 code;
01911         msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, code);
01912         LLUUID session_id;
01913         msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id);
01914         (void)msg->addCircuitCode(code, session_id);
01915 
01916         // Send the ack back
01917         //msg->newMessageFast(_PREHASH_AckAddCircuitCode);
01918         //msg->nextBlockFast(_PREHASH_CircuitCode);
01919         //msg->addU32Fast(_PREHASH_Code, code);
01920         //msg->sendMessage(msg->getSender());
01921 }
01922 
01923 bool LLMessageSystem::addCircuitCode(U32 code, const LLUUID& session_id)
01924 {
01925         if(!code)
01926         {
01927                 LL_WARNS("Messaging") << "addCircuitCode: zero circuit code" << llendl;
01928                 return false;
01929         }
01930         code_session_map_t::iterator it = mCircuitCodes.find(code);
01931         if(it == mCircuitCodes.end())
01932         {
01933                 LL_INFOS("Messaging") << "New circuit code " << code << " added" << llendl;
01934                 //msg->mCircuitCodes[circuit_code] = circuit_code;
01935                 
01936                 mCircuitCodes.insert(code_session_map_t::value_type(code, session_id));
01937         }
01938         else
01939         {
01940                 LL_INFOS("Messaging") << "Duplicate circuit code " << code << " added" << llendl;
01941         }
01942         return true;
01943 }
01944 
01945 //void ack_add_circuit_code(LLMessageSystem *msgsystem, void** /*user_data*/)
01946 //{
01947         // By default, we do nothing.  This particular message is only handled by the spaceserver
01948 //}
01949 
01950 // static
01951 void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg,
01952                                                                                         void** user)
01953 {
01954         U32 circuit_code_in;
01955         msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, circuit_code_in);
01956 
01957         U32 ip = msg->getSenderIP();
01958         U32 port = msg->getSenderPort();
01959 
01960         U64 ip64 = ip;
01961         U64 port64 = port;
01962         U64 ip_port_in = (ip64 << 32) | port64;
01963 
01964         if (circuit_code_in)
01965         {
01966                 //if (!msg->mCircuitCodes.checkKey(circuit_code_in))
01967                 code_session_map_t::iterator it;
01968                 it = msg->mCircuitCodes.find(circuit_code_in);
01969                 if(it == msg->mCircuitCodes.end())
01970                 {
01971                         // Whoah, abort!  We don't know anything about this circuit code.
01972                         LL_WARNS("Messaging") << "UseCircuitCode for " << circuit_code_in
01973                                         << " received without AddCircuitCode message - aborting"
01974                                         << llendl;
01975                         return;
01976                 }
01977 
01978                 LLUUID id;
01979                 msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_ID, id);
01980                 LLUUID session_id;
01981                 msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id);
01982                 if(session_id != (*it).second)
01983                 {
01984                         LL_WARNS("Messaging") << "UseCircuitCode unmatched session id. Got "
01985                                         << session_id << " but expected " << (*it).second
01986                                         << llendl;
01987                         return;
01988                 }
01989 
01990                 // Clean up previous references to this ip/port or circuit
01991                 U64 ip_port_old = get_if_there(msg->mCircuitCodeToIPPort, circuit_code_in, U64(0));
01992                 U32 circuit_code_old = get_if_there(msg->mIPPortToCircuitCode, ip_port_in, U32(0));
01993 
01994                 if (ip_port_old)
01995                 {
01996                         if ((ip_port_old == ip_port_in) && (circuit_code_old == circuit_code_in))
01997                         {
01998                                 // Current information is the same as incoming info, ignore
01999                                 LL_INFOS("Messaging") << "Got duplicate UseCircuitCode for circuit " << circuit_code_in << " to " << msg->getSender() << llendl;
02000                                 return;
02001                         }
02002 
02003                         // Hmm, got a different IP and port for the same circuit code.
02004                         U32 circut_code_old_ip_port = get_if_there(msg->mIPPortToCircuitCode, ip_port_old, U32(0));
02005                         msg->mCircuitCodeToIPPort.erase(circut_code_old_ip_port);
02006                         msg->mIPPortToCircuitCode.erase(ip_port_old);
02007                         U32 old_port = (U32)(ip_port_old & (U64)0xFFFFFFFF);
02008                         U32 old_ip = (U32)(ip_port_old >> 32);
02009                         LL_INFOS("Messaging") << "Removing derelict lookup entry for circuit " << circuit_code_old << " to " << LLHost(old_ip, old_port) << llendl;
02010                 }
02011 
02012                 if (circuit_code_old)
02013                 {
02014                         LLHost cur_host(ip, port);
02015 
02016                         LL_WARNS("Messaging") << "Disabling existing circuit for " << cur_host << llendl;
02017                         msg->disableCircuit(cur_host);
02018                         if (circuit_code_old == circuit_code_in)
02019                         {
02020                                 LL_WARNS("Messaging") << "Asymmetrical circuit to ip/port lookup!" << llendl;
02021                                 LL_WARNS("Messaging") << "Multiple circuit codes for " << cur_host << " probably!" << llendl;
02022                                 LL_WARNS("Messaging") << "Permanently disabling circuit" << llendl;
02023                                 return;
02024                         }
02025                         else
02026                         {
02027                                 LL_WARNS("Messaging") << "Circuit code changed for " << msg->getSender()
02028                                                 << " from " << circuit_code_old << " to "
02029                                                 << circuit_code_in << llendl;
02030                         }
02031                 }
02032 
02033                 // Since this comes from the viewer, it's untrusted, but it
02034                 // passed the circuit code and session id check, so we will go
02035                 // ahead and persist the ID associated.
02036                 LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender());
02037                 BOOL had_circuit_already = cdp ? TRUE : FALSE;
02038 
02039                 msg->enableCircuit(msg->getSender(), FALSE);
02040                 cdp = msg->mCircuitInfo.findCircuit(msg->getSender());
02041                 if(cdp)
02042                 {
02043                         cdp->setRemoteID(id);
02044                         cdp->setRemoteSessionID(session_id);
02045                 }
02046 
02047                 if (!had_circuit_already)
02048                 {
02049                         //
02050                         // HACK HACK HACK HACK HACK!
02051                         //
02052                         // This would NORMALLY happen inside logValidMsg, but at the point that this happens
02053                         // inside logValidMsg, there's no circuit for this message yet.  So the awful thing that
02054                         // we do here is do it inside this message handler immediately AFTER the message is
02055                         // handled.
02056                         //
02057                         // We COULD not do this, but then what happens is that some of the circuit bookkeeping
02058                         // gets broken, especially the packets in count.  That causes some later packets to flush
02059                         // the RecentlyReceivedReliable list, resulting in an error in which UseCircuitCode
02060                         // doesn't get properly duplicate suppressed.  Not a BIG deal, but it's somewhat confusing
02061                         // (and bad from a state point of view).  DJS 9/23/04
02062                         //
02063                         cdp->checkPacketInID(gMessageSystem->mCurrentRecvPacketID, FALSE ); // Since this is the first message on the circuit, by definition it's not resent.
02064                 }
02065 
02066                 msg->mIPPortToCircuitCode[ip_port_in] = circuit_code_in;
02067                 msg->mCircuitCodeToIPPort[circuit_code_in] = ip_port_in;
02068 
02069                 LL_INFOS("Messaging") << "Circuit code " << circuit_code_in << " from "
02070                                 << msg->getSender() << " for agent " << id << " in session "
02071                                 << session_id << llendl;
02072 
02073                 const LLUseCircuitCodeResponder* responder =
02074                         (const LLUseCircuitCodeResponder*) user;
02075                 if(responder)
02076                 {
02077                         responder->complete(msg->getSender(), id);
02078                 }
02079         }
02080         else
02081         {
02082                 LL_WARNS("Messaging") << "Got zero circuit code in use_circuit_code" << llendl;
02083         }
02084 }
02085 
02086 // static
02087 void LLMessageSystem::processError(LLMessageSystem* msg, void**)
02088 {
02089         char buffer[MTUBYTES];
02090         S32 error_code = 0;
02091         msg->getS32("Data", "Code", error_code);
02092         std::string error_token;
02093         msg->getString("Data", "Token", MTUBYTES, buffer);
02094         error_token.assign(buffer);
02095         LLUUID error_id;
02096         msg->getUUID("Data", "ID", error_id);
02097         std::string error_system;
02098         msg->getString("Data", "System", MTUBYTES, buffer);
02099         error_system.assign(buffer);
02100         std::string error_message;
02101         msg->getString("Data", "Message", MTUBYTES, buffer);
02102         error_message.assign(buffer);
02103 
02104         LL_WARNS("Messaging") << "Message error from " << msg->getSender() << " - "
02105                 << error_code << " " << error_token << " " << error_id << " \""
02106                 << error_system << "\" \"" << error_message << "\"" << llendl;
02107 }
02108 
02109 
02110 static LLHTTPNode& messageRootNode()
02111 {
02112         static LLHTTPNode root_node;
02113         static bool initialized = false;
02114         if (!initialized) {
02115                 initialized = true;
02116                 LLHTTPRegistrar::buildAllServices(root_node);
02117         }
02118 
02119         return root_node;
02120 }
02121 
02122 //static
02123 void LLMessageSystem::dispatch(
02124         const std::string& msg_name,
02125         const LLSD& message)
02126 {
02127         LLPointer<LLSimpleResponse>     responsep =     LLSimpleResponse::create();
02128         dispatch(msg_name, message, responsep);
02129 }
02130 
02131 //static
02132 void LLMessageSystem::dispatch(
02133         const std::string& msg_name,
02134         const LLSD& message,
02135         LLHTTPNode::ResponsePtr responsep)
02136 {
02137         if ((gMessageSystem->mMessageTemplates.find
02138                         (LLMessageStringTable::getInstance()->getString(msg_name.c_str())) ==
02139                                 gMessageSystem->mMessageTemplates.end()) &&
02140                 !LLMessageConfig::isValidMessage(msg_name))
02141         {
02142                 LL_WARNS("Messaging") << "Ignoring unknown message " << msg_name << llendl;
02143                 responsep->notFound("Invalid message name");
02144                 return;
02145         }
02146         
02147         std::string     path = "/message/" + msg_name;
02148         LLSD context;
02149         const LLHTTPNode* handler =     messageRootNode().traverse(path, context);
02150         if (!handler)
02151         {
02152                 LL_WARNS("Messaging")   << "LLMessageService::dispatch > no handler for "
02153                                 << path << llendl;
02154                 return;
02155         }
02156         // enable this for output of message names
02157         //LL_INFOS("Messaging") << "< \"" << msg_name << "\"" << llendl;
02158         //lldebugs << "data: " << LLSDNotationStreamer(message) << llendl;         
02159 
02160         handler->post(responsep, context, message);
02161 }
02162 
02163 static void check_for_unrecognized_messages(
02164                 const char* type,
02165                 const LLSD& map,
02166                 LLMessageSystem::message_template_name_map_t& templates)
02167 {
02168         for (LLSD::map_const_iterator iter = map.beginMap(),
02169                         end = map.endMap();
02170                  iter != end; ++iter)
02171         {
02172                 const char* name = LLMessageStringTable::getInstance()->getString(iter->first.c_str());
02173 
02174                 if (templates.find(name) == templates.end())
02175                 {
02176                         LL_INFOS("AppInit") << "    " << type
02177                                 << " ban list contains unrecognized message "
02178                                 << name << LL_ENDL;
02179                 }
02180         }
02181 }
02182 
02183 void LLMessageSystem::setMessageBans(
02184                 const LLSD& trusted, const LLSD& untrusted)
02185 {
02186         LL_DEBUGS("AppInit") << "LLMessageSystem::setMessageBans:" << LL_ENDL;
02187         bool any_set = false;
02188 
02189         for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(),
02190                          end = mMessageTemplates.end();
02191                  iter != end; ++iter)
02192         {
02193                 LLMessageTemplate* mt = iter->second;
02194 
02195                 std::string name(mt->mName);
02196                 bool ban_from_trusted
02197                         = trusted.has(name) && trusted.get(name).asBoolean();
02198                 bool ban_from_untrusted
02199                         = untrusted.has(name) && untrusted.get(name).asBoolean();
02200 
02201                 mt->mBanFromTrusted = ban_from_trusted;
02202                 mt->mBanFromUntrusted = ban_from_untrusted;
02203 
02204                 if (ban_from_trusted  ||  ban_from_untrusted)
02205                 {
02206                         LL_INFOS("AppInit") << "    " << name << " banned from "
02207                                 << (ban_from_trusted ? "TRUSTED " : " ")
02208                                 << (ban_from_untrusted ? "UNTRUSTED " : " ")
02209                                 << LL_ENDL;
02210                         any_set = true;
02211                 }
02212         }
02213 
02214         if (!any_set) 
02215         {
02216                 LL_DEBUGS("AppInit") << "    no messages banned" << LL_ENDL;
02217         }
02218 
02219         check_for_unrecognized_messages("trusted", trusted, mMessageTemplates);
02220         check_for_unrecognized_messages("untrusted", untrusted, mMessageTemplates);
02221 }
02222 
02223 S32 LLMessageSystem::sendError(
02224         const LLHost& host,
02225         const LLUUID& agent_id,
02226         S32 code,
02227         const std::string& token,
02228         const LLUUID& id,
02229         const std::string& system,
02230         const std::string& message,
02231         const LLSD& data)
02232 {
02233         newMessage("Error");
02234         nextBlockFast(_PREHASH_AgentData);
02235         addUUIDFast(_PREHASH_AgentID, agent_id);
02236         nextBlockFast(_PREHASH_Data);
02237         addS32("Code", code);
02238         addString("Token", token);
02239         addUUID("ID", id);
02240         addString("System", system);
02241         std::string temp;
02242         temp = message;
02243         if(temp.size() > (size_t)MTUBYTES) temp.resize((size_t)MTUBYTES);
02244         addString("Message", message);
02245         LLPointer<LLSDBinaryFormatter> formatter = new LLSDBinaryFormatter;
02246         std::ostringstream ostr;
02247         formatter->format(data, ostr);
02248         temp = ostr.str();
02249         bool pack_data = true;
02250         static const std::string ERROR_MESSAGE_NAME("Error");
02251         if (LLMessageConfig::getMessageFlavor(ERROR_MESSAGE_NAME) ==
02252                 LLMessageConfig::TEMPLATE_FLAVOR)
02253         {
02254                 S32 msg_size = temp.size() + mMessageBuilder->getMessageSize();
02255                 if(msg_size >= ETHERNET_MTU_BYTES)
02256                 {
02257                         pack_data = false;
02258                 }
02259         }
02260         if(pack_data)
02261         {
02262                 addBinaryData("Data", (void*)temp.c_str(), temp.size());
02263         }
02264         else
02265         {
02266                 LL_WARNS("Messaging") << "Data and message were too large -- data removed."
02267                         << llendl;
02268                 addBinaryData("Data", NULL, 0);
02269         }
02270         return sendReliable(host);
02271 }
02272 
02273 void    process_packet_ack(LLMessageSystem *msgsystem, void** /*user_data*/)
02274 {
02275         TPACKETID packet_id;
02276 
02277         LLHost host = msgsystem->getSender();
02278         LLCircuitData *cdp = msgsystem->mCircuitInfo.findCircuit(host);
02279         if (cdp)
02280         {
02281         
02282                 S32 ack_count = msgsystem->getNumberOfBlocksFast(_PREHASH_Packets);
02283 
02284                 for (S32 i = 0; i < ack_count; i++)
02285                 {
02286                         msgsystem->getU32Fast(_PREHASH_Packets, _PREHASH_ID, packet_id, i);
02287 //                      LL_DEBUGS("Messaging") << "ack recvd' from " << host << " for packet " << (TPACKETID)packet_id << llendl;
02288                         cdp->ackReliablePacket(packet_id);
02289                 }
02290                 if (!cdp->getUnackedPacketCount())
02291                 {
02292                         // Remove this circuit from the list of circuits with unacked packets
02293                         gMessageSystem->mCircuitInfo.mUnackedCircuitMap.erase(host);
02294                 }
02295         }
02296 }
02297 
02298 
02299 /*
02300 void process_log_messages(LLMessageSystem* msg, void**)
02301 {
02302         U8 log_message;
02303 
02304         msg->getU8Fast(_PREHASH_Options, _PREHASH_Enable, log_message);
02305         
02306         if (log_message)
02307         {
02308                 LL_INFOS("Messaging") << "Starting logging via message" << llendl;
02309                 msg->startLogging();
02310         }
02311         else
02312         {
02313                 LL_INFOS("Messaging") << "Stopping logging via message" << llendl;
02314                 msg->stopLogging();
02315         }
02316 }*/
02317 
02318 // Make circuit trusted if the MD5 Digest matches, otherwise
02319 // notify remote end that they are not trusted.
02320 void process_create_trusted_circuit(LLMessageSystem *msg, void **)
02321 {
02322         // don't try to create trust on machines with no shared secret
02323         std::string shared_secret = get_shared_secret();
02324         if(shared_secret.empty()) return;
02325 
02326         LLUUID remote_id;
02327         msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_EndPointID, remote_id);
02328 
02329         LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender());
02330         if (!cdp)
02331         {
02332                 LL_WARNS("Messaging") << "Attempt to create trusted circuit without circuit data: "
02333                                 << msg->getSender() << llendl;
02334                 return;
02335         }
02336 
02337         LLUUID local_id;
02338         local_id = cdp->getLocalEndPointID();
02339         if (remote_id == local_id)
02340         {
02341                 //      Don't respond to requests that use the same end point ID
02342                 return;
02343         }
02344 
02345         char their_digest[MD5HEX_STR_SIZE];     /* Flawfinder: ignore */
02346         S32 size = msg->getSizeFast(_PREHASH_DataBlock, _PREHASH_Digest);
02347         if(size != MD5HEX_STR_BYTES)
02348         {
02349                 // ignore requests which pack the wrong amount of data.
02350                 return;
02351         }
02352         msg->getBinaryDataFast(_PREHASH_DataBlock, _PREHASH_Digest, their_digest, MD5HEX_STR_BYTES);
02353         their_digest[MD5HEX_STR_SIZE - 1] = '\0';
02354         if(msg->isMatchingDigestForWindowAndUUIDs(their_digest, TRUST_TIME_WINDOW, local_id, remote_id))
02355         {
02356                 cdp->setTrusted(TRUE);
02357                 LL_INFOS("Messaging") << "Trusted digest from " << msg->getSender() << llendl;
02358                 return;
02359         }
02360         else if (cdp->getTrusted())
02361         {
02362                 // The digest is bad, but this circuit is already trusted.
02363                 // This means that this could just be the result of a stale deny sent from a while back, and
02364                 // the message system is being slow.  Don't bother sending the deny, as it may continually
02365                 // ping-pong back and forth on a very hosed circuit.
02366                 LL_WARNS("Messaging") << "Ignoring bad digest from known trusted circuit: " << their_digest
02367                         << " host: " << msg->getSender() << llendl;
02368                 return;
02369         }
02370         else
02371         {
02372                 LL_WARNS("Messaging") << "Bad digest from known circuit: " << their_digest
02373                                 << " host: " << msg->getSender() << llendl;
02374                 msg->sendDenyTrustedCircuit(msg->getSender());
02375                 return;
02376         }
02377 }                  
02378 
02379 void process_deny_trusted_circuit(LLMessageSystem *msg, void **)
02380 {
02381         // don't try to create trust on machines with no shared secret
02382         std::string shared_secret = get_shared_secret();
02383         if(shared_secret.empty()) return;
02384 
02385         LLUUID remote_id;
02386         msg->getUUIDFast(_PREHASH_DataBlock, _PREHASH_EndPointID, remote_id);
02387 
02388         LLCircuitData *cdp = msg->mCircuitInfo.findCircuit(msg->getSender());
02389         if (!cdp)
02390         {
02391                 return;
02392         }
02393 
02394         LLUUID local_id;
02395         local_id = cdp->getLocalEndPointID();
02396         if (remote_id == local_id)
02397         {
02398                 //      Don't respond to requests that use the same end point ID
02399                 return;
02400         }
02401 
02402         // Assume that we require trust to proceed, so resend.
02403         // This catches the case where a circuit that was trusted
02404         // times out, and allows us to re-establish it, but does
02405         // mean that if our shared_secret or clock is wrong, we'll
02406         // spin.
02407         // *TODO: probably should keep a count of number of resends
02408         // per circuit, and stop resending after a while.
02409         LL_INFOS("Messaging") << "Got DenyTrustedCircuit. Sending CreateTrustedCircuit to "
02410                         << msg->getSender() << llendl;
02411         msg->sendCreateTrustedCircuit(msg->getSender(), local_id, remote_id);
02412 }
02413 
02414 
02415 void dump_prehash_files()
02416 {
02417         U32 i;
02418         LLFILE* fp = LLFile::fopen("../../indra/llmessage/message_prehash.h", "w");     /* Flawfinder: ignore */
02419         if (fp)
02420         {
02421                 fprintf(
02422                         fp,
02423                         "/**\n"
02424                         " * @file message_prehash.h\n"
02425                         " * @brief header file of externs of prehashed variables plus defines.\n"
02426                         " *\n"
02427                         " * $LicenseInfo:firstyear=2003&license=viewergpl$"
02428                         " * $/LicenseInfo$"
02429                         " */\n\n"
02430                         "#ifndef LL_MESSAGE_PREHASH_H\n#define LL_MESSAGE_PREHASH_H\n\n");
02431                 fprintf(
02432                         fp,
02433                         "/**\n"
02434                         " * Generated from message template version number %.3f\n"
02435                         " */\n",
02436                         gMessageSystem->mMessageFileVersionNumber);
02437                 fprintf(fp, "\n\nextern F32 gPrehashVersionNumber;\n\n");
02438                 for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++)
02439                 {
02440                         if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.')
02441                         {
02442                                 fprintf(fp, "extern char * _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]);
02443                         }
02444                 }
02445                 fprintf(fp, "\n\n#endif\n");
02446                 fclose(fp);
02447         }
02448         fp = LLFile::fopen("../../indra/llmessage/message_prehash.cpp", "w");   /* Flawfinder: ignore */
02449         if (fp)
02450         {
02451                 fprintf(
02452                         fp,
02453                         "/**\n"
02454                         " * @file message_prehash.cpp\n"
02455                         " * @brief file of prehashed variables\n"
02456                         " *\n"
02457                         " * $LicenseInfo:firstyear=2003&license=viewergpl$"
02458                         " * $/LicenseInfo$"
02459                         " */\n\n"
02460                         "/**\n"
02461                         " * Generated from message template version number %.3f\n"
02462                         " */\n",
02463                         gMessageSystem->mMessageFileVersionNumber);
02464                 fprintf(fp, "#include \"linden_common.h\"\n");
02465                 fprintf(fp, "#include \"message.h\"\n\n");
02466                 fprintf(fp, "\n\nF32 gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber);
02467                 for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++)
02468                 {
02469                         if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.')
02470                         {
02471                                 fprintf(fp, "char * _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]);
02472                         }
02473                 }
02474                 fclose(fp);
02475         }
02476 }
02477 
02478 BOOL start_messaging_system(
02479         const std::string& template_name,
02480         U32 port,
02481         S32 version_major,
02482         S32 version_minor,
02483         S32 version_patch,
02484         BOOL b_dump_prehash_file,
02485         const std::string& secret,
02486         const LLUseCircuitCodeResponder* responder)
02487 {
02488         gMessageSystem = new LLMessageSystem(
02489                 template_name.c_str(),
02490                 port, 
02491                 version_major, 
02492                 version_minor, 
02493                 version_patch);
02494         g_shared_secret.assign(secret);
02495 
02496         if (!gMessageSystem)
02497         {
02498                 LL_ERRS("AppInit") << "Messaging system initialization failed." << LL_ENDL;
02499                 return FALSE;
02500         }
02501 
02502         // bail if system encountered an error.
02503         if(!gMessageSystem->isOK())
02504         {
02505                 return FALSE;
02506         }
02507 
02508         if (b_dump_prehash_file)
02509         {
02510                 dump_prehash_files();
02511                 exit(0);
02512         }
02513         else
02514         {
02515                 if (gMessageSystem->mMessageFileVersionNumber != gPrehashVersionNumber)
02516                 {
02517                         LL_INFOS("AppInit") << "Message template version does not match prehash version number" << LL_ENDL;
02518                         LL_INFOS("AppInit") << "Run simulator with -prehash command line option to rebuild prehash data" << llendl;
02519                 }
02520                 else
02521                 {
02522                         LL_DEBUGS("AppInit") << "Message template version matches prehash version number" << llendl;
02523                 }
02524         }
02525 
02526         gMessageSystem->setHandlerFuncFast(_PREHASH_StartPingCheck,                     process_start_ping_check,               NULL);
02527         gMessageSystem->setHandlerFuncFast(_PREHASH_CompletePingCheck,          process_complete_ping_check,    NULL);
02528         gMessageSystem->setHandlerFuncFast(_PREHASH_OpenCircuit,                        open_circuit,                   NULL);
02529         gMessageSystem->setHandlerFuncFast(_PREHASH_CloseCircuit,                       close_circuit,                  NULL);
02530 
02531         //gMessageSystem->setHandlerFuncFast(_PREHASH_AssignCircuitCode, LLMessageSystem::processAssignCircuitCode);       
02532         gMessageSystem->setHandlerFuncFast(_PREHASH_AddCircuitCode, LLMessageSystem::processAddCircuitCode);
02533         //gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode,                ack_add_circuit_code,           NULL);
02534         gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder);
02535         gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck,             process_packet_ack,      NULL);
02536         //gMessageSystem->setHandlerFuncFast(_PREHASH_LogMessages,                      process_log_messages,   NULL);
02537         gMessageSystem->setHandlerFuncFast(_PREHASH_CreateTrustedCircuit,
02538                                        process_create_trusted_circuit,
02539                                        NULL);
02540         gMessageSystem->setHandlerFuncFast(_PREHASH_DenyTrustedCircuit,
02541                                        process_deny_trusted_circuit,
02542                                        NULL);
02543         gMessageSystem->setHandlerFunc("Error", LLMessageSystem::processError);
02544 
02545         // We can hand this to the null_message_callback since it is a
02546         // trusted message, so it will automatically be denied if it isn't
02547         // trusted and ignored if it is -- exactly what we want.
02548         gMessageSystem->setHandlerFunc(
02549                 "RequestTrustedCircuit",
02550                 null_message_callback,
02551                 NULL);
02552 
02553         // Initialize the transfer manager
02554         gTransferManager.init();
02555 
02556         return TRUE;
02557 }
02558 
02559 void LLMessageSystem::startLogging()
02560 {
02561         mVerboseLog = TRUE;
02562         std::ostringstream str;
02563         str << "START MESSAGE LOG" << std::endl;
02564         str << "Legend:" << std::endl;
02565         str << "\t<-\tincoming message" <<std::endl;
02566         str << "\t->\toutgoing message" << std::endl;
02567         str << "     <>        host           size    zero      id name";
02568         LL_INFOS("Messaging") << str.str() << llendl;
02569 }
02570 
02571 void LLMessageSystem::stopLogging()
02572 {
02573         if(mVerboseLog)
02574         {
02575                 mVerboseLog = FALSE;
02576                 LL_INFOS("Messaging") << "END MESSAGE LOG" << llendl;
02577         }
02578 }
02579 
02580 void LLMessageSystem::summarizeLogs(std::ostream& str)
02581 {
02582         char buffer[MAX_STRING];        /* Flawfinder: ignore */ 
02583         char tmp_str[MAX_STRING];        /* Flawfinder: ignore */ 
02584         F32 run_time = mMessageSystemTimer.getElapsedTimeF32();
02585         str << "START MESSAGE LOG SUMMARY" << std::endl;
02586         snprintf(buffer, MAX_STRING, "Run time: %12.3f seconds", run_time);     /* Flawfinder: ignore */
02587 
02588         // Incoming
02589         str << buffer << std::endl << "Incoming:" << std::endl;
02590         U64_to_str(mTotalBytesIn, tmp_str, sizeof(tmp_str));
02591         snprintf(buffer, MAX_STRING, "Total bytes received:      %20s (%5.2f kbits per second)", tmp_str, ((F32)mTotalBytesIn * 0.008f) / run_time);    /* Flawfinder: ignore */
02592         str << buffer << std::endl;
02593         U64_to_str(mPacketsIn, tmp_str, sizeof(tmp_str));
02594         snprintf(buffer, MAX_STRING, "Total packets received:    %20s (%5.2f packets per second)", tmp_str, ((F32) mPacketsIn / run_time));     /* Flawfinder: ignore */
02595         str << buffer << std::endl;
02596         snprintf(buffer, MAX_STRING, "Average packet size:       %20.0f bytes", (F32)mTotalBytesIn / (F32)mPacketsIn);  /* Flawfinder: ignore */
02597         str << buffer << std::endl;
02598         U64_to_str(mReliablePacketsIn, tmp_str, sizeof(tmp_str));
02599         snprintf(buffer, MAX_STRING, "Total reliable packets:    %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mReliablePacketsIn)/((F32) mPacketsIn + 1));          /* Flawfinder: ignore */
02600         str << buffer << std::endl;
02601         U64_to_str(mCompressedPacketsIn, tmp_str, sizeof(tmp_str));
02602         snprintf(buffer, MAX_STRING, "Total compressed packets:  %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mCompressedPacketsIn)/((F32) mPacketsIn + 1));        /* Flawfinder: ignore */
02603         str << buffer << std::endl;
02604         S64 savings = mUncompressedBytesIn - mCompressedBytesIn;
02605         U64_to_str(savings, tmp_str, sizeof(tmp_str));
02606         snprintf(buffer, MAX_STRING, "Total compression savings: %20s bytes", tmp_str); /* Flawfinder: ignore */
02607         str << buffer << std::endl;
02608         U64_to_str(savings/(mCompressedPacketsIn +1), tmp_str, sizeof(tmp_str));
02609         snprintf(buffer, MAX_STRING, "Avg comp packet savings:   %20s (%5.2f : 1)", tmp_str, ((F32) mUncompressedBytesIn)/((F32) mCompressedBytesIn+1));        /* Flawfinder: ignore */
02610         str << buffer << std::endl;
02611         U64_to_str(savings/(mPacketsIn+1), tmp_str, sizeof(tmp_str));
02612         snprintf(buffer, MAX_STRING, "Avg overall comp savings:  %20s (%5.2f : 1)", tmp_str, ((F32) mTotalBytesIn + (F32) savings)/((F32) mTotalBytesIn + 1.f));        /* Flawfinder: ignore */
02613 
02614         // Outgoing
02615         str << buffer << std::endl << std::endl << "Outgoing:" << std::endl;
02616         U64_to_str(mTotalBytesOut, tmp_str, sizeof(tmp_str));
02617         snprintf(buffer, MAX_STRING, "Total bytes sent:          %20s (%5.2f kbits per second)", tmp_str, ((F32)mTotalBytesOut * 0.008f) / run_time );  /* Flawfinder: ignore */
02618         str << buffer << std::endl;
02619         U64_to_str(mPacketsOut, tmp_str, sizeof(tmp_str));
02620         snprintf(buffer, MAX_STRING, "Total packets sent:        %20s (%5.2f packets per second)", tmp_str, ((F32)mPacketsOut / run_time));     /* Flawfinder: ignore */
02621         str << buffer << std::endl;
02622         snprintf(buffer, MAX_STRING, "Average packet size:       %20.0f bytes", (F32)mTotalBytesOut / (F32)mPacketsOut);        /* Flawfinder: ignore */
02623         str << buffer << std::endl;
02624         U64_to_str(mReliablePacketsOut, tmp_str, sizeof(tmp_str));
02625         snprintf(buffer, MAX_STRING, "Total reliable packets:    %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mReliablePacketsOut)/((F32) mPacketsOut + 1));                /* Flawfinder: ignore */
02626         str << buffer << std::endl;
02627         U64_to_str(mCompressedPacketsOut, tmp_str, sizeof(tmp_str));
02628         snprintf(buffer, MAX_STRING, "Total compressed packets:  %20s (%5.2f%%)", tmp_str, 100.f * ((F32) mCompressedPacketsOut)/((F32) mPacketsOut + 1));              /* Flawfinder: ignore */
02629         str << buffer << std::endl;
02630         savings = mUncompressedBytesOut - mCompressedBytesOut;
02631         U64_to_str(savings, tmp_str, sizeof(tmp_str));
02632         snprintf(buffer, MAX_STRING, "Total compression savings: %20s bytes", tmp_str); /* Flawfinder: ignore */
02633         str << buffer << std::endl;
02634         U64_to_str(savings/(mCompressedPacketsOut +1), tmp_str, sizeof(tmp_str));
02635         snprintf(buffer, MAX_STRING, "Avg comp packet savings:   %20s (%5.2f : 1)", tmp_str, ((F32) mUncompressedBytesOut)/((F32) mCompressedBytesOut+1));              /* Flawfinder: ignore */
02636         str << buffer << std::endl;
02637         U64_to_str(savings/(mPacketsOut+1), tmp_str, sizeof(tmp_str));
02638         snprintf(buffer, MAX_STRING, "Avg overall comp savings:  %20s (%5.2f : 1)", tmp_str, ((F32) mTotalBytesOut + (F32) savings)/((F32) mTotalBytesOut + 1.f));              /* Flawfinder: ignore */
02639         str << buffer << std::endl << std::endl;
02640         snprintf(buffer, MAX_STRING, "SendPacket failures:       %20d", mSendPacketFailureCount);       /* Flawfinder: ignore */
02641         str << buffer << std::endl;
02642         snprintf(buffer, MAX_STRING, "Dropped packets:           %20d", mDroppedPackets);       /* Flawfinder: ignore */
02643         str << buffer << std::endl;
02644         snprintf(buffer, MAX_STRING, "Resent packets:            %20d", mResentPackets);        /* Flawfinder: ignore */
02645         str << buffer << std::endl;
02646         snprintf(buffer, MAX_STRING, "Failed reliable resends:   %20d", mFailedResendPackets);  /* Flawfinder: ignore */
02647         str << buffer << std::endl;
02648         snprintf(buffer, MAX_STRING, "Off-circuit rejected packets: %17d", mOffCircuitPackets); /* Flawfinder: ignore */
02649         str << buffer << std::endl;
02650         snprintf(buffer, MAX_STRING, "On-circuit invalid packets:   %17d", mInvalidOnCircuitPackets);           /* Flawfinder: ignore */
02651         str << buffer << std::endl << std::endl;
02652 
02653         str << "Decoding: " << std::endl;
02654         snprintf(buffer, MAX_STRING, "%35s%10s%10s%10s%10s", "Message", "Count", "Time", "Max", "Avg"); /* Flawfinder: ignore */
02655         str << buffer << std:: endl;    
02656         F32 avg;
02657         for (message_template_name_map_t::const_iterator iter = mMessageTemplates.begin(),
02658                          end = mMessageTemplates.end();
02659                  iter != end; iter++)
02660         {
02661                 const LLMessageTemplate* mt = iter->second;
02662                 if(mt->mTotalDecoded > 0)
02663                 {
02664                         avg = mt->mTotalDecodeTime / (F32)mt->mTotalDecoded;
02665                         snprintf(buffer, MAX_STRING, "%35s%10u%10f%10f%10f", mt->mName, mt->mTotalDecoded, mt->mTotalDecodeTime, mt->mMaxDecodeTimePerMsg, avg);        /* Flawfinder: ignore */
02666                         str << buffer << std::endl;
02667                 }
02668         }
02669         str << "END MESSAGE LOG SUMMARY" << std::endl;
02670 }
02671 
02672 void end_messaging_system()
02673 {
02674         gTransferManager.cleanup();
02675         LLTransferTargetVFile::updateQueue(true); // shutdown LLTransferTargetVFile
02676         if (gMessageSystem)
02677         {
02678                 gMessageSystem->stopLogging();
02679 
02680                 std::ostringstream str;
02681                 gMessageSystem->summarizeLogs(str);
02682                 LL_INFOS("Messaging") << str.str().c_str() << llendl;
02683 
02684                 delete gMessageSystem;
02685                 gMessageSystem = NULL;
02686         }
02687 }
02688 
02689 void LLMessageSystem::resetReceiveCounts()
02690 {
02691         mNumMessageCounts = 0;
02692 
02693         for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(),
02694                          end = mMessageTemplates.end();
02695                  iter != end; iter++)
02696         {
02697                 LLMessageTemplate* mt = iter->second;
02698                 mt->mDecodeTimeThisFrame = 0.f;
02699         }
02700 }
02701 
02702 
02703 void LLMessageSystem::dumpReceiveCounts()
02704 {
02705         LLMessageTemplate               *mt;
02706 
02707         for (message_template_name_map_t::iterator iter = mMessageTemplates.begin(),
02708                          end = mMessageTemplates.end();
02709                  iter != end; iter++)
02710         {
02711                 LLMessageTemplate* mt = iter->second;
02712                 mt->mReceiveCount = 0;
02713                 mt->mReceiveBytes = 0;
02714                 mt->mReceiveInvalid = 0;
02715         }
02716 
02717         S32 i;
02718         for (i = 0; i < mNumMessageCounts; i++)
02719         {
02720                 mt = get_ptr_in_map(mMessageNumbers,mMessageCountList[i].mMessageNum);
02721                 if (mt)
02722                 {
02723                         mt->mReceiveCount++;
02724                         mt->mReceiveBytes += mMessageCountList[i].mMessageBytes;
02725                         if (mMessageCountList[i].mInvalid)
02726                         {
02727                                 mt->mReceiveInvalid++;
02728                         }
02729                 }
02730         }
02731 
02732         if(mNumMessageCounts > 0)
02733         {
02734                 LL_DEBUGS("Messaging") << "Dump: " << mNumMessageCounts << " messages processed in " << mReceiveTime << " seconds" << llendl;
02735                 for (message_template_name_map_t::const_iterator iter = mMessageTemplates.begin(),
02736                                  end = mMessageTemplates.end();
02737                          iter != end; iter++)
02738                 {
02739                         const LLMessageTemplate* mt = iter->second;
02740                         if (mt->mReceiveCount > 0)
02741                         {
02742                                 LL_INFOS("Messaging") << "Num: " << std::setw(3) << mt->mReceiveCount << " Bytes: " << std::setw(6) << mt->mReceiveBytes
02743                                                 << " Invalid: " << std::setw(3) << mt->mReceiveInvalid << " " << mt->mName << " " << llround(100 * mt->mDecodeTimeThisFrame / mReceiveTime) << "%" << llendl;
02744                         }
02745                 }
02746         }
02747 }
02748 
02749 
02750 
02751 BOOL LLMessageSystem::isClear() const
02752 {
02753         return mMessageBuilder->isClear();
02754 }
02755 
02756 
02757 S32 LLMessageSystem::flush(const LLHost &host)
02758 {
02759         if (mMessageBuilder->getMessageSize())
02760         {
02761                 S32 sentbytes = sendMessage(host);
02762                 clearMessage();
02763                 return sentbytes;
02764         }
02765         else
02766         {
02767                 return 0;
02768         }
02769 }
02770 
02771 U32 LLMessageSystem::getListenPort( void ) const
02772 {
02773         return mPort;
02774 }
02775 
02776 // TODO: babbage: remove this horror!
02777 S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
02778 {
02779         if(mMessageBuilder == mLLSDMessageBuilder)
02780         {
02781                 // babbage: don't compress LLSD messages, so delta is 0
02782                 return 0;
02783         }
02784         
02785         if (! mMessageBuilder->isBuilt())
02786         {
02787                 mSendSize = mMessageBuilder->buildMessage(
02788                         mSendBuffer,
02789                         MAX_BUFFER_SIZE,
02790                         0);
02791         }
02792         // TODO: babbage: remove this horror
02793         mMessageBuilder->setBuilt(FALSE);
02794 
02795         S32 count = mSendSize;
02796         
02797         S32 net_gain = 0;
02798         U8 num_zeroes = 0;
02799         
02800         U8 *inptr = (U8 *)mSendBuffer;
02801 
02802 // skip the packet id field
02803 
02804         for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii)
02805         {
02806                 count--;
02807                 inptr++;
02808         }
02809 
02810 // don't actually build, just test
02811 
02812 // sequential zero bytes are encoded as 0 [U8 count] 
02813 // with 0 0 [count] representing wrap (>256 zeroes)
02814 
02815         while (count--)
02816         {
02817                 if (!(*inptr))   // in a zero count
02818                 {
02819                         if (num_zeroes)
02820                         {
02821                                 if (++num_zeroes > 254)
02822                                 {
02823                                         num_zeroes = 0;
02824                                 }
02825                                 net_gain--;   // subseqent zeroes save one
02826                         }
02827                         else
02828                         {
02829                                 net_gain++;  // starting a zero count adds one
02830                                 num_zeroes = 1;
02831                         }
02832                         inptr++;
02833                 }
02834                 else
02835                 {
02836                         if (num_zeroes)
02837                         {
02838                                 num_zeroes = 0;
02839                         }
02840                         inptr++;
02841                 }
02842         }
02843         if (net_gain < 0)
02844         {
02845                 return net_gain;
02846         }
02847         else
02848         {
02849                 return 0;
02850         }
02851 }
02852 
02853 
02854 
02855 S32 LLMessageSystem::zeroCodeExpand(U8** data, S32* data_size)
02856 {
02857         if ((*data_size ) < LL_MINIMUM_VALID_PACKET_SIZE)
02858         {
02859                 LL_WARNS("Messaging") << "zeroCodeExpand() called with data_size of " << *data_size
02860                         << llendl;
02861         }
02862 
02863         mTotalBytesIn += *data_size;
02864 
02865         // if we're not zero-coded, simply return.
02866         if (!(*data[0] & LL_ZERO_CODE_FLAG))
02867         {
02868                 return 0;
02869         }
02870 
02871         S32 in_size = *data_size;
02872         mCompressedPacketsIn++;
02873         mCompressedBytesIn += *data_size;
02874         
02875         *data[0] &= (~LL_ZERO_CODE_FLAG);
02876 
02877         S32 count = (*data_size);  
02878         
02879         U8 *inptr = (U8 *)*data;
02880         U8 *outptr = (U8 *)mEncodedRecvBuffer;
02881 
02882 // skip the packet id field
02883 
02884         for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii)
02885         {
02886                 count--;
02887                 *outptr++ = *inptr++;
02888         }
02889 
02890 // reconstruct encoded packet, keeping track of net size gain
02891 
02892 // sequential zero bytes are encoded as 0 [U8 count] 
02893 // with 0 0 [count] representing wrap (>256 zeroes)
02894 
02895         while (count--)
02896         {
02897                 if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-1]))
02898                 {
02899                         LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 1" << llendl;
02900                         callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE);
02901                         outptr = mEncodedRecvBuffer;                                    
02902                         break;
02903                 }
02904                 if (!((*outptr++ = *inptr++)))
02905                 {
02906                         while (((count--)) && (!(*inptr)))
02907                         {
02908                                 *outptr++ = *inptr++;
02909                                 if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-256]))
02910                                 {
02911                                         LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 2" << llendl;
02912                                         callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE);
02913                                         outptr = mEncodedRecvBuffer;
02914                                         count = -1;
02915                                         break;
02916                                 }
02917                                 memset(outptr,0,255);
02918                                 outptr += 255;
02919                         }
02920                         
02921                         if (count < 0)
02922                         {
02923                                 break;
02924                         }
02925 
02926                         else
02927                         {
02928                                 if (outptr > (&mEncodedRecvBuffer[MAX_BUFFER_SIZE-(*inptr)]))
02929                                 {
02930                                         LL_WARNS("Messaging") << "attempt to write past reasonable encoded buffer size 3" << llendl;
02931                                         callExceptionFunc(MX_WROTE_PAST_BUFFER_SIZE);
02932                                         outptr = mEncodedRecvBuffer;                                    
02933                                 }
02934                                 memset(outptr,0,(*inptr) - 1);
02935                                 outptr += ((*inptr) - 1);
02936                                 inptr++;
02937                         }
02938                 }               
02939         }
02940         
02941         *data = mEncodedRecvBuffer;
02942         *data_size = (S32)(outptr - mEncodedRecvBuffer);
02943         mUncompressedBytesIn += *data_size;
02944 
02945         return(in_size);
02946 }
02947 
02948 
02949 void LLMessageSystem::addTemplate(LLMessageTemplate *templatep)
02950 {
02951         if (mMessageTemplates.count(templatep->mName) > 0)
02952         {       
02953                 LL_ERRS("Messaging") << templatep->mName << " already  used as a template name!"
02954                         << llendl;
02955         }
02956         mMessageTemplates[templatep->mName] = templatep;
02957         mMessageNumbers[templatep->mMessageNumber] = templatep;
02958 }
02959 
02960 
02961 void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data)
02962 {
02963         LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name);
02964         if (msgtemplate)
02965         {
02966                 msgtemplate->setHandlerFunc(handler_func, user_data);
02967         }
02968         else
02969         {
02970                 LL_ERRS("Messaging") << name << " is not a known message name!" << llendl;
02971         }
02972 }
02973 
02974 bool LLMessageSystem::callHandler(const char *name,
02975                 bool trustedSource, LLMessageSystem* msg)
02976 {
02977         name = LLMessageStringTable::getInstance()->getString(name);
02978         message_template_name_map_t::const_iterator iter;
02979         iter = mMessageTemplates.find(name);
02980         if(iter == mMessageTemplates.end())
02981         {
02982                 LL_WARNS("Messaging") << "LLMessageSystem::callHandler: unknown message " 
02983                         << name << llendl;
02984                 return false;
02985         }
02986 
02987         const LLMessageTemplate* msg_template = iter->second;
02988         if (msg_template->isBanned(trustedSource))
02989         {
02990                 LL_WARNS("Messaging") << "LLMessageSystem::callHandler: banned message " 
02991                         << name 
02992                         << " from "
02993                         << (trustedSource ? "trusted " : "untrusted ")
02994                         << "source" << llendl;
02995                 return false;
02996         }
02997 
02998         return msg_template->callHandlerFunc(msg);
02999 }
03000 
03001 
03002 void LLMessageSystem::setExceptionFunc(EMessageException e,
03003                                                                            msg_exception_callback func,
03004                                                                            void* data)
03005 {
03006         callbacks_t::iterator it = mExceptionCallbacks.find(e);
03007         if(it != mExceptionCallbacks.end())
03008         {
03009                 mExceptionCallbacks.erase(it);
03010         }
03011         if(func)
03012         {
03013                 mExceptionCallbacks.insert(callbacks_t::value_type(e, exception_t(func, data)));
03014         }
03015 }
03016 
03017 BOOL LLMessageSystem::callExceptionFunc(EMessageException exception)
03018 {
03019         callbacks_t::iterator it = mExceptionCallbacks.find(exception);
03020         if(it != mExceptionCallbacks.end())
03021         {
03022                 ((*it).second.first)(this, (*it).second.second,exception);
03023                 return TRUE;
03024         }
03025         return FALSE;
03026 }
03027 
03028 void LLMessageSystem::setTimingFunc(msg_timing_callback func, void* data)
03029 {
03030         mTimingCallback = func;
03031         mTimingCallbackData = data;
03032 }
03033 
03034 BOOL LLMessageSystem::isCircuitCodeKnown(U32 code) const
03035 {
03036         if(mCircuitCodes.find(code) == mCircuitCodes.end())
03037                 return FALSE;
03038         return TRUE;
03039 }
03040 
03041 BOOL LLMessageSystem::isMessageFast(const char *msg)
03042 {
03043         return msg == mMessageReader->getMessageName();
03044 }
03045 
03046 
03047 char* LLMessageSystem::getMessageName()
03048 {
03049         return const_cast<char*>(mMessageReader->getMessageName());
03050 }
03051 
03052 const LLUUID& LLMessageSystem::getSenderID() const
03053 {
03054         LLCircuitData *cdp = mCircuitInfo.findCircuit(mLastSender);
03055         if (cdp)
03056         {
03057                 return (cdp->mRemoteID);
03058         }
03059 
03060         return LLUUID::null;
03061 }
03062 
03063 const LLUUID& LLMessageSystem::getSenderSessionID() const
03064 {
03065         LLCircuitData *cdp = mCircuitInfo.findCircuit(mLastSender);
03066         if (cdp)
03067         {
03068                 return (cdp->mRemoteSessionID);
03069         }
03070         return LLUUID::null;
03071 }
03072 
03073 bool LLMessageSystem::generateDigestForNumberAndUUIDs(
03074         char* digest,
03075         const U32 number,
03076         const LLUUID& id1,
03077         const LLUUID& id2) const
03078 {
03079         // *NOTE: This method is needlessly inefficient. Instead of
03080         // calling LLUUID::asString, it should just call
03081         // LLUUID::toString().
03082 
03083         const char *colon = ":";
03084         char tbuf[16];  /* Flawfinder: ignore */ 
03085         LLMD5 d;
03086         std::string id1string = id1.asString();
03087         std::string id2string = id2.asString();
03088         std::string shared_secret = get_shared_secret();
03089         unsigned char * secret = (unsigned char*)shared_secret.c_str();
03090         unsigned char * id1str = (unsigned char*)id1string.c_str();
03091         unsigned char * id2str = (unsigned char*)id2string.c_str();
03092 
03093         memset(digest, 0, MD5HEX_STR_SIZE);
03094         
03095         if( secret != NULL)
03096         {
03097                 d.update(secret, (U32)strlen((char *) secret)); /* Flawfinder: ignore */
03098         }
03099 
03100         d.update((const unsigned char *) colon, (U32)strlen(colon));    /* Flawfinder: ignore */ 
03101         
03102         snprintf(tbuf, sizeof(tbuf),"%i", number);              /* Flawfinder: ignore */
03103         d.update((unsigned char *) tbuf, (U32)strlen(tbuf));    /* Flawfinder: ignore */ 
03104         
03105         d.update((const unsigned char *) colon, (U32)strlen(colon));    /* Flawfinder: ignore */ 
03106         if( (char*) id1str != NULL)
03107         {
03108                 d.update(id1str, (U32)strlen((char *) id1str)); /* Flawfinder: ignore */         
03109         }
03110         d.update((const unsigned char *) colon, (U32)strlen(colon));    /* Flawfinder: ignore */ 
03111         
03112         if( (char*) id2str != NULL)
03113         {
03114                 d.update(id2str, (U32)strlen((char *) id2str)); /* Flawfinder: ignore */        
03115         }
03116         
03117         d.finalize();
03118         d.hex_digest(digest);
03119         digest[MD5HEX_STR_SIZE - 1] = '\0';
03120 
03121         return true;
03122 }
03123 
03124 bool LLMessageSystem::generateDigestForWindowAndUUIDs(char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const
03125 {
03126         if(0 == window) return false;
03127         std::string shared_secret = get_shared_secret();
03128         if(shared_secret.empty())
03129         {
03130                 LL_ERRS("Messaging") << "Trying to generate complex digest on a machine without a shared secret!" << llendl;
03131         }
03132 
03133         U32 now = time(NULL);
03134 
03135         now /= window;
03136 
03137         bool result = generateDigestForNumberAndUUIDs(digest, now, id1, id2);
03138 
03139         return result;
03140 }
03141 
03142 bool LLMessageSystem::isMatchingDigestForWindowAndUUIDs(const char* digest, const S32 window, const LLUUID &id1, const LLUUID &id2) const
03143 {
03144         if(0 == window) return false;
03145 
03146         std::string shared_secret = get_shared_secret();
03147         if(shared_secret.empty())
03148         {
03149                 LL_ERRS("Messaging") << "Trying to compare complex digests on a machine without a shared secret!" << llendl;
03150         }
03151         
03152         char our_digest[MD5HEX_STR_SIZE];       /* Flawfinder: ignore */
03153         U32 now = time(NULL);
03154 
03155         now /= window;
03156 
03157         // Check 1 window ago, now, and one window from now to catch edge
03158         // conditions. Process them as current window, one window ago, and
03159         // one window in the future to catch the edges.
03160         const S32 WINDOW_BIN_COUNT = 3;
03161         U32 window_bin[WINDOW_BIN_COUNT];
03162         window_bin[0] = now;
03163         window_bin[1] = now - 1;
03164         window_bin[2] = now + 1;
03165         for(S32 i = 0; i < WINDOW_BIN_COUNT; ++i)
03166         {
03167                 generateDigestForNumberAndUUIDs(our_digest, window_bin[i], id2, id1);
03168                 if(0 == strncmp(digest, our_digest, MD5HEX_STR_BYTES))
03169                 {
03170                         return true;
03171                 }
03172         }
03173         return false;
03174 }
03175 
03176 bool LLMessageSystem::generateDigestForNumber(char* digest, const U32 number) const
03177 {
03178         memset(digest, 0, MD5HEX_STR_SIZE);
03179 
03180         LLMD5 d;
03181         std::string shared_secret = get_shared_secret();
03182         d = LLMD5((const unsigned char *)shared_secret.c_str(), number);
03183         d.hex_digest(digest);
03184         digest[MD5HEX_STR_SIZE - 1] = '\0';
03185 
03186         return true;
03187 }
03188 
03189 bool LLMessageSystem::generateDigestForWindow(char* digest, const S32 window) const
03190 {
03191         if(0 == window) return false;
03192 
03193         std::string shared_secret = get_shared_secret();
03194         if(shared_secret.empty())
03195         {
03196                 LL_ERRS("Messaging") << "Trying to generate simple digest on a machine without a shared secret!" << llendl;
03197         }
03198 
03199         U32 now = time(NULL);
03200 
03201         now /= window;
03202 
03203         bool result = generateDigestForNumber(digest, now);
03204 
03205         return result;
03206 }
03207 
03208 bool LLMessageSystem::isMatchingDigestForWindow(const char* digest, S32 const window) const
03209 {
03210         if(0 == window) return false;
03211 
03212         std::string shared_secret = get_shared_secret();
03213         if(shared_secret.empty())
03214         {
03215                 LL_ERRS("Messaging") << "Trying to compare simple digests on a machine without a shared secret!" << llendl;
03216         }
03217         
03218         char our_digest[MD5HEX_STR_SIZE];       /* Flawfinder: ignore */
03219         U32 now = (S32)time(NULL);
03220 
03221         now /= window;
03222 
03223         // Check 1 window ago, now, and one window from now to catch edge
03224         // conditions. Process them as current window, one window ago, and
03225         // one window in the future to catch the edges.
03226         const S32 WINDOW_BIN_COUNT = 3;
03227         U32 window_bin[WINDOW_BIN_COUNT];
03228         window_bin[0] = now;
03229         window_bin[1] = now - 1;
03230         window_bin[2] = now + 1;
03231         for(S32 i = 0; i < WINDOW_BIN_COUNT; ++i)
03232         {
03233                 generateDigestForNumber(our_digest, window_bin[i]);
03234                 if(0 == strncmp(digest, our_digest, MD5HEX_STR_BYTES))
03235                 {
03236                         return true;
03237                 }
03238         }
03239         return false;
03240 }
03241 
03242 void LLMessageSystem::sendCreateTrustedCircuit(const LLHost &host, const LLUUID & id1, const LLUUID & id2)
03243 {
03244         std::string shared_secret = get_shared_secret();
03245         if(shared_secret.empty()) return;
03246         char digest[MD5HEX_STR_SIZE];   /* Flawfinder: ignore */
03247         if (id1.isNull())
03248         {
03249                 LL_WARNS("Messaging") << "Can't send CreateTrustedCircuit to " << host << " because we don't have the local end point ID" << llendl;
03250                 return;
03251         }
03252         if (id2.isNull())
03253         {
03254                 LL_WARNS("Messaging") << "Can't send CreateTrustedCircuit to " << host << " because we don't have the remote end point ID" << llendl;
03255                 return;
03256         }
03257         generateDigestForWindowAndUUIDs(digest, TRUST_TIME_WINDOW, id1, id2);
03258         newMessageFast(_PREHASH_CreateTrustedCircuit);
03259         nextBlockFast(_PREHASH_DataBlock);
03260         addUUIDFast(_PREHASH_EndPointID, id1);
03261         addBinaryDataFast(_PREHASH_Digest, digest, MD5HEX_STR_BYTES);
03262         LL_INFOS("Messaging") << "xmitting digest: " << digest << " Host: " << host << llendl;
03263         sendMessage(host);
03264 }
03265 
03266 void LLMessageSystem::sendDenyTrustedCircuit(const LLHost &host)
03267 {
03268         mDenyTrustedCircuitSet.insert(host);
03269 }
03270 
03271 void LLMessageSystem::reallySendDenyTrustedCircuit(const LLHost &host)
03272 {
03273         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
03274         if (!cdp)
03275         {
03276                 LL_WARNS("Messaging") << "Not sending DenyTrustedCircuit to host without a circuit." << llendl;
03277                 return;
03278         }
03279         LL_INFOS("Messaging") << "Sending DenyTrustedCircuit to " << host << llendl;
03280         newMessageFast(_PREHASH_DenyTrustedCircuit);
03281         nextBlockFast(_PREHASH_DataBlock);
03282         addUUIDFast(_PREHASH_EndPointID, cdp->getLocalEndPointID());
03283         sendMessage(host);
03284 }
03285 
03286 void null_message_callback(LLMessageSystem *msg, void **data)
03287 {
03288         // Nothing should ever go here, but we use this to register messages
03289         // that we are expecting to see (and spinning on) at startup.
03290         return;
03291 }
03292 
03293 // Try to establish a bidirectional trust metric by pinging a host until it's
03294 // up, and then sending auth messages.
03295 void LLMessageSystem::establishBidirectionalTrust(const LLHost &host, S64 frame_count )
03296 {
03297         std::string shared_secret = get_shared_secret();
03298         if(shared_secret.empty())
03299         {
03300                 LL_ERRS("Messaging") << "Trying to establish bidirectional trust on a machine without a shared secret!" << llendl;
03301         }
03302         LLTimer timeout;
03303 
03304         timeout.setTimerExpirySec(20.0);
03305         setHandlerFuncFast(_PREHASH_StartPingCheck, null_message_callback, NULL);
03306         setHandlerFuncFast(_PREHASH_CompletePingCheck, null_message_callback,
03307                        NULL);
03308 
03309         while (! timeout.hasExpired())
03310         {
03311                 newMessageFast(_PREHASH_StartPingCheck);
03312                 nextBlockFast(_PREHASH_PingID);
03313                 addU8Fast(_PREHASH_PingID, 0);
03314                 addU32Fast(_PREHASH_OldestUnacked, 0);
03315                 sendMessage(host);
03316                 if (checkMessages( frame_count ))
03317                 {
03318                         if (isMessageFast(_PREHASH_CompletePingCheck) &&
03319                             (getSender() == host))
03320                         {
03321                                 break;
03322                         }
03323                 }
03324                 processAcks();
03325                 ms_sleep(1);
03326         }
03327 
03328         // Send a request, a deny, and give the host 2 seconds to complete
03329         // the trust handshake.
03330         newMessage("RequestTrustedCircuit");
03331         sendMessage(host);
03332         reallySendDenyTrustedCircuit(host);
03333         setHandlerFuncFast(_PREHASH_StartPingCheck, process_start_ping_check, NULL);
03334         setHandlerFuncFast(_PREHASH_CompletePingCheck, process_complete_ping_check, NULL);
03335 
03336         timeout.setTimerExpirySec(2.0);
03337         LLCircuitData* cdp = NULL;
03338         while(!timeout.hasExpired())
03339         {
03340                 cdp = mCircuitInfo.findCircuit(host);
03341                 if(!cdp) break; // no circuit anymore, no point continuing.
03342                 if(cdp->getTrusted()) break; // circuit is trusted.
03343                 checkMessages(frame_count);
03344                 processAcks();
03345                 ms_sleep(1);
03346         }
03347 }
03348 
03349 
03350 void LLMessageSystem::dumpPacketToLog()
03351 {
03352         LL_WARNS("Messaging") << "Packet Dump from:" << mPacketRing.getLastSender() << llendl;
03353         LL_WARNS("Messaging") << "Packet Size:" << mTrueReceiveSize << llendl;
03354         char line_buffer[256];          /* Flawfinder: ignore */
03355         S32 i;
03356         S32 cur_line_pos = 0;
03357         S32 cur_line = 0;
03358 
03359         for (i = 0; i < mTrueReceiveSize; i++)
03360         {
03361                 S32 offset = cur_line_pos * 3;
03362                 snprintf(line_buffer + offset, sizeof(line_buffer) - offset,
03363                                  "%02x ", mTrueReceiveBuffer[i]);       /* Flawfinder: ignore */
03364                 cur_line_pos++;
03365                 if (cur_line_pos >= 16)
03366                 {
03367                         cur_line_pos = 0;
03368                         LL_WARNS("Messaging") << "PD:" << cur_line << "PD:" << line_buffer << llendl;
03369                         cur_line++;
03370                 }
03371         }
03372         if (cur_line_pos)
03373         {
03374                 LL_WARNS("Messaging") << "PD:" << cur_line << "PD:" << line_buffer << llendl;
03375         }
03376 }
03377 
03378 
03379 //static
03380 U64 LLMessageSystem::getMessageTimeUsecs(const BOOL update)
03381 {
03382         if (gMessageSystem)
03383         {
03384                 if (update)
03385                 {
03386                         gMessageSystem->mCurrentMessageTimeSeconds = totalTime()*SEC_PER_USEC;
03387                 }
03388                 return (U64)(gMessageSystem->mCurrentMessageTimeSeconds * USEC_PER_SEC);
03389         }
03390         else
03391         {
03392                 return totalTime();
03393         }
03394 }
03395 
03396 //static
03397 F64 LLMessageSystem::getMessageTimeSeconds(const BOOL update)
03398 {
03399         if (gMessageSystem)
03400         {
03401                 if (update)
03402                 {
03403                         gMessageSystem->mCurrentMessageTimeSeconds = totalTime()*SEC_PER_USEC;
03404                 }
03405                 return gMessageSystem->mCurrentMessageTimeSeconds;
03406         }
03407         else
03408         {
03409                 return totalTime()*SEC_PER_USEC;
03410         }
03411 }
03412 
03413 std::string get_shared_secret()
03414 {
03415         static const std::string SHARED_SECRET_KEY("shared_secret");
03416         if(g_shared_secret.empty())
03417         {
03418                 LLApp* app = LLApp::instance();
03419                 if(app) return app->getOption(SHARED_SECRET_KEY);
03420         }
03421         return g_shared_secret;
03422 }
03423 
03424 typedef std::map<const char*, LLMessageBuilder*> BuilderMap;
03425 
03426 void LLMessageSystem::newMessageFast(const char *name)
03427 {
03428         LLMessageConfig::Flavor message_flavor =
03429                 LLMessageConfig::getMessageFlavor(name);
03430         LLMessageConfig::Flavor server_flavor =
03431                 LLMessageConfig::getServerDefaultFlavor();
03432 
03433         if(message_flavor == LLMessageConfig::TEMPLATE_FLAVOR)
03434         {
03435                 mMessageBuilder = mTemplateMessageBuilder;
03436         }
03437         else if (message_flavor == LLMessageConfig::LLSD_FLAVOR)
03438         {
03439                 mMessageBuilder = mLLSDMessageBuilder;
03440         }
03441         // NO_FLAVOR
03442         else
03443         {
03444                 if (server_flavor == LLMessageConfig::LLSD_FLAVOR)
03445                 {
03446                         mMessageBuilder = mLLSDMessageBuilder;
03447                 }
03448                 // TEMPLATE_FLAVOR or NO_FLAVOR
03449                 else
03450                 {
03451                         mMessageBuilder = mTemplateMessageBuilder;
03452                 }
03453         }
03454         mSendReliable = FALSE;
03455         mMessageBuilder->newMessage(name);
03456 }
03457         
03458 void LLMessageSystem::newMessage(const char *name)
03459 {
03460         newMessageFast(LLMessageStringTable::getInstance()->getString(name));
03461 }
03462 
03463 void LLMessageSystem::addBinaryDataFast(const char *varname, const void *data, S32 size)
03464 {
03465         mMessageBuilder->addBinaryData(varname, data, size);
03466 }
03467 
03468 void LLMessageSystem::addBinaryData(const char *varname, const void *data, S32 size)
03469 {
03470         mMessageBuilder->addBinaryData(LLMessageStringTable::getInstance()->getString(varname),data, size);
03471 }
03472 
03473 void LLMessageSystem::addS8Fast(const char *varname, S8 v)
03474 {
03475         mMessageBuilder->addS8(varname, v);
03476 }
03477 
03478 void LLMessageSystem::addS8(const char *varname, S8 v)
03479 {
03480         mMessageBuilder->addS8(LLMessageStringTable::getInstance()->getString(varname), v);
03481 }
03482 
03483 void LLMessageSystem::addU8Fast(const char *varname, U8 v)
03484 {
03485         mMessageBuilder->addU8(varname, v);
03486 }
03487 
03488 void LLMessageSystem::addU8(const char *varname, U8 v)
03489 {
03490         mMessageBuilder->addU8(LLMessageStringTable::getInstance()->getString(varname), v);
03491 }
03492 
03493 void LLMessageSystem::addS16Fast(const char *varname, S16 v)
03494 {
03495         mMessageBuilder->addS16(varname, v);
03496 }
03497 
03498 void LLMessageSystem::addS16(const char *varname, S16 v)
03499 {
03500         mMessageBuilder->addS16(LLMessageStringTable::getInstance()->getString(varname), v);
03501 }
03502 
03503 void LLMessageSystem::addU16Fast(const char *varname, U16 v)
03504 {
03505         mMessageBuilder->addU16(varname, v);
03506 }
03507 
03508 void LLMessageSystem::addU16(const char *varname, U16 v)
03509 {
03510         mMessageBuilder->addU16(LLMessageStringTable::getInstance()->getString(varname), v);
03511 }
03512 
03513 void LLMessageSystem::addF32Fast(const char *varname, F32 v)
03514 {
03515         mMessageBuilder->addF32(varname, v);
03516 }
03517 
03518 void LLMessageSystem::addF32(const char *varname, F32 v)
03519 {
03520         mMessageBuilder->addF32(LLMessageStringTable::getInstance()->getString(varname), v);
03521 }
03522 
03523 void LLMessageSystem::addS32Fast(const char *varname, S32 v)
03524 {
03525         mMessageBuilder->addS32(varname, v);
03526 }
03527 
03528 void LLMessageSystem::addS32(const char *varname, S32 v)
03529 {
03530         mMessageBuilder->addS32(LLMessageStringTable::getInstance()->getString(varname), v);
03531 }
03532 
03533 void LLMessageSystem::addU32Fast(const char *varname, U32 v)
03534 {
03535         mMessageBuilder->addU32(varname, v);
03536 }
03537 
03538 void LLMessageSystem::addU32(const char *varname, U32 v)
03539 {
03540         mMessageBuilder->addU32(LLMessageStringTable::getInstance()->getString(varname), v);
03541 }
03542 
03543 void LLMessageSystem::addU64Fast(const char *varname, U64 v)
03544 {
03545         mMessageBuilder->addU64(varname, v);
03546 }
03547 
03548 void LLMessageSystem::addU64(const char *varname, U64 v)
03549 {
03550         mMessageBuilder->addU64(LLMessageStringTable::getInstance()->getString(varname), v);
03551 }
03552 
03553 void LLMessageSystem::addF64Fast(const char *varname, F64 v)
03554 {
03555         mMessageBuilder->addF64(varname, v);
03556 }
03557 
03558 void LLMessageSystem::addF64(const char *varname, F64 v)
03559 {
03560         mMessageBuilder->addF64(LLMessageStringTable::getInstance()->getString(varname), v);
03561 }
03562 
03563 void LLMessageSystem::addIPAddrFast(const char *varname, U32 v)
03564 {
03565         mMessageBuilder->addIPAddr(varname, v);
03566 }
03567 
03568 void LLMessageSystem::addIPAddr(const char *varname, U32 v)
03569 {
03570         mMessageBuilder->addIPAddr(LLMessageStringTable::getInstance()->getString(varname), v);
03571 }
03572 
03573 void LLMessageSystem::addIPPortFast(const char *varname, U16 v)
03574 {
03575         mMessageBuilder->addIPPort(varname, v);
03576 }
03577 
03578 void LLMessageSystem::addIPPort(const char *varname, U16 v)
03579 {
03580         mMessageBuilder->addIPPort(LLMessageStringTable::getInstance()->getString(varname), v);
03581 }
03582 
03583 void LLMessageSystem::addBOOLFast(const char* varname, BOOL v)
03584 {
03585         mMessageBuilder->addBOOL(varname, v);
03586 }
03587 
03588 void LLMessageSystem::addBOOL(const char* varname, BOOL v)
03589 {
03590         mMessageBuilder->addBOOL(LLMessageStringTable::getInstance()->getString(varname), v);
03591 }
03592 
03593 void LLMessageSystem::addStringFast(const char* varname, const char* v)
03594 {
03595         mMessageBuilder->addString(varname, v);
03596 }
03597 
03598 void LLMessageSystem::addString(const char* varname, const char* v)
03599 {
03600         mMessageBuilder->addString(LLMessageStringTable::getInstance()->getString(varname), v);
03601 }
03602 
03603 void LLMessageSystem::addStringFast(const char* varname, const std::string& v)
03604 {
03605         mMessageBuilder->addString(varname, v);
03606 }
03607 
03608 void LLMessageSystem::addString(const char* varname, const std::string& v)
03609 {
03610         mMessageBuilder->addString(LLMessageStringTable::getInstance()->getString(varname), v);
03611 }
03612 
03613 void LLMessageSystem::addVector3Fast(const char *varname, const LLVector3& v)
03614 {
03615         mMessageBuilder->addVector3(varname, v);
03616 }
03617 
03618 void LLMessageSystem::addVector3(const char *varname, const LLVector3& v)
03619 {
03620         mMessageBuilder->addVector3(LLMessageStringTable::getInstance()->getString(varname), v);
03621 }
03622 
03623 void LLMessageSystem::addVector4Fast(const char *varname, const LLVector4& v)
03624 {
03625         mMessageBuilder->addVector4(varname, v);
03626 }
03627 
03628 void LLMessageSystem::addVector4(const char *varname, const LLVector4& v)
03629 {
03630         mMessageBuilder->addVector4(LLMessageStringTable::getInstance()->getString(varname), v);
03631 }
03632 
03633 void LLMessageSystem::addVector3dFast(const char *varname, const LLVector3d& v)
03634 {
03635         mMessageBuilder->addVector3d(varname, v);
03636 }
03637 
03638 void LLMessageSystem::addVector3d(const char *varname, const LLVector3d& v)
03639 {
03640         mMessageBuilder->addVector3d(LLMessageStringTable::getInstance()->getString(varname), v);
03641 }
03642 
03643 void LLMessageSystem::addQuatFast(const char *varname, const LLQuaternion& v)
03644 {
03645         mMessageBuilder->addQuat(varname, v);
03646 }
03647 
03648 void LLMessageSystem::addQuat(const char *varname, const LLQuaternion& v)
03649 {
03650         mMessageBuilder->addQuat(LLMessageStringTable::getInstance()->getString(varname), v);
03651 }
03652 
03653 
03654 void LLMessageSystem::addUUIDFast(const char *varname, const LLUUID& v)
03655 {
03656         mMessageBuilder->addUUID(varname, v);
03657 }
03658 
03659 void LLMessageSystem::addUUID(const char *varname, const LLUUID& v)
03660 {
03661         mMessageBuilder->addUUID(LLMessageStringTable::getInstance()->getString(varname), v);
03662 }
03663 
03664 S32 LLMessageSystem::getCurrentSendTotal() const
03665 {
03666         return mMessageBuilder->getMessageSize();
03667 }
03668 
03669 void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u, 
03670                                                                 S32 blocknum)
03671 {
03672         mMessageReader->getS8(block, var, u, blocknum);
03673 }
03674 
03675 void LLMessageSystem::getS8(const char *block, const char *var, S8 &u, 
03676                                                         S32 blocknum)
03677 {
03678         getS8Fast(LLMessageStringTable::getInstance()->getString(block), 
03679                           LLMessageStringTable::getInstance()->getString(var), u, blocknum);
03680 }
03681 
03682 void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u, 
03683                                                                 S32 blocknum)
03684 {
03685         mMessageReader->getU8(block, var, u, blocknum);
03686 }
03687 
03688 void LLMessageSystem::getU8(const char *block, const char *var, U8 &u, 
03689                                                         S32 blocknum)
03690 {
03691         getU8Fast(LLMessageStringTable::getInstance()->getString(block), 
03692                                 LLMessageStringTable::getInstance()->getString(var), u, blocknum);
03693 }
03694 
03695 void LLMessageSystem::getBOOLFast(const char *block, const char *var, BOOL &b,
03696                                                                   S32 blocknum)
03697 {
03698         mMessageReader->getBOOL(block, var, b, blocknum);
03699 }
03700 
03701 void LLMessageSystem::getBOOL(const char *block, const char *var, BOOL &b, 
03702                                                           S32 blocknum)
03703 {
03704         getBOOLFast(LLMessageStringTable::getInstance()->getString(block), 
03705                                 LLMessageStringTable::getInstance()->getString(var), b, blocknum);
03706 }
03707 
03708 void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d, 
03709                                                                  S32 blocknum)
03710 {
03711         mMessageReader->getS16(block, var, d, blocknum);
03712 }
03713 
03714 void LLMessageSystem::getS16(const char *block, const char *var, S16 &d, 
03715                                                          S32 blocknum)
03716 {
03717         getS16Fast(LLMessageStringTable::getInstance()->getString(block), 
03718                            LLMessageStringTable::getInstance()->getString(var), d, blocknum);
03719 }
03720 
03721 void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d, 
03722                                                                  S32 blocknum)
03723 {
03724         mMessageReader->getU16(block, var, d, blocknum);
03725 }
03726 
03727 void LLMessageSystem::getU16(const char *block, const char *var, U16 &d, 
03728                                                          S32 blocknum)
03729 {
03730         getU16Fast(LLMessageStringTable::getInstance()->getString(block), 
03731                            LLMessageStringTable::getInstance()->getString(var), d, blocknum);
03732 }
03733 
03734 void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d, 
03735                                                                  S32 blocknum)
03736 {
03737         mMessageReader->getS32(block, var, d, blocknum);
03738 }
03739 
03740 void LLMessageSystem::getS32(const char *block, const char *var, S32 &d, 
03741                                                          S32 blocknum)
03742 {
03743         getS32Fast(LLMessageStringTable::getInstance()->getString(block), 
03744                            LLMessageStringTable::getInstance()->getString(var), d, blocknum);
03745 }
03746 
03747 void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d, 
03748                                                                  S32 blocknum)
03749 {
03750         mMessageReader->getU32(block, var, d, blocknum);
03751 }
03752 
03753 void LLMessageSystem::getU32(const char *block, const char *var, U32 &d, 
03754                                                          S32 blocknum)
03755 {
03756         getU32Fast(LLMessageStringTable::getInstance()->getString(block), 
03757                                 LLMessageStringTable::getInstance()->getString(var), d, blocknum);
03758 }
03759 
03760 void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d, 
03761                                                                  S32 blocknum)
03762 {
03763         mMessageReader->getU64(block, var, d, blocknum);
03764 }
03765 
03766 void LLMessageSystem::getU64(const char *block, const char *var, U64 &d, 
03767                                                          S32 blocknum)
03768 {
03769         
03770         getU64Fast(LLMessageStringTable::getInstance()->getString(block), 
03771                            LLMessageStringTable::getInstance()->getString(var), d, blocknum);
03772 }
03773 
03774 void LLMessageSystem::getBinaryDataFast(const char *blockname, 
03775                                                                                 const char *varname, 
03776                                                                                 void *datap, S32 size, 
03777                                                                                 S32 blocknum, S32 max_size)
03778 {
03779         mMessageReader->getBinaryData(blockname, varname, datap, size, blocknum, 
03780                                                                   max_size);
03781 }
03782 
03783 void LLMessageSystem::getBinaryData(const char *blockname, 
03784                                                                         const char *varname, 
03785                                                                         void *datap, S32 size, 
03786                                                                         S32 blocknum, S32 max_size)
03787 {
03788         getBinaryDataFast(LLMessageStringTable::getInstance()->getString(blockname), 
03789                                           LLMessageStringTable::getInstance()->getString(varname), 
03790                                           datap, size, blocknum, max_size);
03791 }
03792 
03793 void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d, 
03794                                                                  S32 blocknum)
03795 {
03796         mMessageReader->getF32(block, var, d, blocknum);
03797 }
03798 
03799 void LLMessageSystem::getF32(const char *block, const char *var, F32 &d, 
03800                                                          S32 blocknum)
03801 {
03802         getF32Fast(LLMessageStringTable::getInstance()->getString(block), 
03803                            LLMessageStringTable::getInstance()->getString(var), d, blocknum);
03804 }
03805 
03806 void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d, 
03807                                                                  S32 blocknum)
03808 {
03809         mMessageReader->getF64(block, var, d, blocknum);
03810 }
03811 
03812 void LLMessageSystem::getF64(const char *block, const char *var, F64 &d, 
03813                                                          S32 blocknum)
03814 {
03815         getF64Fast(LLMessageStringTable::getInstance()->getString(block), 
03816                                 LLMessageStringTable::getInstance()->getString(var), d, blocknum);
03817 }
03818 
03819 
03820 void LLMessageSystem::getVector3Fast(const char *block, const char *var, 
03821                                                                          LLVector3 &v, S32 blocknum )
03822 {
03823         mMessageReader->getVector3(block, var, v, blocknum);
03824 }
03825 
03826 void LLMessageSystem::getVector3(const char *block, const char *var, 
03827                                                                  LLVector3 &v, S32 blocknum )
03828 {
03829         getVector3Fast(LLMessageStringTable::getInstance()->getString(block), 
03830                                    LLMessageStringTable::getInstance()->getString(var), v, blocknum);
03831 }
03832 
03833 void LLMessageSystem::getVector4Fast(const char *block, const char *var, 
03834                                                                          LLVector4 &v, S32 blocknum )
03835 {
03836         mMessageReader->getVector4(block, var, v, blocknum);
03837 }
03838 
03839 void LLMessageSystem::getVector4(const char *block, const char *var, 
03840                                                                  LLVector4 &v, S32 blocknum )
03841 {
03842         getVector4Fast(LLMessageStringTable::getInstance()->getString(block), 
03843                                    LLMessageStringTable::getInstance()->getString(var), v, blocknum);
03844 }
03845 
03846 void LLMessageSystem::getVector3dFast(const char *block, const char *var, 
03847                                                                           LLVector3d &v, S32 blocknum )
03848 {
03849         mMessageReader->getVector3d(block, var, v, blocknum);
03850 }
03851 
03852 void LLMessageSystem::getVector3d(const char *block, const char *var, 
03853                                                                   LLVector3d &v, S32 blocknum )
03854 {
03855         getVector3dFast(LLMessageStringTable::getInstance()->getString(block), 
03856                                 LLMessageStringTable::getInstance()->getString(var), v, blocknum);
03857 }
03858 
03859 void LLMessageSystem::getQuatFast(const char *block, const char *var, 
03860                                                                   LLQuaternion &q, S32 blocknum )
03861 {
03862         mMessageReader->getQuat(block, var, q, blocknum);
03863 }
03864 
03865 void LLMessageSystem::getQuat(const char *block, const char *var, 
03866                                                           LLQuaternion &q, S32 blocknum)
03867 {
03868         getQuatFast(LLMessageStringTable::getInstance()->getString(block), 
03869                         LLMessageStringTable::getInstance()->getString(var), q, blocknum);
03870 }
03871 
03872 void LLMessageSystem::getUUIDFast(const char *block, const char *var, 
03873                                                                   LLUUID &u, S32 blocknum )
03874 {
03875         mMessageReader->getUUID(block, var, u, blocknum);
03876 }
03877 
03878 void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u, 
03879                                                           S32 blocknum )
03880 {
03881         getUUIDFast(LLMessageStringTable::getInstance()->getString(block), 
03882                                 LLMessageStringTable::getInstance()->getString(var), u, blocknum);
03883 }
03884 
03885 void LLMessageSystem::getIPAddrFast(const char *block, const char *var, 
03886                                                                         U32 &u, S32 blocknum)
03887 {
03888         mMessageReader->getIPAddr(block, var, u, blocknum);
03889 }
03890 
03891 void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u, 
03892                                                                 S32 blocknum)
03893 {
03894         getIPAddrFast(LLMessageStringTable::getInstance()->getString(block), 
03895                                   LLMessageStringTable::getInstance()->getString(var), u, blocknum);
03896 }
03897 
03898 void LLMessageSystem::getIPPortFast(const char *block, const char *var, 
03899                                                                         U16 &u, S32 blocknum)
03900 {
03901         mMessageReader->getIPPort(block, var, u, blocknum);
03902 }
03903 
03904 void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u, 
03905                                                                 S32 blocknum)
03906 {
03907         getIPPortFast(LLMessageStringTable::getInstance()->getString(block), 
03908                                   LLMessageStringTable::getInstance()->getString(var), u, 
03909                                   blocknum);
03910 }
03911 
03912 
03913 void LLMessageSystem::getStringFast(const char *block, const char *var, 
03914                                                                         S32 buffer_size, char *s, S32 blocknum)
03915 {
03916         if(buffer_size <= 0)
03917         {
03918                 LL_WARNS("Messaging") << "buffer_size <= 0" << llendl;
03919         }
03920         mMessageReader->getString(block, var, buffer_size, s, blocknum);
03921 }
03922 
03923 void LLMessageSystem::getString(const char *block, const char *var, 
03924                                                                 S32 buffer_size, char *s, S32 blocknum )
03925 {
03926         getStringFast(LLMessageStringTable::getInstance()->getString(block), 
03927                                   LLMessageStringTable::getInstance()->getString(var), buffer_size, s, 
03928                                   blocknum);
03929 }
03930 
03931 S32     LLMessageSystem::getNumberOfBlocksFast(const char *blockname)
03932 {
03933         return mMessageReader->getNumberOfBlocks(blockname);
03934 }
03935 
03936 S32     LLMessageSystem::getNumberOfBlocks(const char *blockname)
03937 {
03938         return getNumberOfBlocksFast(LLMessageStringTable::getInstance()->getString(blockname));
03939 }
03940         
03941 S32     LLMessageSystem::getSizeFast(const char *blockname, const char *varname)
03942 {
03943         return mMessageReader->getSize(blockname, varname);
03944 }
03945 
03946 S32     LLMessageSystem::getSize(const char *blockname, const char *varname)
03947 {
03948         return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), 
03949                                            LLMessageStringTable::getInstance()->getString(varname));
03950 }
03951         
03952 // size in bytes of variable length data
03953 S32     LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum, 
03954                                                                  const char *varname)
03955 {
03956         return mMessageReader->getSize(blockname, blocknum, varname);
03957 }
03958                 
03959 S32     LLMessageSystem::getSize(const char *blockname, S32 blocknum, 
03960                                                          const char *varname)
03961 {
03962         return getSizeFast(LLMessageStringTable::getInstance()->getString(blockname), blocknum, 
03963                                            LLMessageStringTable::getInstance()->getString(varname));
03964 }
03965 
03966 S32 LLMessageSystem::getReceiveSize() const
03967 {
03968         return mMessageReader->getMessageSize();
03969 }
03970 
03971 //static 
03972 void LLMessageSystem::setTimeDecodes( BOOL b )
03973 {
03974         LLMessageReader::setTimeDecodes(b);
03975 }
03976                 
03977 //static 
03978 void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds )
03979 { 
03980         LLMessageReader::setTimeDecodesSpamThreshold(seconds);
03981 }
03982 
03983 // HACK! babbage: return true if message rxed via either UDP or HTTP
03984 // TODO: babbage: move gServicePump in to LLMessageSystem?
03985 bool LLMessageSystem::checkAllMessages(S64 frame_count, LLPumpIO* http_pump)
03986 {
03987         if(checkMessages(frame_count))
03988         {
03989                 return true;
03990         }
03991         U32 packetsIn = mPacketsIn;
03992         http_pump->pump();
03993         http_pump->callback();
03994         return (mPacketsIn - packetsIn) > 0;
03995 }

Generated on Fri May 16 08:32:36 2008 for SecondLife by  doxygen 1.5.5