PageRenderTime 133ms CodeModel.GetById 20ms app.highlight 98ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/llmessage/message.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2414 lines | 1773 code | 315 blank | 326 comment | 219 complexity | 8400c111b21e6920cc8d92b43a44cd55 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/** 
   2 * @file message.cpp
   3 * @brief LLMessageSystem class implementation
   4 *
   5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "linden_common.h"
  28
  29#include "message.h"
  30
  31// system library includes
  32#if !LL_WINDOWS
  33// following header files required for inet_addr()
  34#include <sys/types.h>
  35#include <sys/socket.h>
  36#include <netinet/in.h>
  37#include <arpa/inet.h>
  38#endif
  39#include <iomanip>
  40#include <iterator>
  41#include <sstream>
  42
  43#include "llapr.h"
  44#include "apr_portable.h"
  45#include "apr_network_io.h"
  46#include "apr_poll.h"
  47
  48// linden library headers
  49#include "indra_constants.h"
  50#include "lldarray.h"
  51#include "lldir.h"
  52#include "llerror.h"
  53#include "llerrorlegacy.h"
  54#include "llfasttimer.h"
  55#include "llhttpclient.h"
  56#include "llhttpnodeadapter.h"
  57#include "llhttpsender.h"
  58#include "llmd5.h"
  59#include "llmessagebuilder.h"
  60#include "llmessageconfig.h"
  61#include "lltemplatemessagedispatcher.h"
  62#include "llpumpio.h"
  63#include "lltemplatemessagebuilder.h"
  64#include "lltemplatemessagereader.h"
  65#include "lltrustedmessageservice.h"
  66#include "llmessagetemplate.h"
  67#include "llmessagetemplateparser.h"
  68#include "llsd.h"
  69#include "llsdmessagebuilder.h"
  70#include "llsdmessagereader.h"
  71#include "llsdserialize.h"
  72#include "llstring.h"
  73#include "lltransfermanager.h"
  74#include "lluuid.h"
  75#include "llxfermanager.h"
  76#include "timing.h"
  77#include "llquaternion.h"
  78#include "u64.h"
  79#include "v3dmath.h"
  80#include "v3math.h"
  81#include "v4math.h"
  82#include "lltransfertargetvfile.h"
  83#include "llmemtype.h"
  84
  85// Constants
  86//const char* MESSAGE_LOG_FILENAME = "message.log";
  87static const F32 CIRCUIT_DUMP_TIMEOUT = 30.f;
  88static const S32 TRUST_TIME_WINDOW = 3;
  89
  90// *NOTE: This needs to be moved into a seperate file so that it never gets
  91// included in the viewer.  30 Sep 2002 mark
  92// *NOTE: I don't think it's important that the messgage system tracks
  93// this since it must get set externally. 2004.08.25 Phoenix.
  94static std::string g_shared_secret;
  95std::string get_shared_secret();
  96
  97class LLMessagePollInfo
  98{
  99public:
 100	apr_socket_t *mAPRSocketp;
 101	apr_pollfd_t mPollFD;
 102};
 103
 104namespace
 105{
 106	class LLFnPtrResponder : public LLHTTPClient::Responder
 107	{
 108		LOG_CLASS(LLFnPtrResponder);
 109	public:
 110		LLFnPtrResponder(void (*callback)(void **,S32), void **callbackData, const std::string& name) :
 111			mCallback(callback),
 112			mCallbackData(callbackData),
 113			mMessageName(name)
 114		{
 115		}
 116
 117		virtual void error(U32 status, const std::string& reason)
 118		{
 119			// don't spam when agent communication disconnected already
 120			if (status != 410)
 121			{
 122				LL_WARNS("Messaging") << "error status " << status
 123						<< " for message " << mMessageName
 124						<< " reason " << reason << llendl;
 125			}
 126			// TODO: Map status in to useful error code.
 127			if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT);
 128		}
 129		
 130		virtual void result(const LLSD& content)
 131		{
 132			if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_NOERR);
 133		}
 134
 135	private:
 136
 137		void (*mCallback)(void **,S32);    
 138		void **mCallbackData;
 139		std::string mMessageName;
 140	};
 141}
 142
 143class LLMessageHandlerBridge : public LLHTTPNode
 144{
 145	virtual bool validate(const std::string& name, LLSD& context) const
 146		{ return true; }
 147
 148	virtual void post(LLHTTPNode::ResponsePtr response, const LLSD& context, 
 149					  const LLSD& input) const;
 150};
 151
 152//virtual 
 153void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response, 
 154							const LLSD& context, const LLSD& input) const
 155{
 156	std::string name = context["request"]["wildcard"]["message-name"];
 157	char* namePtr = LLMessageStringTable::getInstance()->getString(name.c_str());
 158	
 159	lldebugs << "Setting mLastSender " << input["sender"].asString() << llendl;
 160	gMessageSystem->mLastSender = LLHost(input["sender"].asString());
 161	gMessageSystem->mPacketsIn += 1;
 162	gMessageSystem->mLLSDMessageReader->setMessage(namePtr, input["body"]);
 163	gMessageSystem->mMessageReader = gMessageSystem->mLLSDMessageReader;
 164	
 165	if(gMessageSystem->callHandler(namePtr, false, gMessageSystem))
 166	{
 167		response->result(LLSD());
 168	}
 169	else
 170	{
 171		response->notFound();
 172	}
 173}
 174
 175LLHTTPRegistration<LLMessageHandlerBridge>
 176	gHTTPRegistrationMessageWildcard("/message/<message-name>");
 177
 178//virtual
 179LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder()
 180{
 181	// even abstract base classes need a concrete destructor
 182}
 183
 184static const char* nullToEmpty(const char* s)
 185{
 186	static char emptyString[] = "";
 187	return s? s : emptyString;
 188}
 189
 190void LLMessageSystem::init()
 191{
 192	// initialize member variables
 193	mVerboseLog = FALSE;
 194
 195	mbError = FALSE;
 196	mErrorCode = 0;
 197	mSendReliable = FALSE;
 198
 199	mUnackedListDepth = 0;
 200	mUnackedListSize = 0;
 201	mDSMaxListDepth = 0;
 202
 203	mNumberHighFreqMessages = 0;
 204	mNumberMediumFreqMessages = 0;
 205	mNumberLowFreqMessages = 0;
 206	mPacketsIn = mPacketsOut = 0;
 207	mBytesIn = mBytesOut = 0;
 208	mCompressedPacketsIn = mCompressedPacketsOut = 0;
 209	mReliablePacketsIn = mReliablePacketsOut = 0;
 210
 211	mCompressedBytesIn = 0;
 212	mCompressedBytesOut = 0;
 213	mUncompressedBytesIn = 0;
 214	mUncompressedBytesOut = 0;
 215	mTotalBytesIn = 0;
 216	mTotalBytesOut = 0;
 217
 218    mDroppedPackets = 0;            // total dropped packets in
 219    mResentPackets = 0;             // total resent packets out
 220    mFailedResendPackets = 0;       // total resend failure packets out
 221    mOffCircuitPackets = 0;         // total # of off-circuit packets rejected
 222    mInvalidOnCircuitPackets = 0;   // total # of on-circuit packets rejected
 223
 224	mOurCircuitCode = 0;
 225
 226	mIncomingCompressedSize = 0;
 227	mCurrentRecvPacketID = 0;
 228
 229	mMessageFileVersionNumber = 0.f;
 230
 231	mTimingCallback = NULL;
 232	mTimingCallbackData = NULL;
 233
 234	mMessageBuilder = NULL;
 235	mMessageReader = NULL;
 236}
 237
 238// Read file and build message templates
 239LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port, 
 240								 S32 version_major,
 241								 S32 version_minor,
 242								 S32 version_patch,
 243								 bool failure_is_fatal,
 244								 const F32 circuit_heartbeat_interval, const F32 circuit_timeout) :
 245	mCircuitInfo(circuit_heartbeat_interval, circuit_timeout),
 246	mLastMessageFromTrustedMessageService(false)
 247{
 248	init();
 249
 250	mSendSize = 0;
 251
 252	mSystemVersionMajor = version_major;
 253	mSystemVersionMinor = version_minor;
 254	mSystemVersionPatch = version_patch;
 255	mSystemVersionServer = 0;
 256	mVersionFlags = 0x0;
 257
 258	// default to not accepting packets from not alive circuits
 259	mbProtected = TRUE;
 260
 261	// default to blocking trusted connections on a public interface if one is specified
 262	mBlockUntrustedInterface = true;
 263
 264	mSendPacketFailureCount = 0;
 265
 266	mCircuitPrintFreq = 60.f;		// seconds
 267
 268	loadTemplateFile(filename, failure_is_fatal);
 269
 270	mTemplateMessageBuilder = new LLTemplateMessageBuilder(mMessageTemplates);
 271	mLLSDMessageBuilder = new LLSDMessageBuilder();
 272	mMessageBuilder = NULL;
 273
 274	mTemplateMessageReader = new LLTemplateMessageReader(mMessageNumbers);
 275	mLLSDMessageReader = new LLSDMessageReader();
 276	mMessageReader = NULL;
 277
 278	// initialize various bits of net info
 279	mSocket = 0;
 280	mPort = port;
 281
 282	S32 error = start_net(mSocket, mPort);
 283	if (error != 0)
 284	{
 285		mbError = TRUE;
 286		mErrorCode = error;
 287	}
 288//	LL_DEBUGS("Messaging") <<  << "*** port: " << mPort << llendl;
 289
 290	//
 291	// Create the data structure that we can poll on
 292	//
 293	if (!gAPRPoolp)
 294	{
 295		LL_ERRS("Messaging") << "No APR pool before message system initialization!" << llendl;
 296		ll_init_apr();
 297	}
 298	apr_socket_t *aprSocketp = NULL;
 299	apr_os_sock_put(&aprSocketp, (apr_os_sock_t*)&mSocket, gAPRPoolp);
 300
 301	mPollInfop = new LLMessagePollInfo;
 302	mPollInfop->mAPRSocketp = aprSocketp;
 303	mPollInfop->mPollFD.p = gAPRPoolp;
 304	mPollInfop->mPollFD.desc_type = APR_POLL_SOCKET;
 305	mPollInfop->mPollFD.reqevents = APR_POLLIN;
 306	mPollInfop->mPollFD.rtnevents = 0;
 307	mPollInfop->mPollFD.desc.s = aprSocketp;
 308	mPollInfop->mPollFD.client_data = NULL;
 309
 310	F64 mt_sec = getMessageTimeSeconds();
 311	mResendDumpTime = mt_sec;
 312	mMessageCountTime = mt_sec;
 313	mCircuitPrintTime = mt_sec;
 314	mCurrentMessageTimeSeconds = mt_sec;
 315
 316	// Constants for dumping output based on message processing time/count
 317	mNumMessageCounts = 0;
 318	mMaxMessageCounts = 200; // >= 0 means dump warnings
 319	mMaxMessageTime   = 1.f;
 320
 321	mTrueReceiveSize = 0;
 322
 323	mReceiveTime = 0.f;
 324}
 325
 326
 327
 328// Read file and build message templates
 329void LLMessageSystem::loadTemplateFile(const std::string& filename, bool failure_is_fatal)
 330{
 331	if(filename.empty())
 332	{
 333		LL_ERRS("Messaging") << "No template filename specified" << llendl;
 334		mbError = TRUE;
 335		return;
 336	}
 337
 338	std::string template_body;
 339	if(!_read_file_into_string(template_body, filename))
 340	{
 341		if (failure_is_fatal) {
 342			LL_ERRS("Messaging") << "Failed to open template: " << filename << llendl;
 343		} else {
 344			LL_WARNS("Messaging") << "Failed to open template: " << filename << llendl;
 345		}
 346		mbError = TRUE;
 347		return;
 348	}
 349	
 350	LLTemplateTokenizer tokens(template_body);
 351	LLTemplateParser parsed(tokens);
 352	mMessageFileVersionNumber = parsed.getVersion();
 353	for(LLTemplateParser::message_iterator iter = parsed.getMessagesBegin();
 354		iter != parsed.getMessagesEnd();
 355		iter++)
 356	{
 357		addTemplate(*iter);
 358	}
 359}
 360
 361
 362LLMessageSystem::~LLMessageSystem()
 363{
 364	mMessageTemplates.clear(); // don't delete templates.
 365	for_each(mMessageNumbers.begin(), mMessageNumbers.end(), DeletePairedPointer());
 366	mMessageNumbers.clear();
 367	
 368	if (!mbError)
 369	{
 370		end_net(mSocket);
 371	}
 372	mSocket = 0;
 373	
 374	delete mTemplateMessageReader;
 375	mTemplateMessageReader = NULL;
 376	mMessageReader = NULL;
 377
 378	delete mTemplateMessageBuilder;
 379	mTemplateMessageBuilder = NULL;
 380	mMessageBuilder = NULL;
 381
 382	delete mLLSDMessageReader;
 383	mLLSDMessageReader = NULL;
 384
 385	delete mLLSDMessageBuilder;
 386	mLLSDMessageBuilder = NULL;
 387
 388	delete mPollInfop;
 389	mPollInfop = NULL;
 390
 391	mIncomingCompressedSize = 0;
 392	mCurrentRecvPacketID = 0;
 393}
 394
 395void LLMessageSystem::clearReceiveState()
 396{
 397	mCurrentRecvPacketID = 0;
 398	mIncomingCompressedSize = 0;
 399	mLastSender.invalidate();
 400	mLastReceivingIF.invalidate();
 401	mMessageReader->clearMessage();
 402	mLastMessageFromTrustedMessageService = false;
 403}
 404
 405
 406BOOL LLMessageSystem::poll(F32 seconds)
 407{
 408	S32 num_socks;
 409	apr_status_t status;
 410	status = apr_poll(&(mPollInfop->mPollFD), 1, &num_socks,(U64)(seconds*1000000.f));
 411	if (status != APR_TIMEUP)
 412	{
 413		ll_apr_warn_status(status);
 414	}
 415	if (num_socks)
 416	{
 417		return TRUE;
 418	}
 419	else
 420	{
 421		return FALSE;
 422	}
 423}
 424
 425bool LLMessageSystem::isTrustedSender(const LLHost& host) const
 426{
 427	LLCircuitData* cdp = mCircuitInfo.findCircuit(host);
 428	if(NULL == cdp)
 429	{
 430		return false;
 431	}
 432	return cdp->getTrusted();
 433}
 434
 435void LLMessageSystem::receivedMessageFromTrustedSender()
 436{
 437	mLastMessageFromTrustedMessageService = true;
 438}
 439
 440bool LLMessageSystem::isTrustedSender() const
 441{	
 442	return mLastMessageFromTrustedMessageService ||
 443		isTrustedSender(getSender());
 444}
 445
 446static LLMessageSystem::message_template_name_map_t::const_iterator 
 447findTemplate(const LLMessageSystem::message_template_name_map_t& templates, 
 448			 std::string name)
 449{
 450	const char* namePrehash = LLMessageStringTable::getInstance()->getString(name.c_str());
 451	if(NULL == namePrehash) {return templates.end();}
 452	return templates.find(namePrehash);
 453}
 454
 455bool LLMessageSystem::isTrustedMessage(const std::string& name) const
 456{
 457	message_template_name_map_t::const_iterator iter = 
 458		findTemplate(mMessageTemplates, name);
 459	if(iter == mMessageTemplates.end()) {return false;}
 460	return iter->second->getTrust() == MT_TRUST;
 461}
 462
 463bool LLMessageSystem::isUntrustedMessage(const std::string& name) const
 464{
 465	message_template_name_map_t::const_iterator iter = 
 466		findTemplate(mMessageTemplates, name);
 467	if(iter == mMessageTemplates.end()) {return false;}
 468	return iter->second->getTrust() == MT_NOTRUST;
 469}
 470
 471LLCircuitData* LLMessageSystem::findCircuit(const LLHost& host,
 472											bool resetPacketId)
 473{
 474	LLCircuitData* cdp = mCircuitInfo.findCircuit(host);
 475	if (!cdp)
 476	{
 477		// This packet comes from a circuit we don't know about.
 478		
 479		// Are we rejecting off-circuit packets?
 480		if (mbProtected)
 481		{
 482			// cdp is already NULL, so we don't need to unset it.
 483		}
 484		else
 485		{
 486			// nope, open the new circuit
 487			cdp = mCircuitInfo.addCircuitData(host, mCurrentRecvPacketID);
 488
 489			if(resetPacketId)
 490			{
 491				// I added this - I think it's correct - DJS
 492				// reset packet in ID
 493				cdp->setPacketInID(mCurrentRecvPacketID);
 494			}
 495			// And claim the packet is on the circuit we just added.
 496		}
 497	}
 498	else
 499	{
 500		// this is an old circuit. . . is it still alive?
 501		if (!cdp->isAlive())
 502		{
 503			// nope. don't accept if we're protected
 504			if (mbProtected)
 505			{
 506				// don't accept packets from unexpected sources
 507				cdp = NULL;
 508			}
 509			else
 510			{
 511				// wake up the circuit
 512				cdp->setAlive(TRUE);
 513				
 514				if(resetPacketId)
 515				{
 516					// reset packet in ID
 517					cdp->setPacketInID(mCurrentRecvPacketID);
 518				}
 519			}
 520		}
 521	}
 522	return cdp;
 523}
 524
 525// Returns TRUE if a valid, on-circuit message has been received.
 526BOOL LLMessageSystem::checkMessages( S64 frame_count )
 527{
 528	// Pump 
 529	BOOL	valid_packet = FALSE;
 530	mMessageReader = mTemplateMessageReader;
 531
 532	LLTransferTargetVFile::updateQueue();
 533	
 534	if (!mNumMessageCounts)
 535	{
 536		// This is the first message being handled after a resetReceiveCounts,
 537		// we must be starting the message processing loop.  Reset the timers.
 538		mCurrentMessageTimeSeconds = totalTime() * SEC_PER_USEC;
 539		mMessageCountTime = getMessageTimeSeconds();
 540	}
 541
 542	// loop until either no packets or a valid packet
 543	// i.e., burn through packets from unregistered circuits
 544	S32 receive_size = 0;
 545	do
 546	{
 547		clearReceiveState();
 548		
 549		BOOL recv_reliable = FALSE;
 550		BOOL recv_resent = FALSE;
 551		S32 acks = 0;
 552		S32 true_rcv_size = 0;
 553
 554		U8* buffer = mTrueReceiveBuffer;
 555		
 556		mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer);
 557		// If you want to dump all received packets into SecondLife.log, uncomment this
 558		//dumpPacketToLog();
 559		
 560		receive_size = mTrueReceiveSize;
 561		mLastSender = mPacketRing.getLastSender();
 562		mLastReceivingIF = mPacketRing.getLastReceivingInterface();
 563		
 564		if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE)
 565		{
 566			// A receive size of zero is OK, that means that there are no more packets available.
 567			// Ones that are non-zero but below the minimum packet size are worrisome.
 568			if (receive_size > 0)
 569			{
 570				LL_WARNS("Messaging") << "Invalid (too short) packet discarded " << receive_size << llendl;
 571				callExceptionFunc(MX_PACKET_TOO_SHORT);
 572			}
 573			// no data in packet receive buffer
 574			valid_packet = FALSE;
 575		}
 576		else
 577		{
 578			LLHost host;
 579			LLCircuitData* cdp;
 580			
 581			// note if packet acks are appended.
 582			if(buffer[0] & LL_ACK_FLAG)
 583			{
 584				acks += buffer[--receive_size];
 585				true_rcv_size = receive_size;
 586				if(receive_size >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE)))
 587				{
 588					receive_size -= acks * sizeof(TPACKETID);
 589				}
 590				else
 591				{
 592					// mal-formed packet. ignore it and continue with
 593					// the next one
 594					LL_WARNS("Messaging") << "Malformed packet received. Packet size "
 595						<< receive_size << " with invalid no. of acks " << acks
 596						<< llendl;
 597					valid_packet = FALSE;
 598					continue;
 599				}
 600			}
 601
 602			// process the message as normal
 603			mIncomingCompressedSize = zeroCodeExpand(&buffer, &receive_size);
 604			mCurrentRecvPacketID = ntohl(*((U32*)(&buffer[1])));
 605			host = getSender();
 606
 607			const bool resetPacketId = true;
 608			cdp = findCircuit(host, resetPacketId);
 609
 610			// At this point, cdp is now a pointer to the circuit that
 611			// this message came in on if it's valid, and NULL if the
 612			// circuit was bogus.
 613
 614			if(cdp && (acks > 0) && ((S32)(acks * sizeof(TPACKETID)) < (true_rcv_size)))
 615			{
 616				TPACKETID packet_id;
 617				U32 mem_id=0;
 618				for(S32 i = 0; i < acks; ++i)
 619				{
 620					true_rcv_size -= sizeof(TPACKETID);
 621					memcpy(&mem_id, &mTrueReceiveBuffer[true_rcv_size], /* Flawfinder: ignore*/
 622					     sizeof(TPACKETID));
 623					packet_id = ntohl(mem_id);
 624					//LL_INFOS("Messaging") << "got ack: " << packet_id << llendl;
 625					cdp->ackReliablePacket(packet_id);
 626				}
 627				if (!cdp->getUnackedPacketCount())
 628				{
 629					// Remove this circuit from the list of circuits with unacked packets
 630					mCircuitInfo.mUnackedCircuitMap.erase(cdp->mHost);
 631				}
 632			}
 633
 634			if (buffer[0] & LL_RELIABLE_FLAG)
 635			{
 636				recv_reliable = TRUE;
 637			}
 638			if (buffer[0] & LL_RESENT_FLAG)
 639			{
 640				recv_resent = TRUE;
 641				if (cdp && cdp->isDuplicateResend(mCurrentRecvPacketID))
 642				{
 643					// We need to ACK here to suppress
 644					// further resends of packets we've
 645					// already seen.
 646					if (recv_reliable)
 647					{
 648						//mAckList.addData(new LLPacketAck(host, mCurrentRecvPacketID));
 649						// ***************************************
 650						// TESTING CODE
 651						//if(mCircuitInfo.mCurrentCircuit->mHost != host)
 652						//{
 653						//	LL_WARNS("Messaging") << "DISCARDED PACKET HOST MISMATCH! HOST: "
 654						//			<< host << " CIRCUIT: "
 655						//			<< mCircuitInfo.mCurrentCircuit->mHost
 656						//			<< llendl;
 657						//}
 658						// ***************************************
 659						//mCircuitInfo.mCurrentCircuit->mAcks.put(mCurrentRecvPacketID);
 660						cdp->collectRAck(mCurrentRecvPacketID);
 661					}
 662								 
 663					LL_DEBUGS("Messaging") << "Discarding duplicate resend from " << host << llendl;
 664					if(mVerboseLog)
 665					{
 666						std::ostringstream str;
 667						str << "MSG: <- " << host;
 668						std::string tbuf;
 669						tbuf = llformat( "\t%6d\t%6d\t%6d ", receive_size, (mIncomingCompressedSize ? mIncomingCompressedSize : receive_size), mCurrentRecvPacketID);
 670						str << tbuf << "(unknown)"
 671							<< (recv_reliable ? " reliable" : "")
 672							<< " resent "
 673							<< ((acks > 0) ? "acks" : "")
 674							<< " DISCARD DUPLICATE";
 675						LL_INFOS("Messaging") << str.str() << llendl;
 676					}
 677					mPacketsIn++;
 678					valid_packet = FALSE;
 679					continue;
 680				}
 681			}
 682
 683			// UseCircuitCode can be a valid, off-circuit packet.
 684			// But we don't want to acknowledge UseCircuitCode until the circuit is
 685			// available, which is why the acknowledgement test is done above.  JC
 686			bool trusted = cdp && cdp->getTrusted();
 687			valid_packet = mTemplateMessageReader->validateMessage(
 688				buffer,
 689				receive_size,
 690				host,
 691				trusted);
 692			if (!valid_packet)
 693			{
 694				clearReceiveState();
 695			}
 696
 697			// UseCircuitCode is allowed in even from an invalid circuit, so that
 698			// we can toss circuits around.
 699			if(
 700				valid_packet &&
 701				!cdp && 
 702				(mTemplateMessageReader->getMessageName() !=
 703				 _PREHASH_UseCircuitCode))
 704			{
 705				logMsgFromInvalidCircuit( host, recv_reliable );
 706				clearReceiveState();
 707				valid_packet = FALSE;
 708			}
 709
 710			if(
 711				valid_packet &&
 712				cdp &&
 713				!cdp->getTrusted() && 
 714				mTemplateMessageReader->isTrusted())
 715			{
 716				logTrustedMsgFromUntrustedCircuit( host );
 717				clearReceiveState();
 718
 719				sendDenyTrustedCircuit(host);
 720				valid_packet = FALSE;
 721			}
 722
 723			if( valid_packet )
 724			{
 725				logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) );
 726				valid_packet = mTemplateMessageReader->readMessage(buffer, host);
 727			}
 728
 729			// It's possible that the circuit went away, because ANY message can disable the circuit
 730			// (for example, UseCircuit, CloseCircuit, DisableSimulator).  Find it again.
 731			cdp = mCircuitInfo.findCircuit(host);
 732
 733			if (valid_packet)
 734			{
 735				mPacketsIn++;
 736				mBytesIn += mTrueReceiveSize;
 737				
 738				// ACK here for	valid packets that we've seen
 739				// for the first time.
 740				if (cdp && recv_reliable)
 741				{
 742					// Add to the recently received list for duplicate suppression
 743					cdp->mRecentlyReceivedReliablePackets[mCurrentRecvPacketID] = getMessageTimeUsecs();
 744
 745					// Put it onto the list of packets to be acked
 746					cdp->collectRAck(mCurrentRecvPacketID);
 747					mReliablePacketsIn++;
 748				}
 749			}
 750			else
 751			{
 752				if (mbProtected  && (!cdp))
 753				{
 754					LL_WARNS("Messaging") << "Invalid Packet from invalid circuit " << host << llendl;
 755					mOffCircuitPackets++;
 756				}
 757				else
 758				{
 759					mInvalidOnCircuitPackets++;
 760				}
 761			}
 762		}
 763	} while (!valid_packet && receive_size > 0);
 764
 765	F64 mt_sec = getMessageTimeSeconds();
 766	// Check to see if we need to print debug info
 767	if ((mt_sec - mCircuitPrintTime) > mCircuitPrintFreq)
 768	{
 769		dumpCircuitInfo();
 770		mCircuitPrintTime = mt_sec;
 771	}
 772
 773	if( !valid_packet )
 774	{
 775		clearReceiveState();
 776	}
 777
 778	return valid_packet;
 779}
 780
 781S32	LLMessageSystem::getReceiveBytes() const
 782{
 783	if (getReceiveCompressedSize())
 784	{
 785		return getReceiveCompressedSize() * 8;
 786	}
 787	else
 788	{
 789		return getReceiveSize() * 8;
 790	}
 791}
 792
 793
 794void LLMessageSystem::processAcks()
 795{
 796	LLMemType mt_pa(LLMemType::MTYPE_MESSAGE_PROCESS_ACKS);
 797	F64 mt_sec = getMessageTimeSeconds();
 798	{
 799		gTransferManager.updateTransfers();
 800
 801		if (gXferManager)
 802		{
 803			gXferManager->retransmitUnackedPackets();
 804		}
 805
 806		if (gAssetStorage)
 807		{
 808			gAssetStorage->checkForTimeouts();
 809		}
 810	}
 811
 812	BOOL dump = FALSE;
 813	{
 814		// Check the status of circuits
 815		mCircuitInfo.updateWatchDogTimers(this);
 816
 817		//resend any necessary packets
 818		mCircuitInfo.resendUnackedPackets(mUnackedListDepth, mUnackedListSize);
 819
 820		//cycle through ack list for each host we need to send acks to
 821		mCircuitInfo.sendAcks();
 822
 823		if (!mDenyTrustedCircuitSet.empty())
 824		{
 825			LL_INFOS("Messaging") << "Sending queued DenyTrustedCircuit messages." << llendl;
 826			for (host_set_t::iterator hostit = mDenyTrustedCircuitSet.begin(); hostit != mDenyTrustedCircuitSet.end(); ++hostit)
 827			{
 828				reallySendDenyTrustedCircuit(*hostit);
 829			}
 830			mDenyTrustedCircuitSet.clear();
 831		}
 832
 833		if (mMaxMessageCounts >= 0)
 834		{
 835			if (mNumMessageCounts >= mMaxMessageCounts)
 836			{
 837				dump = TRUE;
 838			}
 839		}
 840
 841		if (mMaxMessageTime >= 0.f)
 842		{
 843			// This is one of the only places where we're required to get REAL message system time.
 844			mReceiveTime = (F32)(getMessageTimeSeconds(TRUE) - mMessageCountTime);
 845			if (mReceiveTime > mMaxMessageTime)
 846			{
 847				dump = TRUE;
 848			}
 849		}
 850	}
 851
 852	if (dump)
 853	{
 854		dumpReceiveCounts();
 855	}
 856	resetReceiveCounts();
 857
 858	if ((mt_sec - mResendDumpTime) > CIRCUIT_DUMP_TIMEOUT)
 859	{
 860		mResendDumpTime = mt_sec;
 861		mCircuitInfo.dumpResends();
 862	}
 863}
 864
 865void LLMessageSystem::copyMessageReceivedToSend()
 866{
 867	// NOTE: babbage: switch builder to match reader to avoid
 868	// converting message format
 869	if(mMessageReader == mTemplateMessageReader)
 870	{
 871		mMessageBuilder = mTemplateMessageBuilder;
 872	}
 873	else
 874	{
 875		mMessageBuilder = mLLSDMessageBuilder;
 876	}
 877	mSendReliable = FALSE;
 878	mMessageBuilder->newMessage(mMessageReader->getMessageName());
 879	mMessageReader->copyToBuilder(*mMessageBuilder);
 880}
 881
 882LLSD LLMessageSystem::getReceivedMessageLLSD() const
 883{
 884	LLSDMessageBuilder builder;
 885	mMessageReader->copyToBuilder(builder);
 886	return builder.getMessage();
 887}
 888
 889LLSD LLMessageSystem::getBuiltMessageLLSD() const 
 890{
 891	LLSD result;
 892	if (mLLSDMessageBuilder == mMessageBuilder)
 893	{
 894		 result = mLLSDMessageBuilder->getMessage();
 895	}
 896	else
 897	{
 898		// TODO: implement as below?
 899		llerrs << "Message not built as LLSD." << llendl; 
 900	}
 901	return result;
 902}
 903
 904LLSD LLMessageSystem::wrapReceivedTemplateData() const
 905{
 906	if(mMessageReader == mTemplateMessageReader)
 907	{
 908		LLTemplateMessageBuilder builder(mMessageTemplates);
 909		builder.newMessage(mMessageReader->getMessageName());
 910		mMessageReader->copyToBuilder(builder);
 911		U8 buffer[MAX_BUFFER_SIZE];
 912		const U8 offset_to_data = 0;
 913		U32 size = builder.buildMessage(buffer, MAX_BUFFER_SIZE,
 914										offset_to_data);
 915		std::vector<U8> binary_data(buffer, buffer+size);
 916		LLSD wrapped_data = LLSD::emptyMap();
 917		wrapped_data["binary-template-data"] = binary_data;
 918		return wrapped_data;
 919	}
 920	else
 921	{
 922		return getReceivedMessageLLSD();
 923	}
 924}
 925
 926LLSD LLMessageSystem::wrapBuiltTemplateData() const
 927{
 928	LLSD result;
 929	if (mLLSDMessageBuilder == mMessageBuilder)
 930	{
 931		result = getBuiltMessageLLSD();
 932	}
 933	else
 934	{
 935		U8 buffer[MAX_BUFFER_SIZE];
 936		const U8 offset_to_data = 0;
 937		U32 size = mTemplateMessageBuilder->buildMessage(
 938			buffer, MAX_BUFFER_SIZE,
 939			offset_to_data);
 940		std::vector<U8> binary_data(buffer, buffer+size);
 941		LLSD wrapped_data = LLSD::emptyMap();
 942		wrapped_data["binary-template-data"] = binary_data;
 943		result = wrapped_data;
 944	}
 945	return result;
 946}
 947
 948LLStoredMessagePtr LLMessageSystem::getReceivedMessage() const
 949{
 950	const std::string& name = mMessageReader->getMessageName();
 951	LLSD message = wrapReceivedTemplateData();
 952
 953	return LLStoredMessagePtr(new LLStoredMessage(name, message));
 954}
 955
 956LLStoredMessagePtr LLMessageSystem::getBuiltMessage() const
 957{
 958	const std::string& name = mMessageBuilder->getMessageName();
 959	LLSD message = wrapBuiltTemplateData();
 960
 961	return LLStoredMessagePtr(new LLStoredMessage(name, message));
 962}
 963
 964S32 LLMessageSystem::sendMessage(const LLHost &host, LLStoredMessagePtr message)
 965{
 966	return sendMessage(host, message->mName.c_str(), message->mMessage);
 967}
 968
 969
 970void LLMessageSystem::clearMessage()
 971{
 972	mSendReliable = FALSE;
 973	mMessageBuilder->clearMessage();
 974}
 975
 976// set block to add data to within current message
 977void LLMessageSystem::nextBlockFast(const char *blockname)
 978{
 979	mMessageBuilder->nextBlock(blockname);
 980}
 981
 982void LLMessageSystem::nextBlock(const char *blockname)
 983{
 984	nextBlockFast(LLMessageStringTable::getInstance()->getString(blockname));
 985}
 986
 987BOOL LLMessageSystem::isSendFull(const char* blockname)
 988{
 989	char* stringTableName = NULL;
 990	if(NULL != blockname)
 991	{
 992		stringTableName = LLMessageStringTable::getInstance()->getString(blockname);
 993	}
 994	return isSendFullFast(stringTableName);
 995}
 996
 997BOOL LLMessageSystem::isSendFullFast(const char* blockname)
 998{
 999	return mMessageBuilder->isMessageFull(blockname);
1000}
1001
1002
1003// blow away the last block of a message, return FALSE if that leaves no blocks or there wasn't a block to remove
1004// TODO: Babbage: Remove this horror.
1005BOOL LLMessageSystem::removeLastBlock()
1006{
1007	return mMessageBuilder->removeLastBlock();
1008}
1009
1010S32 LLMessageSystem::sendReliable(const LLHost &host)
1011{
1012	return sendReliable(host, LL_DEFAULT_RELIABLE_RETRIES, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
1013}
1014
1015
1016S32 LLMessageSystem::sendSemiReliable(const LLHost &host, void (*callback)(void **,S32), void ** callback_data)
1017{
1018	F32 timeout;
1019
1020	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1021	if (cdp)
1022	{
1023		timeout = llmax(LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS,
1024						LL_SEMIRELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged());
1025	}
1026	else
1027	{
1028		timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX;
1029	}
1030
1031	const S32 retries = 0;
1032	const BOOL ping_based_timeout = FALSE;
1033	return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);
1034}
1035
1036// send the message via a UDP packet
1037S32 LLMessageSystem::sendReliable(	const LLHost &host, 
1038									S32 retries, 
1039									BOOL ping_based_timeout,
1040									F32 timeout, 
1041									void (*callback)(void **,S32), 
1042									void ** callback_data)
1043{
1044	if (ping_based_timeout)
1045	{
1046	    LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1047	    if (cdp)
1048	    {
1049		    timeout = llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, LL_RELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged());
1050	    }
1051	    else
1052	    {
1053		    timeout = llmax(LL_MINIMUM_RELIABLE_TIMEOUT_SECONDS, LL_RELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX);
1054	    }
1055	}
1056
1057	mSendReliable = TRUE;
1058	mReliablePacketParams.set(host, retries, ping_based_timeout, timeout, 
1059		callback, callback_data, 
1060		const_cast<char*>(mMessageBuilder->getMessageName()));
1061	return sendMessage(host);
1062}
1063
1064void LLMessageSystem::forwardMessage(const LLHost &host)
1065{
1066	copyMessageReceivedToSend();
1067	sendMessage(host);
1068}
1069
1070void LLMessageSystem::forwardReliable(const LLHost &host)
1071{
1072	copyMessageReceivedToSend();
1073	sendReliable(host);
1074}
1075
1076void LLMessageSystem::forwardReliable(const U32 circuit_code)
1077{
1078	copyMessageReceivedToSend();
1079	sendReliable(findHost(circuit_code));
1080}
1081
1082S32 LLMessageSystem::forwardReliable(	const LLHost &host, 
1083										S32 retries, 
1084										BOOL ping_based_timeout,
1085										F32 timeout, 
1086										void (*callback)(void **,S32), 
1087										void ** callback_data)
1088{
1089	copyMessageReceivedToSend();
1090	return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);
1091}
1092
1093S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void **,S32), void ** callback_data)
1094{
1095	F32 timeout; 
1096
1097	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1098	if (cdp)
1099	{
1100		timeout = llmax(LL_MINIMUM_SEMIRELIABLE_TIMEOUT_SECONDS,
1101						LL_SEMIRELIABLE_TIMEOUT_FACTOR * cdp->getPingDelayAveraged());
1102	}
1103	else
1104	{
1105		timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX;
1106	}
1107
1108	S32 send_bytes = 0;
1109	if (mMessageBuilder->getMessageSize())
1110	{
1111		mSendReliable = TRUE;
1112		// No need for ping-based retry as not going to retry
1113		mReliablePacketParams.set(host, 0, FALSE, timeout, callback, 
1114								  callback_data, 
1115								  const_cast<char*>(mMessageBuilder->getMessageName()));
1116		send_bytes = sendMessage(host);
1117		clearMessage();
1118	}
1119	else
1120	{
1121		delete callback_data;
1122	}
1123	return send_bytes;
1124}
1125
1126S32 LLMessageSystem::flushReliable(const LLHost &host)
1127{
1128	S32 send_bytes = 0;
1129	if (mMessageBuilder->getMessageSize())
1130	{
1131		send_bytes = sendReliable(host);
1132	}
1133	clearMessage();
1134	return send_bytes;
1135}
1136
1137LLHTTPClient::ResponderPtr LLMessageSystem::createResponder(const std::string& name)
1138{
1139	if(mSendReliable)
1140	{
1141		return new LLFnPtrResponder(
1142			mReliablePacketParams.mCallback,
1143			mReliablePacketParams.mCallbackData,
1144			name);
1145	}
1146	else
1147	{
1148		// These messages aren't really unreliable, they just weren't
1149		// explicitly sent as reliable, so they don't have a callback
1150//		LL_WARNS("Messaging") << "LLMessageSystem::sendMessage: Sending unreliable "
1151//				<< mMessageBuilder->getMessageName() << " message via HTTP"
1152//				<< llendl;
1153		return new LLFnPtrResponder(
1154			NULL,
1155			NULL,
1156			name);
1157	}
1158}
1159
1160// This can be called from signal handlers,
1161// so should should not use llinfos.
1162S32 LLMessageSystem::sendMessage(const LLHost &host)
1163{
1164	if (! mMessageBuilder->isBuilt())
1165	{
1166		mSendSize = mMessageBuilder->buildMessage(
1167			mSendBuffer,
1168			MAX_BUFFER_SIZE,
1169			0);
1170	}
1171
1172	if (!(host.isOk()))    // if port and ip are zero, don't bother trying to send the message
1173	{
1174		return 0;
1175	}
1176
1177	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1178	if (!cdp)
1179	{
1180		// this is a new circuit!
1181		// are we protected?
1182		if (mbProtected)
1183		{
1184			// yup! don't send packets to an unknown circuit
1185			if(mVerboseLog)
1186			{
1187				LL_INFOS_ONCE("Messaging") << "MSG: -> " << host << "\tUNKNOWN CIRCUIT:\t"
1188						<< mMessageBuilder->getMessageName() << llendl;
1189			}
1190			LL_WARNS_ONCE("Messaging") << "sendMessage - Trying to send "
1191					<< mMessageBuilder->getMessageName() << " on unknown circuit "
1192					<< host << llendl;
1193			return 0;
1194		}
1195		else
1196		{
1197			// nope, open the new circuit
1198
1199			cdp = mCircuitInfo.addCircuitData(host, 0);
1200		}
1201	}
1202	else
1203	{
1204		// this is an old circuit. . . is it still alive?
1205		if (!cdp->isAlive())
1206		{
1207			// nope. don't send to dead circuits
1208			if(mVerboseLog)
1209			{
1210				LL_INFOS("Messaging") << "MSG: -> " << host << "\tDEAD CIRCUIT\t\t"
1211						<< mMessageBuilder->getMessageName() << llendl;
1212			}
1213			LL_WARNS("Messaging") << "sendMessage - Trying to send message "
1214					<< mMessageBuilder->getMessageName() << " to dead circuit "
1215					<< host << llendl;
1216			return 0;
1217		}
1218	}
1219
1220	// NOTE: babbage: LLSD message -> HTTP, template message -> UDP
1221	if(mMessageBuilder == mLLSDMessageBuilder)
1222	{
1223		LLSD message = mLLSDMessageBuilder->getMessage();
1224		
1225		const LLHTTPSender& sender = LLHTTPSender::getSender(host);
1226		sender.send(
1227			host,
1228			mLLSDMessageBuilder->getMessageName(),
1229			message,
1230			createResponder(mLLSDMessageBuilder->getMessageName()));
1231
1232		mSendReliable = FALSE;
1233		mReliablePacketParams.clear();
1234		return 1;
1235	}
1236
1237	// zero out the flags and packetid. Subtract 1 here so that we do
1238	// not overwrite the offset if it was set set in buildMessage().
1239	memset(mSendBuffer, 0, LL_PACKET_ID_SIZE - 1); 
1240
1241	// add the send id to the front of the message
1242	cdp->nextPacketOutID();
1243
1244	// Packet ID size is always 4
1245	*((S32*)&mSendBuffer[PHL_PACKET_ID]) = htonl(cdp->getPacketOutID());
1246
1247	// Compress the message, which will usually reduce its size.
1248	U8 * buf_ptr = (U8 *)mSendBuffer;
1249	U32 buffer_length = mSendSize;
1250	mMessageBuilder->compressMessage(buf_ptr, buffer_length);
1251
1252	if (buffer_length > 1500)
1253	{
1254		if((mMessageBuilder->getMessageName() != _PREHASH_ChildAgentUpdate)
1255		   && (mMessageBuilder->getMessageName() != _PREHASH_SendXferPacket))
1256		{
1257			LL_WARNS("Messaging") << "sendMessage - Trying to send "
1258					<< ((buffer_length > 4000) ? "EXTRA " : "")
1259					<< "BIG message " << mMessageBuilder->getMessageName() << " - "
1260					<< buffer_length << llendl;
1261		}
1262	}
1263	if (mSendReliable)
1264	{
1265		buf_ptr[0] |= LL_RELIABLE_FLAG;
1266
1267		if (!cdp->getUnackedPacketCount())
1268		{
1269			// We are adding the first packed onto the unacked packet list(s)
1270			// Add this circuit to the list of circuits with unacked packets
1271			mCircuitInfo.mUnackedCircuitMap[cdp->mHost] = cdp;
1272		}
1273
1274		cdp->addReliablePacket(mSocket,buf_ptr,buffer_length, &mReliablePacketParams);
1275		mReliablePacketsOut++;
1276	}
1277
1278	// tack packet acks onto the end of this message
1279	S32 space_left = (MTUBYTES - buffer_length) / sizeof(TPACKETID); // space left for packet ids
1280	S32 ack_count = (S32)cdp->mAcks.size();
1281	BOOL is_ack_appended = FALSE;
1282	std::vector<TPACKETID> acks;
1283	if((space_left > 0) && (ack_count > 0) && 
1284	   (mMessageBuilder->getMessageName() != _PREHASH_PacketAck))
1285	{
1286		buf_ptr[0] |= LL_ACK_FLAG;
1287		S32 append_ack_count = llmin(space_left, ack_count);
1288		const S32 MAX_ACKS = 250;
1289		append_ack_count = llmin(append_ack_count, MAX_ACKS);
1290		std::vector<TPACKETID>::iterator iter = cdp->mAcks.begin();
1291		std::vector<TPACKETID>::iterator last = cdp->mAcks.begin();
1292		last += append_ack_count;
1293		TPACKETID packet_id;
1294		for( ; iter != last ; ++iter)
1295		{
1296			// grab the next packet id.
1297			packet_id = (*iter);
1298			if(mVerboseLog)
1299			{
1300				acks.push_back(packet_id);
1301			}
1302
1303			// put it on the end of the buffer
1304			packet_id = htonl(packet_id);
1305
1306			if((S32)(buffer_length + sizeof(TPACKETID)) < MAX_BUFFER_SIZE)
1307			{
1308			    memcpy(&buf_ptr[buffer_length], &packet_id, sizeof(TPACKETID));	/* Flawfinder: ignore */
1309			    // Do the accounting
1310			    buffer_length += sizeof(TPACKETID);
1311			}
1312			else
1313			{
1314			    // Just reporting error is likely not enough.  Need to
1315			    // check how to abort or error out gracefully from
1316			    // this function. XXXTBD
1317				// *NOTE: Actually hitting this error would indicate
1318				// the calculation above for space_left, ack_count,
1319				// append_acout_count is incorrect or that
1320				// MAX_BUFFER_SIZE has fallen below MTU which is bad
1321				// and probably programmer error.
1322			    LL_ERRS("Messaging") << "Buffer packing failed due to size.." << llendl;
1323			}
1324		}
1325
1326		// clean up the source
1327		cdp->mAcks.erase(cdp->mAcks.begin(), last);
1328
1329		// tack the count in the final byte
1330		U8 count = (U8)append_ack_count;
1331		buf_ptr[buffer_length++] = count;
1332		is_ack_appended = TRUE;
1333	}
1334
1335	BOOL success;
1336	success = mPacketRing.sendPacket(mSocket, (char *)buf_ptr, buffer_length, host);
1337
1338	if (!success)
1339	{
1340		mSendPacketFailureCount++;
1341	}
1342	else
1343	{
1344		// mCircuitInfo already points to the correct circuit data
1345		cdp->addBytesOut( buffer_length );
1346	}
1347
1348	if(mVerboseLog)
1349	{
1350		std::ostringstream str;
1351		str << "MSG: -> " << host;
1352		std::string buffer;
1353		buffer = llformat( "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID());
1354		str << buffer
1355			<< mMessageBuilder->getMessageName()
1356			<< (mSendReliable ? " reliable " : "");
1357		if(is_ack_appended)
1358		{
1359			str << "\tACKS:\t";
1360			std::ostream_iterator<TPACKETID> append(str, " ");
1361			std::copy(acks.begin(), acks.end(), append);
1362		}
1363		LL_INFOS("Messaging") << str.str() << llendl;
1364	}
1365
1366
1367	mPacketsOut++;
1368	mBytesOut += buffer_length;
1369	
1370	mSendReliable = FALSE;
1371	mReliablePacketParams.clear();
1372	return buffer_length;
1373}
1374
1375void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_reliable )
1376{
1377	if(mVerboseLog)
1378	{
1379		std::ostringstream str;
1380		str << "MSG: <- " << host;
1381		std::string buffer;
1382		buffer = llformat( "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID);
1383		str << buffer
1384			<< nullToEmpty(mMessageReader->getMessageName())
1385			<< (recv_reliable ? " reliable" : "")
1386 			<< " REJECTED";
1387		LL_INFOS("Messaging") << str.str() << llendl;
1388	}
1389	// nope!
1390	// cout << "Rejecting unexpected message " << mCurrentMessageTemplate->mName << " from " << hex << ip << " , " << dec << port << endl;
1391
1392	// Keep track of rejected messages as well
1393	if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM)
1394	{
1395		LL_WARNS("Messaging") << "Got more than " << MAX_MESSAGE_COUNT_NUM << " packets without clearing counts" << llendl;
1396	}
1397	else
1398	{
1399		// TODO: babbage: work out if we need these
1400		// mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
1401		mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
1402		mMessageCountList[mNumMessageCounts].mInvalid = TRUE;
1403		mNumMessageCounts++;
1404	}
1405}
1406
1407S32 LLMessageSystem::sendMessage(
1408	const LLHost &host,
1409	const char* name,
1410	const LLSD& message)
1411{
1412	if (!(host.isOk()))
1413	{
1414		LL_WARNS("Messaging") << "trying to send message to invalid host"	<< llendl;
1415		return 0;
1416	}
1417
1418	const LLHTTPSender& sender = LLHTTPSender::getSender(host);
1419	sender.send(host, name, message, createResponder(name));
1420	return 1;
1421}
1422
1423void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )
1424{
1425	// RequestTrustedCircuit is how we establish trust, so don't spam
1426	// if it's received on a trusted circuit. JC
1427	if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit"))
1428	{
1429		LL_WARNS("Messaging") << "Received trusted message on untrusted circuit. "
1430				<< "Will reply with deny. "
1431				<< "Message: " << nullToEmpty(mMessageReader->getMessageName())
1432				<< " Host: " << host << llendl;
1433	}
1434
1435	if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM)
1436	{
1437		LL_WARNS("Messaging") << "got more than " << MAX_MESSAGE_COUNT_NUM
1438			<< " packets without clearing counts"
1439			<< llendl;
1440	}
1441	else
1442	{
1443		// TODO: babbage: work out if we need these
1444		//mMessageCountList[mNumMessageCounts].mMessageNum
1445		//	= mCurrentRMessageTemplate->mMessageNumber;
1446		mMessageCountList[mNumMessageCounts].mMessageBytes
1447			= mMessageReader->getMessageSize();
1448		mMessageCountList[mNumMessageCounts].mInvalid = TRUE;
1449		mNumMessageCounts++;
1450	}
1451}
1452
1453void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL recv_reliable, BOOL recv_resent, BOOL recv_acks )
1454{
1455	if (mNumMessageCounts >= MAX_MESSAGE_COUNT_NUM)
1456	{
1457		LL_WARNS("Messaging") << "Got more than " << MAX_MESSAGE_COUNT_NUM << " packets without clearing counts" << llendl;
1458	}
1459	else
1460	{
1461		// TODO: babbage: work out if we need these
1462		//mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber;
1463		mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();
1464		mMessageCountList[mNumMessageCounts].mInvalid = FALSE;
1465		mNumMessageCounts++;
1466	}
1467
1468	if (cdp)
1469	{
1470		// update circuit packet ID tracking (missing/out of order packets)
1471		cdp->checkPacketInID( mCurrentRecvPacketID, recv_resent );
1472		cdp->addBytesIn( mTrueReceiveSize );
1473	}
1474
1475	if(mVerboseLog)
1476	{
1477		std::ostringstream str;
1478		str << "MSG: <- " << host;
1479		std::string buffer;
1480		buffer = llformat( "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID);
1481		str << buffer
1482			<< nullToEmpty(mMessageReader->getMessageName())
1483			<< (recv_reliable ? " reliable" : "")
1484			<< (recv_resent ? " resent" : "")
1485			<< (recv_acks ? " acks" : "");
1486		LL_INFOS("Messaging") << str.str() << llendl;
1487	}
1488}
1489
1490void LLMessageSystem::sanityCheck()
1491{
1492// TODO: babbage: reinstate
1493
1494//	if (!mCurrentRMessageData)
1495//	{
1496//		LL_ERRS("Messaging") << "mCurrentRMessageData is NULL" << llendl;
1497//	}
1498
1499//	if (!mCurrentRMessageTemplate)
1500//	{
1501//		LL_ERRS("Messaging") << "mCurrentRMessageTemplate is NULL" << llendl;
1502//	}
1503
1504//	if (!mCurrentRTemplateBlock)
1505//	{
1506//		LL_ERRS("Messaging") << "mCurrentRTemplateBlock is NULL" << llendl;
1507//	}
1508
1509//	if (!mCurrentRDataBlock)
1510//	{
1511//		LL_ERRS("Messaging") << "mCurrentRDataBlock is NULL" << llendl;
1512//	}
1513
1514//	if (!mCurrentSMessageData)
1515//	{
1516//		LL_ERRS("Messaging") << "mCurrentSMessageData is NULL" << llendl;
1517//	}
1518
1519//	if (!mCurrentSMessageTemplate)
1520//	{
1521//		LL_ERRS("Messaging") << "mCurrentSMessageTemplate is NULL" << llendl;
1522//	}
1523
1524//	if (!mCurrentSTemplateBlock)
1525//	{
1526//		LL_ERRS("Messaging") << "mCurrentSTemplateBlock is NULL" << llendl;
1527//	}
1528
1529//	if (!mCurrentSDataBlock)
1530//	{
1531//		LL_ERRS("Messaging") << "mCurrentSDataBlock is NULL" << llendl;
1532//	}
1533}
1534
1535void LLMessageSystem::showCircuitInfo()
1536{
1537	LL_INFOS("Messaging") << mCircuitInfo << llendl;
1538}
1539
1540
1541void LLMessageSystem::dumpCircuitInfo()
1542{
1543	lldebugst(LLERR_CIRCUIT_INFO) << mCircuitInfo << llendl;
1544}
1545
1546/* virtual */
1547U32 LLMessageSystem::getOurCircuitCode()
1548{
1549	return mOurCircuitCode;
1550}
1551
1552void LLMessageSystem::getCircuitInfo(LLSD& info) const
1553{
1554	mCircuitInfo.getInfo(info);
1555}
1556
1557// returns whether the given host is on a trusted circuit
1558BOOL    LLMessageSystem::getCircuitTrust(const LLHost &host)
1559{
1560	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1561	if (cdp)
1562	{
1563		return cdp->getTrusted();
1564	}
1565
1566	return FALSE;
1567}
1568
1569// Activate a circuit, and set its trust level (TRUE if trusted,
1570// FALSE if not).
1571void LLMessageSystem::enableCircuit(const LLHost &host, BOOL trusted)
1572{
1573	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1574	if (!cdp)
1575	{
1576		cdp = mCircuitInfo.addCircuitData(host, 0);
1577	}
1578	else
1579	{
1580		cdp->setAlive(TRUE);
1581	}
1582	cdp->setTrusted(trusted);
1583}
1584
1585void LLMessageSystem::disableCircuit(const LLHost &host)
1586{
1587	LL_INFOS("Messaging") << "LLMessageSystem::disableCircuit for " << host << llendl;
1588	U32 code = gMessageSystem->findCircuitCode( host );
1589
1590	// Don't need to do this, as we're removing the circuit info anyway - djs 01/28/03
1591
1592	// don't clean up 0 circuit code entries
1593	// because many hosts (neighbor sims, etc) can have the 0 circuit
1594	if (code)
1595	{
1596		//if (mCircuitCodes.checkKey(code))
1597		code_session_map_t::iterator it = mCircuitCodes.find(code);
1598		if(it != mCircuitCodes.end())
1599		{
1600			LL_INFOS("Messaging") << "Circuit " << code << " removed from list" << llendl;
1601			//mCircuitCodes.removeData(code);
1602			mCircuitCodes.erase(it);
1603		}
1604
1605		U64 ip_port = 0;
1606		std::map<U32, U64>::iterator iter = gMessageSystem->mCircuitCodeToIPPort.find(code);
1607		if (iter != gMessageSystem->mCircuitCodeToIPPort.end())
1608		{
1609			ip_port = iter->second;
1610
1611			gMessageSystem->mCircuitCodeToIPPort.erase(iter);
1612
1613			U32 old_port = (U32)(ip_port & (U64)0xFFFFFFFF);
1614			U32 old_ip = (U32)(ip_port >> 32);
1615
1616			LL_INFOS("Messaging") << "Host " << LLHost(old_ip, old_port) << " circuit " << code << " removed from lookup table" << llendl;
1617			gMessageSystem->mIPPortToCircuitCode.erase(ip_port);
1618		}
1619		mCircuitInfo.removeCircuitData(host);
1620	}
1621	else
1622	{
1623		// Sigh, since we can open circuits which don't have circuit
1624		// codes, it's possible for this to happen...
1625		
1626		LL_WARNS("Messaging") << "Couldn't find circuit code for " << host << llendl;
1627	}
1628
1629}
1630
1631
1632void LLMessageSystem::setCircuitAllowTimeout(const LLHost &host, BOOL allow)
1633{
1634	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1635	if (cdp)
1636	{
1637		cdp->setAllowTimeout(allow);
1638	}
1639}
1640
1641void LLMessageSystem::setCircuitTimeoutCallback(const LLHost &host, void (*callback_func)(const LLHost & host, void *user_data), void *user_data)
1642{
1643	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1644	if (cdp)
1645	{
1646		cdp->setTimeoutCallback(callback_func, user_data);
1647	}
1648}
1649
1650
1651BOOL LLMessageSystem::checkCircuitBlocked(const U32 circuit)
1652{
1653	LLHost host = findHost(circuit);
1654
1655	if (!host.isOk())
1656	{
1657		LL_DEBUGS("Messaging") << "checkCircuitBlocked: Unknown circuit " << circuit << llendl;
1658		return TRUE;
1659	}
1660
1661	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1662	if (cdp)
1663	{
1664		return cdp->isBlocked();
1665	}
1666	else
1667	{
1668		LL_INFOS("Messaging") << "checkCircuitBlocked(circuit): Unknown host - " << host << llendl;
1669		return FALSE;
1670	}
1671}
1672
1673BOOL LLMessageSystem::checkCircuitAlive(const U32 circuit)
1674{
1675	LLHost host = findHost(circuit);
1676
1677	if (!host.isOk())
1678	{
1679		LL_DEBUGS("Messaging") << "checkCircuitAlive: Unknown circuit " << circuit << llendl;
1680		return FALSE;
1681	}
1682
1683	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1684	if (cdp)
1685	{
1686		return cdp->isAlive();
1687	}
1688	else
1689	{
1690		LL_INFOS("Messaging") << "checkCircuitAlive(circuit): Unknown host - " << host << llendl;
1691		return FALSE;
1692	}
1693}
1694
1695BOOL LLMessageSystem::checkCircuitAlive(const LLHost &host)
1696{
1697	LLCircuitData *cdp = mCircuitInfo.findCircuit(host);
1698	if (cdp)
1699	{
1700		return cdp->isAlive();
1701	}
1702	else
1703	{
1704		LL_DEBUGS("Messaging") << "checkCircuitAlive(host): Unknown host - " << host << llendl;
1705		return FALSE;
1706	}
1707}
1708
1709
1710void LLMessageSystem::setCircuitProtection(BOOL b_protect)
1711{
1712	mbProtected = b_protect;
1713}
1714
1715
1716U32 LLMessageSystem::findCircuitCode(const LLHost &host)
1717{
1718	U64 ip64 = (U64) host.getAddress();
1719	U64 port64 = (U64) host.getPort();
1720	U64 ip_port = (ip64 << 32) | port64;
1721
1722	return get_if_there(mIPPortToCircuitCode, ip_port, U32(0));
1723}
1724
1725LLHost LLMessageSystem::findHost(const U32 circuit_code)
1726{
1727	if (mCircuitCodeToIPPort.count(circuit_code) > 0)
1728	{
1729		return LLHost(mCircuitCodeToIPPort[circuit_code]);
1730	}
1731	else
1732	{
1733		return LLHost::invalid;
1734	}
1735}
1736
1737void LLMessageSystem::setMaxMessageTime(const F32 seconds)
1738{
1739	mMaxMessageTime = seconds;
1740}
1741
1742void LLMessageSystem::setMaxMessageCounts(const S32 num)
1743{
1744	mMaxMessageCounts = num;
1745}
1746
1747
1748std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg)
1749{
1750	U32 i;
1751	if (msg.mbError)
1752	{
1753		s << "Message system not correctly initialized";
1754	}
1755	else
1756	{
1757		s << "Message system open on port " << msg.mPort << " and socket " << msg.mSocket << "\n";
1758//		s << "Message template file " << msg.mName << " loaded\n";
1759		
1760		s << "\nHigh frequency messages:\n";
1761
1762		for (i = 1; msg.mMessageNumbers[i] && (i < 255); i++)
1763		{
1764			s << *(msg.mMessageNumbers[i]);
1765		}
1766		
1767		s << "\nMedium frequency messages:\n";
1768
1769		for (i = (255 << 8) + 1; msg.mMessageNumbers[i] && (i < (255 << 8) + 255); i++)
1770		{
1771			s << *msg.mMessageNumbers[i];
1772		}
1773		
1774		s << "\nLow frequency messages:\n";
1775
1776		for (i = (0xFFFF0000) + 1; msg.mMessageNumbers[i] && (i < 0xFFFFFFFF); i++)
1777		{
1778			s << *msg.mMessageNumbers[i];
1779		}
1780	}
1781	return s;
1782}
1783
1784LLMessageSystem	*gMessageSystem = NULL;
1785
1786// update appropriate ping info
1787void	process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/)
1788{
1789	U8 ping_id;
1790	msgsystem->getU8Fast(_PREHASH_PingID, _PREHASH_PingID, ping_id);
1791
1792	LLCircuitData *cdp;
1793	cdp = msgsystem->mCircuitInfo.findCircuit(msgsystem->getSender());
1794
1795	// stop the appropriate timer
1796	if (cdp)
1797	{
1798		cdp->pingTimerStop(ping_id);
1799	}
1800}
1801
1802void	process_start_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/)
1803{
1804	U8 ping_id;
1805	msgsystem->getU8Fast(_PREHASH_PingID, _PREHASH_PingID, ping_id);
1806
1807	LLCircuitData *cdp;
1808	cdp = msgsystem->mCircuitInfo.findCircuit(msgsystem->getSender());
1809	if (cdp)
1810	{
1811		// Grab the packet id of the oldest unacked packet
1812		U32 packet_id;
1813		msgsystem->getU32Fast(_PREHASH_PingID, _PREHASH_OldestUnacked, packet_id);
1814		cdp->clearDuplicateList(packet_id);
1815	}
1816
1817	// Send off the response
1818	msgsystem->newMessageFast(_PREHASH_CompletePingCheck);
1819	msgsystem->nextBlockFast(_PREHASH_PingID);
1820	msgsystem->addU8(_PREHASH_PingID, ping_id);
1821	msgsystem->sendMessage(msgsystem->getSender());
1822}
1823
1824
1825
1826// Note: this is currently unused. --mark
1827void	open_circuit(LLMessageSystem *msgsystem, void** /*user_data*/)
1828{
1829	U32  ip;
1830	U16	 port;
1831
1832	msgsystem->getIPAddrFast(_PREHASH_CircuitInfo, _PREHASH_IP, ip);
1833	msgsystem->getIPPortFast(_PREHASH_CircuitInfo, _PREHASH_Port, port);
1834
1835	// By default, OpenCircuit's are untrusted
1836	msgsystem->enableCircuit(LLHost(ip, port), FALSE);
1837}
1838
1839void	close_circuit(LLMessageSystem *msgsystem, void** /*user_data*/)
1840{
1841	msgsystem->disableCircuit(msgsystem->getSender());
1842}
1843
1844// static
1845/*
1846void LLMessageSystem::processAssignCircuitCode(LLMessageSystem* msg, void**)
1847{
1848	// if we already have a circuit code, we can bail
1849	if(msg->mOurCircuitCode) return;
1850	LLUUID session_id;
1851	msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id);
1852	if(session_id != msg->getMySessionID())
1853	{
1854		LL_WARNS("Messaging") << "AssignCircuitCode, bad session id. Expecting "
1855				<< msg->getMySessionID() << " but got " << session_id
1856				<< llendl;
1857		return;
1858	}
1859	U32 code;
1860	msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, code);
1861	if (!code)
1862	{
1863		LL_ERRS("Messaging") << "Assigning circuit code of zero!" << llendl;
1864	}
1865	
1866	msg->mOurCircuitCode = code;
1867	LL_INFOS("Messaging") << "Circuit code " << code << " assigned." << llendl;
1868}
1869*/
1870
1871// static
1872void LLMessageSystem::processAddCircuitCode(LLMessageSystem* msg, void**)
1873{
1874	U32 code;
1875	msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, code);
1876	LLUUID session_id;
1877	msg->getUUIDFast(_PREHASH_CircuitCode, _PREHASH_SessionID, session_id);
1878	(void)msg->addCircuitCode(code, session_id);
1879
1880	// Send the ack back
1881	//msg->newMessageFast(_PREHASH_AckAddCircuitCode);
1882	//msg->nextBlockFast(_PREHASH_CircuitCode);
1883	//msg->addU32Fast(_PREHASH_Code, code);
1884	//msg->sendMessage(msg->getSender());
1885}
1886
1887bool LLMessageSystem::addCircuitCode(U32 code, const LLUUID& session_id)
1888{
1889	if(!code)
1890	{
1891		LL_WARNS("Messaging") << "addCircuitCode: zero circuit code" << llendl;
1892		return false;
1893	}
1894	code_session_map_t::iterator it = mCircuitCodes.find(code);
1895	if(it == mCircuitCodes.end())
1896	{
1897		LL_INFOS("Messaging") << "New circuit code " << code << " added" << llendl;
1898		//msg->mCircuitCodes[circuit_code] = circuit_code;
1899		
1900		mCircuitCodes.insert(code_session_map_t::value_type(code, session_id));
1901	}
1902	else
1903	{
1904		LL_INFOS("Messaging") << "Duplicate circuit code " << code << " added" << llendl;
1905	}
1906	return true;
1907}
1908
1909//void ack_add_circuit_code(LLMessageSystem *msgsystem, void** /*user_data*…

Large files files are truncated, but you can click here to view the full file