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

Generated on Thu Jul 1 06:09:55 2010 for Second Life Viewer by  doxygen 1.4.7