00001 
00032 #include "linden_common.h"
00033 
00034 #include "message.h"
00035 
00036 
00037 #if !LL_WINDOWS
00038 
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 
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 
00087 
00088 static const F32 CIRCUIT_DUMP_TIMEOUT = 30.f;
00089 static const S32 TRUST_TIME_WINDOW = 3;
00090 
00091 
00092 
00093 
00094 
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                         
00121                         if (status != 410)
00122                         {
00123                                 llwarns << "error status " << status
00124                                                 << " for message " << mMessageName
00125                                                 << " reason " << reason << llendl;
00126                         }
00127                         
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 
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         
00171         
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 
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 
00229 LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder()
00230 {
00231         
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         
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;            
00269     mResentPackets = 0;             
00270     mFailedResendPackets = 0;       
00271     mOffCircuitPackets = 0;         
00272     mInvalidOnCircuitPackets = 0;   
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 
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         
00303         mbProtected = TRUE;
00304 
00305         mSendPacketFailureCount = 0;
00306 
00307         mCircuitPrintFreq = 60.f;               
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         
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         
00330 
00331         
00332         
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         
00358         mNumMessageCounts = 0;
00359         mMaxMessageCounts = 200; 
00360         mMaxMessageTime   = 1.f;
00361 
00362         mTrueReceiveSize = 0;
00363 }
00364 
00365 
00366 
00367 
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(); 
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                 
00500                 
00501                 
00502                 if (mbProtected)
00503                 {
00504                         
00505                 }
00506                 else
00507                 {
00508                         
00509                         cdp = mCircuitInfo.addCircuitData(host, mCurrentRecvPacketID);
00510 
00511                         if(resetPacketId)
00512                         {
00513                                 
00514                                 
00515                                 cdp->setPacketInID(mCurrentRecvPacketID);
00516                         }
00517                         
00518                 }
00519         }
00520         else
00521         {
00522                 
00523                 if (!cdp->isAlive())
00524                 {
00525                         
00526                         if (mbProtected)
00527                         {
00528                                 
00529                                 cdp = NULL;
00530                         }
00531                         else
00532                         {
00533                                 
00534                                 cdp->setAlive(TRUE);
00535                                 
00536                                 if(resetPacketId)
00537                                 {
00538                                         
00539                                         cdp->setPacketInID(mCurrentRecvPacketID);
00540                                 }
00541                         }
00542                 }
00543         }
00544         return cdp;
00545 }
00546 
00547 
00548 BOOL LLMessageSystem::checkMessages( S64 frame_count )
00549 {
00550         
00551         BOOL    valid_packet = FALSE;
00552         mMessageReader = mTemplateMessageReader;
00553 
00554         LLTransferTargetVFile::updateQueue();
00555         
00556         if (!mNumMessageCounts)
00557         {
00558                 
00559                 
00560                 mCurrentMessageTimeSeconds = totalTime() * SEC_PER_USEC;
00561                 mMessageCountTime = getMessageTimeSeconds();
00562         }
00563 
00564         
00565         
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                 
00580                 
00581                 
00582                 receive_size = mTrueReceiveSize;
00583                 mLastSender = mPacketRing.getLastSender();
00584                 
00585                 if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE)
00586                 {
00587                         
00588                         
00589                         if (receive_size > 0)
00590                         {
00591                                 llwarns << "Invalid (too short) packet discarded " << receive_size << llendl;
00592                                 callExceptionFunc(MX_PACKET_TOO_SHORT);
00593                         }
00594                         
00595                         valid_packet = FALSE;
00596                 }
00597                 else
00598                 {
00599                         LLHost host;
00600                         LLCircuitData* cdp;
00601                         
00602                         
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                                         
00614                                         
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                         
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                         
00632                         
00633                         
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], 
00643                                              sizeof(TPACKETID));
00644                                         packet_id = ntohl(mem_id);
00645                                         
00646                                         cdp->ackReliablePacket(packet_id);
00647                                 }
00648                                 if (!cdp->getUnackedPacketCount())
00649                                 {
00650                                         
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                                         
00665                                         
00666                                         
00667                                         if (recv_reliable)
00668                                         {
00669                                                 
00670                                                 
00671                                                 
00672                                                 
00673                                                 
00674                                                 
00675                                                 
00676                                                 
00677                                                 
00678                                                 
00679                                                 
00680                                                 
00681                                                 cdp->collectRAck(mCurrentRecvPacketID);
00682                                         }
00683                                                                  
00684                                         
00685                                         if(mVerboseLog)
00686                                         {
00687                                                 std::ostringstream str;
00688                                                 str << "MSG: <- " << host;
00689                                                 char buffer[MAX_STRING]; 
00690                                                 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", receive_size, (mIncomingCompressedSize ? mIncomingCompressedSize : receive_size), mCurrentRecvPacketID);       
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                         
00705                         
00706                         
00707 
00708                         valid_packet = mTemplateMessageReader->validateMessage(buffer, 
00709                                                                                                                    receive_size,
00710                                                                                                                    host);
00711 
00712                         
00713                         
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                         
00753                         
00754                         cdp = mCircuitInfo.findCircuit(host);
00755 
00756                         if (valid_packet)
00757                         {
00758                                 
00759                                 
00760                                                 
00761 
00762                                 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771 
00772 
00773 
00774 
00775 
00776 
00777 
00778 
00779 
00780 
00781 
00782 
00783 
00784 
00785 
00786 
00787 
00788 
00789 
00790 
00791 
00792 
00793 
00794 
00795 
00796 
00797 
00798 
00799 
00800 
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 
00810 
00811 
00812 
00813 
00814 
00815 
00816 
00817 
00818 
00819 
00820 
00821 
00822 
00823 
00824 
00825 
00826 
00827 
00828 
00829 
00830 
00831 
00832 
00833 
00834 
00835 
00836 
00837 
00838 
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00846 
00847                                 mPacketsIn++;
00848                                 mBytesIn += mTrueReceiveSize;
00849                                 
00850                                 
00851                                 
00852                                 if (cdp && recv_reliable)
00853                                 {
00854                                         
00855                                         cdp->mRecentlyReceivedReliablePackets[mCurrentRecvPacketID] = getMessageTimeUsecs();
00856 
00857                                         
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                         
00876                         
00877                 }
00878         } while (!valid_packet && receive_size > 0);
00879 
00880         F64 mt_sec = getMessageTimeSeconds();
00881         
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                 
00929                 mCircuitInfo.updateWatchDogTimers(this);
00930 
00931                 
00932                 mCircuitInfo.resendUnackedPackets(mUnackedListDepth, mUnackedListSize);
00933 
00934                 
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                         
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         
00982         
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 
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 
01025 
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 
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                 
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                 
01158                 
01159 
01160 
01161 
01162                 return new LLFnPtrResponder(NULL, NULL,
01163                                                                         mMessageBuilder->getMessageName());
01164         }
01165 }
01166 
01167 
01168 
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()))    
01180         {
01181                 return 0;
01182         }
01183 
01184         LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
01185         if (!cdp)
01186         {
01187                 
01188                 
01189                 if (mbProtected)
01190                 {
01191                         
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                         
01205 
01206                         cdp = mCircuitInfo.addCircuitData(host, 0);
01207                 }
01208         }
01209         else
01210         {
01211                 
01212                 if (!cdp->isAlive())
01213                 {
01214                         
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         
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         
01242         
01243         memset(mSendBuffer, 0, LL_PACKET_ID_SIZE - 1); 
01244 
01245         
01246         cdp->nextPacketOutID();
01247 
01248         
01249         *((S32*)&mSendBuffer[PHL_PACKET_ID]) = htonl(cdp->getPacketOutID());
01250 
01251         
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                         
01274                         
01275                         mCircuitInfo.mUnackedCircuitMap[cdp->mHost] = cdp;
01276                 }
01277 
01278                 cdp->addReliablePacket(mSocket,buf_ptr,buffer_length, &mReliablePacketParams);
01279                 mReliablePacketsOut++;
01280         }
01281 
01282         
01283         S32 space_left = (MTUBYTES - buffer_length) / sizeof(TPACKETID); 
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                         
01301                         packet_id = (*iter);
01302                         if(mVerboseLog)
01303                         {
01304                                 acks.push_back(packet_id);
01305                         }
01306 
01307                         
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));     
01313                             
01314                             buffer_length += sizeof(TPACKETID);
01315                         }
01316                         else
01317                         {
01318                             
01319                             
01320                             
01321                                 
01322                                 
01323                                 
01324                                 
01325                                 
01326                             llerrs << "Buffer packing failed due to size.." << llendl;
01327                         }
01328                 }
01329 
01330                 
01331                 cdp->mAcks.erase(cdp->mAcks.begin(), last);
01332 
01333                 
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                 
01349                 cdp->addBytesOut( buffer_length );
01350         }
01351 
01352         if(mVerboseLog)
01353         {
01354                 std::ostringstream str;
01355                 str << "MSG: -> " << host;
01356                 char buffer[MAX_STRING];                        
01357                 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID());              
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         
01371 
01372 
01373 
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];                        
01390                 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID);                
01391                 str << buffer
01392                         << nullToEmpty(mMessageReader->getMessageName())
01393                         << (recv_reliable ? " reliable" : "")
01394                         << " REJECTED";
01395                 llinfos << str.str() << llendl;
01396         }
01397         
01398         
01399 
01400         
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                 
01408                 
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         
01439         
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                 
01457                 
01458                 
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                 
01475                 
01476                 mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
01477                 mMessageCountList[mNumMessageCounts].mInvalid = FALSE;
01478                 mNumMessageCounts++;
01479         }
01480 
01481         if (cdp)
01482         {
01483                 
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];                        
01493                 snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID);               
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 
01506 
01507 
01508 
01509 
01510 
01511 
01512 
01513 
01514 
01515 
01516 
01517 
01518 
01519 
01520 
01521 
01522 
01523 
01524 
01525 
01526 
01527 
01528 
01529 
01530 
01531 
01532 
01533 
01534 
01535 
01536 
01537 
01538 
01539 
01540 
01541 
01542 
01543 
01544 
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 
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 
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 
01586 
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         
01607 
01608         
01609         
01610         if (code)
01611         {
01612                 
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                         
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                 
01640                 
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                 
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                 
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                 
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 
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 
01803 void    process_complete_ping_check(LLMessageSystem *msgsystem, void** )
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         
01812         if (cdp)
01813         {
01814                 cdp->pingTimerStop(ping_id);
01815         }
01816 }
01817 
01818 void    process_start_ping_check(LLMessageSystem *msgsystem, void** )
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                 
01828                 U32 packet_id;
01829                 msgsystem->getU32Fast(_PREHASH_PingID, _PREHASH_OldestUnacked, packet_id);
01830                 cdp->clearDuplicateList(packet_id);
01831         }
01832 
01833         
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 
01843 void    open_circuit(LLMessageSystem *msgsystem, void** )
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         
01852         msgsystem->enableCircuit(LLHost(ip, port), FALSE);
01853 }
01854 
01855 void    close_circuit(LLMessageSystem *msgsystem, void** )
01856 {
01857         msgsystem->disableCircuit(msgsystem->getSender());
01858 }
01859 
01860 
01861 
01862 
01863 
01864 
01865 
01866 
01867 
01868 
01869 
01870 
01871 
01872 
01873 
01874 
01875 
01876 
01877 
01878 
01879 
01880 
01881 
01882 
01883 
01884 
01885 
01886 
01887 
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         
01897         
01898         
01899         
01900         
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                 
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 
01926 
01927         
01928 
01929 
01930 
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                 
01947                 code_session_map_t::iterator it;
01948                 it = msg->mCircuitCodes.find(circuit_code_in);
01949                 if(it == msg->mCircuitCodes.end())
01950                 {
01951                         
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                 
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                                 
01979                                 llinfos << "Got duplicate UseCircuitCode for circuit " << circuit_code_in << " to " << msg->getSender() << llendl;
01980                                 return;
01981                         }
01982 
01983                         
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                 
02014                 
02015                 
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                         
02031                         
02032                         
02033                         
02034                         
02035                         
02036                         
02037                         
02038                         
02039                         
02040                         
02041                         
02042                         
02043                         cdp->checkPacketInID(gMessageSystem->mCurrentRecvPacketID, FALSE ); 
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 
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 
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 
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         
02137         
02138         
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** )
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 
02268                         cdp->ackReliablePacket(packet_id);
02269                 }
02270                 if (!cdp->getUnackedPacketCount())
02271                 {
02272                         
02273                         gMessageSystem->mCircuitInfo.mUnackedCircuitMap.erase(host);
02274                 }
02275         }
02276 }
02277 
02278 
02279 
02280 
02281 
02282 
02283 
02284 
02285 
02286 
02287 
02288 
02289 
02290 
02291 
02292 
02293 
02294 
02295 
02296 
02297 
02298 
02299 
02300 void process_create_trusted_circuit(LLMessageSystem *msg, void **)
02301 {
02302         
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                 
02322                 return;
02323         }
02324 
02325         char their_digest[MD5HEX_STR_SIZE];     
02326         S32 size = msg->getSizeFast(_PREHASH_DataBlock, _PREHASH_Digest);
02327         if(size != MD5HEX_STR_BYTES)
02328         {
02329                 
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                 
02343                 
02344                 
02345                 
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         
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                 
02379                 return;
02380         }
02381 
02382         
02383         
02384         
02385         
02386         
02387         
02388         
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");       
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");   
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         
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         
02525         gMessageSystem->setHandlerFuncFast(_PREHASH_AddCircuitCode, LLMessageSystem::processAddCircuitCode);
02526         
02527         gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder);
02528         gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck,             process_packet_ack,      NULL);
02529         
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         
02539         
02540         
02541         gMessageSystem->setHandlerFunc(
02542                 "RequestTrustedCircuit",
02543                 null_message_callback,
02544                 NULL);
02545 
02546         
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];         
02576         char tmp_str[MAX_STRING];         
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);     
02580 
02581         
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);    
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));     
02588         str << buffer << std::endl;
02589         snprintf(buffer, MAX_STRING, "Average packet size:       %20.0f bytes", (F32)mTotalBytesIn / (F32)mPacketsIn);  
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));          
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));        
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); 
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));        
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));        
02606 
02607         
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 );  
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));     
02614         str << buffer << std::endl;
02615         snprintf(buffer, MAX_STRING, "Average packet size:       %20.0f bytes", (F32)mTotalBytesOut / (F32)mPacketsOut);        
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));                
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));              
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); 
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));              
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));              
02632         str << buffer << std::endl << std::endl;
02633         snprintf(buffer, MAX_STRING, "SendPacket failures:       %20d", mSendPacketFailureCount);       
02634         str << buffer << std::endl;
02635         snprintf(buffer, MAX_STRING, "Dropped packets:           %20d", mDroppedPackets);       
02636         str << buffer << std::endl;
02637         snprintf(buffer, MAX_STRING, "Resent packets:            %20d", mResentPackets);        
02638         str << buffer << std::endl;
02639         snprintf(buffer, MAX_STRING, "Failed reliable resends:   %20d", mFailedResendPackets);  
02640         str << buffer << std::endl;
02641         snprintf(buffer, MAX_STRING, "Off-circuit rejected packets: %17d", mOffCircuitPackets); 
02642         str << buffer << std::endl;
02643         snprintf(buffer, MAX_STRING, "On-circuit invalid packets:   %17d", mInvalidOnCircuitPackets);           
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"); 
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);        
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); 
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 
02770 S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()
02771 {
02772         if(mMessageBuilder == mLLSDMessageBuilder)
02773         {
02774                 
02775                 return 0;
02776         }
02777         
02778         if (! mMessageBuilder->isBuilt())
02779         {
02780                 mSendSize = mMessageBuilder->buildMessage(
02781                         mSendBuffer,
02782                         MAX_BUFFER_SIZE,
02783                         0);
02784         }
02785         
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 
02796 
02797         for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii)
02798         {
02799                 count--;
02800                 inptr++;
02801         }
02802 
02803 
02804 
02805 
02806 
02807 
02808         while (count--)
02809         {
02810                 if (!(*inptr))   
02811                 {
02812                         if (num_zeroes)
02813                         {
02814                                 if (++num_zeroes > 254)
02815                                 {
02816                                         num_zeroes = 0;
02817                                 }
02818                                 net_gain--;   
02819                         }
02820                         else
02821                         {
02822                                 net_gain++;  
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         
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 
02876 
02877         for (U32 ii = 0; ii < LL_PACKET_ID_SIZE; ++ii)
02878         {
02879                 count--;
02880                 *outptr++ = *inptr++;
02881         }
02882 
02883 
02884 
02885 
02886 
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         
03099         
03100         
03101 
03102         const char *colon = ":";
03103         char tbuf[16];   
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)); 
03117         }
03118 
03119         d.update((const unsigned char *) colon, (U32)strlen(colon));     
03120         
03121         snprintf(tbuf, sizeof(tbuf),"%i", number);              
03122         d.update((unsigned char *) tbuf, (U32)strlen(tbuf));     
03123         
03124         d.update((const unsigned char *) colon, (U32)strlen(colon));     
03125         if( (char*) id1str != NULL)
03126         {
03127                 d.update(id1str, (U32)strlen((char *) id1str));          
03128         }
03129         d.update((const unsigned char *) colon, (U32)strlen(colon));     
03130         
03131         if( (char*) id2str != NULL)
03132         {
03133                 d.update(id2str, (U32)strlen((char *) id2str));         
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];       
03172         U32 now = time(NULL);
03173 
03174         now /= window;
03175 
03176         
03177         
03178         
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];       
03238         U32 now = (S32)time(NULL);
03239 
03240         now /= window;
03241 
03242         
03243         
03244         
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];   
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         
03308         
03309         return;
03310 }
03311 
03312 
03313 
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         
03348         
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; 
03361                 if(cdp->getTrusted()) break; 
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];          
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]);       
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 
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 
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         
03461         else
03462         {
03463                 if (server_flavor == LLMessageConfig::LLSD_FLAVOR)
03464                 {
03465                         mMessageBuilder = mLLSDMessageBuilder;
03466                 }
03467                 
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 
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 
03991 void LLMessageSystem::setTimeDecodes( BOOL b )
03992 {
03993         LLMessageReader::setTimeDecodes(b);
03994 }
03995                 
03996 
03997 void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds )
03998 { 
03999         LLMessageReader::setTimeDecodesSpamThreshold(seconds);
04000 }
04001 
04002 
04003 
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 }