diff options
| author | Don Kjer <don@lindenlab.com> | 2007-05-01 21:39:25 +0000 | 
|---|---|---|
| committer | Don Kjer <don@lindenlab.com> | 2007-05-01 21:39:25 +0000 | 
| commit | 4ecb9cb63e4993b3b4bc65d73ed255139b5c3f75 (patch) | |
| tree | 48d9bb9a1ae468ecdbd53cf21a598d66ee8eced3 /indra/llmessage | |
| parent | f5e9ce7e47694e349a4eb28b052016b11e1bdf81 (diff) | |
svn merge -r 59163:61099 svn+ssh://svn/svn/linden/branches/release-candidate into release
Diffstat (limited to 'indra/llmessage')
41 files changed, 5156 insertions, 2566 deletions
| diff --git a/indra/llmessage/llblowfishcipher.cpp b/indra/llmessage/llblowfishcipher.cpp index 0255a654df..d15e4fb69a 100644 --- a/indra/llmessage/llblowfishcipher.cpp +++ b/indra/llmessage/llblowfishcipher.cpp @@ -65,27 +65,33 @@ U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)  		<< " iv_len " << iv_length  		<< llendl; -    int output_len = 0; -    if (!EVP_EncryptUpdate(&context, -                dst, -                &output_len, -                src, -                src_len)) -    { -        llwarns << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << llendl; -        return 0; -    } - -	// There may be some final data left to encrypt if the input is -	// not an exact multiple of the block size. -    int temp_len = 0; -    if (!EVP_EncryptFinal_ex(&context, (unsigned char*)(dst + output_len), &temp_len)) -    { -        llwarns << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << llendl; -        return 0; -    } -    output_len += temp_len; -	return output_len; +	int output_len = 0;
 +	int temp_len = 0;
 +	if (!EVP_EncryptUpdate(&context,
 +			dst,
 +			&output_len,
 +			src,
 +			src_len))
 +	{
 +		llwarns << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << llendl;
 +		goto ERROR;
 +	}
 +
 +	// There may be some final data left to encrypt if the input is
 +	// not an exact multiple of the block size.
 +	if (!EVP_EncryptFinal_ex(&context, (unsigned char*)(dst + output_len), &temp_len))
 +	{
 +		llwarns << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << llendl;
 +		goto ERROR;
 +	}
 +	output_len += temp_len;
 +
 +	EVP_CIPHER_CTX_cleanup(&context);
 +	return output_len;
 +
 +ERROR:
 +	EVP_CIPHER_CTX_cleanup(&context);
 +	return 0;
  }  // virtual diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 339fdda9ef..36cd2ce188 100644 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -32,6 +32,10 @@ const char* CN_NONE = "(none)";  const char* CN_HIPPOS = "(hippos)";  const F32 HIPPO_PROBABILITY = 0.01f; +// We track name requests in flight for up to this long. +// We won't re-request a name during this time +const U32 PENDING_TIMEOUT_SECS = 5 * 60; +  // File version number  const S32 CN_FILE_VERSION = 2; @@ -162,8 +166,9 @@ namespace {  	} -	typedef std::vector<LLUUID>					AskQueue; +	typedef std::set<LLUUID>					AskQueue;  	typedef std::vector<PendingReply>			ReplyQueue; +	typedef std::map<LLUUID,U32>				PendingQueue;  	typedef std::map<LLUUID, LLCacheNameEntry*> Cache;  	typedef std::vector<LLCacheNameCallback>	Observers;  }; @@ -180,6 +185,9 @@ public:  	AskQueue			mAskNameQueue;  	AskQueue			mAskGroupQueue;  		// UUIDs to ask our upstream host about +	 +	PendingQueue		mPendingQueue; +		// UUIDs that have been requested but are not in cache yet.  	ReplyQueue			mReplyQueue;  		// requests awaiting replies from us @@ -194,6 +202,7 @@ public:  	void processPendingAsks();  	void processPendingReplies();  	void sendRequest(const char* msg_name, const AskQueue& queue); +	bool isRequestPending(const LLUUID& id);  	// Message system callbacks.  	void processUUIDRequest(LLMessageSystem* msg, bool isGroup); @@ -436,7 +445,10 @@ BOOL LLCacheName::getName(const LLUUID& id, char* first, char* last)  						: CN_WAITING);  		strcpy(last, "");	/*Flawfinder: ignore*/ -		impl.mAskNameQueue.push_back(id); +		if (!impl.isRequestPending(id)) +		{ +			impl.mAskNameQueue.insert(id); +		}	  		return FALSE;  	} @@ -476,8 +488,10 @@ BOOL LLCacheName::getGroupName(const LLUUID& id, char* group)  		// The function signature needs to change to pass in the length  		// of first and last.  		strcpy(group, CN_WAITING);	/*Flawfinder: ignore*/ - -		impl.mAskGroupQueue.push_back(id); +		if (!impl.isRequestPending(id)) +		{ +			impl.mAskGroupQueue.insert(id); +		}  		return FALSE;  	}  } @@ -505,13 +519,16 @@ void LLCacheName::get(const LLUUID& id, BOOL is_group, LLCacheNameCallback callb  	}  	else  	{ -		if (!is_group) -		{ -			impl.mAskNameQueue.push_back(id); -		} -		else +		if (!impl.isRequestPending(id))  		{ -			impl.mAskGroupQueue.push_back(id); +			if (!is_group) +			{ +				impl.mAskNameQueue.insert(id); +			} +			else +			{ +				impl.mAskGroupQueue.insert(id); +			}  		}  		impl.mReplyQueue.push_back(PendingReply(id, callback, user_data));  	} @@ -550,6 +567,19 @@ void LLCacheName::deleteEntriesOlderThan(S32 secs)  			impl.mCache.erase(curiter);  		}  	} + +	// These are pending requests that we never heard back from. +	U32 pending_expire_time = now - PENDING_TIMEOUT_SECS; +	for(PendingQueue::iterator p_iter = impl.mPendingQueue.begin(); +		p_iter != impl.mPendingQueue.end(); ) +	{ +		PendingQueue::iterator p_curitor = p_iter++; +  +		if (p_curitor->second < pending_expire_time) +		{ +			impl.mPendingQueue.erase(p_curitor); +		} +	}  } @@ -579,6 +609,18 @@ void LLCacheName::dump()  	}  } +void LLCacheName::dumpStats() +{ +	llinfos << "Queue sizes: " +			<< " Cache=" << impl.mCache.size() +			<< " AskName=" << impl.mAskNameQueue.size() +			<< " AskGroup=" << impl.mAskGroupQueue.size() +			<< " Pending=" << impl.mPendingQueue.size() +			<< " Reply=" << impl.mReplyQueue.size() +			<< " Observers=" << impl.mObservers.size() +			<< llendl; +} +  void LLCacheName::Impl::processPendingAsks()  {  	sendRequest(_PREHASH_UUIDNameRequest, mAskNameQueue); @@ -682,7 +724,23 @@ void LLCacheName::Impl::notifyObservers(const LLUUID& id,  	}  } +bool LLCacheName::Impl::isRequestPending(const LLUUID& id) +{ +	U32 now = (U32)time(NULL); +	U32 expire_time = now - PENDING_TIMEOUT_SECS; +	PendingQueue::iterator iter = mPendingQueue.find(id); + +	if (iter == mPendingQueue.end() +		|| (iter->second < expire_time) ) +	{ +		mPendingQueue[id] = now; +		return false; +	} + +	return true; +} +	  void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)  {  	// You should only get this message if the cache is at the simulator @@ -720,13 +778,16 @@ void LLCacheName::Impl::processUUIDRequest(LLMessageSystem* msg, bool isGroup)  		}  		else  		{ -			if (isGroup) +			if (!isRequestPending(id))  			{ -				mAskGroupQueue.push_back(id); -			} -			else -			{ -				mAskNameQueue.push_back(id); +				if (isGroup) +				{ +					mAskGroupQueue.insert(id); +				} +				else +				{ +					mAskNameQueue.insert(id); +				}  			}  			mReplyQueue.push_back(PendingReply(id, fromHost)); @@ -750,6 +811,8 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)  			mCache[id] = entry;  		} +		mPendingQueue.erase(id); +  		entry->mIsGroup = isGroup;  		entry->mCreateTime = (U32)time(NULL);  		if (!isGroup) diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h index af49903c88..c4f88ac490 100644 --- a/indra/llmessage/llcachename.h +++ b/indra/llmessage/llcachename.h @@ -78,7 +78,8 @@ public:  	void deleteEntriesOlderThan(S32 secs);  	// Debugging -	void dump(); +	void dump();		// Dumps the contents of the cache +	void dumpStats();	// Dumps the sizes of the cache and associated queues.  private:  	class Impl; diff --git a/indra/llmessage/llhost.cpp b/indra/llmessage/llhost.cpp index d395188b72..6a74cfe831 100644 --- a/indra/llmessage/llhost.cpp +++ b/indra/llmessage/llhost.cpp @@ -28,7 +28,7 @@ LLHost LLHost::invalid(INVALID_PORT,INVALID_HOST_IP_ADDRESS);  LLHost::LLHost(const std::string& ip_and_port)  {  	std::string::size_type colon_index = ip_and_port.find(":"); -	if (colon_index != std::string::npos) +	if (colon_index == std::string::npos)  	{  		mIP = ip_string_to_u32(ip_and_port.c_str());  		mPort = 0; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 121cbd2e68..92c309f1bc 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -18,6 +18,7 @@  #include "llvfile.h"  #include "llvfs.h" +#include "message.h"  #include <curl/curl.h>  const F32 HTTP_REQUEST_EXPIRY_SECS = 60.0f; @@ -92,6 +93,14 @@ namespace  			if (200 <= mStatus && mStatus < 300)  			{  				LLSDSerialize::fromXML(content, istr); +/* +				const S32 parseError = -1; +				if(LLSDSerialize::fromXML(content, istr) == parseError) +				{ +					mStatus = 498; +					mReason = "Client Parse Error"; +				} +*/  			}  			if (mResponder.get()) @@ -232,10 +241,17 @@ static void request(const std::string& url, LLURLRequest::ERequestAction method,  	}  	req->setCallback(new LLHTTPClientURLAdaptor(responder)); +	if (method == LLURLRequest::HTTP_POST  &&  gMessageSystem) { +		req->addHeader(llformat("X-SecondLife-UDP-Listen-Port: %d", +								gMessageSystem->mPort).c_str()); +   	} +	  	if (method == LLURLRequest::HTTP_PUT || method == LLURLRequest::HTTP_POST)  	{ -		req->addHeader(llformat("Content-Type: %s", body_injector->contentType()).c_str()); -		chain.push_back(LLIOPipe::ptr_t(body_injector)); +		req->addHeader(llformat("Content-Type: %s", +								body_injector->contentType()).c_str()); + +   		chain.push_back(LLIOPipe::ptr_t(body_injector));  	}  	chain.push_back(LLIOPipe::ptr_t(req)); @@ -293,6 +309,14 @@ LLSD LLHTTPClient::blockingGet(const std::string& url)  	LLHTTPBuffer http_buffer; +	// Without this timeout, blockingGet() calls have been observed to take +	// up to 90 seconds to complete.  Users of blockingGet() already must  +	// check the HTTP return code for validity, so this will not introduce +	// new errors.  A 5 second timeout will succeed > 95% of the time (and  +	// probably > 99% of the time) based on my statistics. JC +	curl_easy_setopt(curlp, CURLOPT_NOSIGNAL, 1);	// don't use SIGALRM for timeouts +	curl_easy_setopt(curlp, CURLOPT_TIMEOUT, 5);	// seconds +  	curl_easy_setopt(curlp, CURLOPT_WRITEFUNCTION, LLHTTPBuffer::curl_write);  	curl_easy_setopt(curlp, CURLOPT_WRITEDATA, &http_buffer);  	curl_easy_setopt(curlp, CURLOPT_URL, url.c_str()); @@ -382,7 +406,7 @@ namespace boost  	void intrusive_ptr_release(LLHTTPClient::Responder* p)  	{ -		if(0 == --p->mReferenceCount) +		if(p && 0 == --p->mReferenceCount)  		{  			delete p;  		} diff --git a/indra/llmessage/llhttpsender.cpp b/indra/llmessage/llhttpsender.cpp new file mode 100644 index 0000000000..4152dedae5 --- /dev/null +++ b/indra/llmessage/llhttpsender.cpp @@ -0,0 +1,70 @@ +/**  + * @file llhttpsender.cpp + * @brief Abstracts details of sending messages via HTTP. + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "linden_common.h" + +#include "llhttpsender.h" + +#include <map> +#include <sstream> + +#include "llhost.h" +#include "llsd.h" + +namespace +{ +	typedef std::map<LLHost, LLHTTPSender*> SenderMap; +	static SenderMap senderMap; +} + +//virtual  +LLHTTPSender::~LLHTTPSender() +{ +} + +//virtual  +void LLHTTPSender::send(const LLHost& host, const char* name,  +						const LLSD& body,  +						LLHTTPClient::ResponderPtr response) const +{ +	// Default implementation inserts sender, message and sends HTTP POST +	std::ostringstream stream; +	stream << "http://" << host << "/trusted-message/" << name; +	llinfos << "LLHTTPSender::send: POST to " << stream.str() << llendl; +	LLHTTPClient::post(stream.str(), body, response); +} + +//static  +void LLHTTPSender::setSender(const LLHost& host, LLHTTPSender* sender) +{ +	llinfos << "LLHTTPSender::setSender " << host << llendl; +	senderMap[host] = sender; +} + +//static +const LLHTTPSender& LLHTTPSender::getSender(const LLHost& host) +{ +	static LLHTTPSender defaultSender; +	SenderMap::const_iterator iter = senderMap.find(host); +	if(iter == senderMap.end()) +	{ +		return defaultSender; +	} +	return *(iter->second); +} + +//static  +void LLHTTPSender::clearSender(const LLHost& host) +{ +	SenderMap::iterator iter = senderMap.find(host); +	if(iter != senderMap.end()) +	{ +		delete iter->second; +		senderMap.erase(iter); +	} +} diff --git a/indra/llmessage/llhttpsender.h b/indra/llmessage/llhttpsender.h new file mode 100644 index 0000000000..a9f42579c2 --- /dev/null +++ b/indra/llmessage/llhttpsender.h @@ -0,0 +1,38 @@ +/**  + * @file llhttpsender.h + * @brief Abstracts details of sending messages via HTTP. + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_HTTP_SENDER_H +#define LL_HTTP_SENDER_H + +#include "llhttpclient.h" + +class LLHost; +class LLSD; + +class LLHTTPSender +{ + public: + +	virtual ~LLHTTPSender(); + +	/** @brief Send message to host with body, call response when done */  +	virtual void send(const LLHost& host,  +					  const char* message, const LLSD& body,  +					  LLHTTPClient::ResponderPtr response) const; + +	/** @brief Set sender for host, takes ownership of sender. */ +	static void setSender(const LLHost& host, LLHTTPSender* sender); + +	/** @brief Get sender for host, retains ownership of returned sender. */ +	static const LLHTTPSender& getSender(const LLHost& host); +	 +	/** @brief Clear sender for host. */ +	static void clearSender(const LLHost& host); +}; + +#endif // LL_HTTP_SENDER_H diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp index 944785c3a5..28886108ea 100644 --- a/indra/llmessage/llinstantmessage.cpp +++ b/indra/llmessage/llinstantmessage.cpp @@ -16,6 +16,7 @@  #include "lluuid.h"  #include "llsd.h"  #include "llsdserialize.h" +#include "llsdutil.h"  #include "llmemory.h"  #include "message.h" @@ -290,6 +291,35 @@ void LLIMInfo::unpackMessageBlock(LLMessageSystem* msg)  	}  } +LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info) +{ +	LLSD param_version; +	param_version["version"] = 1; +	LLSD param_message; +	param_message["from_id"] = im_info->mFromID; +	param_message["from_group"] = im_info->mFromGroup; +	param_message["to_id"] = im_info->mToID; +	param_message["from_name"] = im_info->mName; +	param_message["message"] = im_info->mMessage; +	param_message["type"] = (S32)im_info->mIMType; +	param_message["id"] = im_info->mID; +	param_message["timestamp"] = (S32)im_info->mTimeStamp; +	param_message["offline"] = (S32)im_info->mOffline; +	param_message["parent_estate_id"] = (S32)im_info->mParentEstateID; +	param_message["region_id"] = im_info->mRegionID; +	param_message["position"] = ll_sd_from_vector3(im_info->mPosition); +	if (im_info->mData) param_message["data"] = im_info->mData; +	LLSD param_agent; +	param_agent["agent_id"] = im_info->mFromID; + +	LLSD params; +	params.append(param_version); +	params.append(param_message); +	params.append(param_agent); + +	return params; +} +  LLPointer<LLIMInfo> LLIMInfo::clone()  {  	return new LLIMInfo( diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h index c8138cf491..99b2734a70 100644 --- a/indra/llmessage/llinstantmessage.h +++ b/indra/llmessage/llinstantmessage.h @@ -74,17 +74,19 @@ enum EInstantMessage  	// communicate with each other.  	// -	// Start a session, or add users to a session. +	// Add users to a session.  	IM_SESSION_ADD = 13, -	// Start a session, but don't prune offline users -	IM_SESSION_OFFLINE_ADD = 14, +	// IM sent automatically on call for help,  +	// sets up a way for each Helper reached to teleport to the +	// helpee +	IM_SESSION_911_SEND = 14,  	// start a session with your gruop  	IM_SESSION_GROUP_START = 15,  	// start a session without a calling card (finder or objects) -	IM_SESSION_CARDLESS_START = 16, +	IM_SESSION_CONFERENCE_START = 16,  	// send a message to a session.  	IM_SESSION_SEND = 17, @@ -123,9 +125,9 @@ enum EInstantMessage  	// Binary bucket contains the name of the session.  	IM_SESSION_911_START = 29, -	// IM sent automatically on call for help,  -	// sends a lure to each Helper reached -	IM_LURE_911 = 30, +	// IM for requesting to teleport to the creator +	// of a livehelp session (assuming they are verified first) +	IM_TELEPORT_911 = 30,  	// a message generated by a script which we don't want to  	// be sent through e-mail.  Similar to IM_FROM_TASK, but @@ -266,6 +268,7 @@ public:  	S32 mTTL;  }; +LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info);  void pack_instant_message(  	LLMessageSystem* msgsystem, diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index c1a9bc442e..869012e431 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -27,6 +27,8 @@  #include "llsdserialize_xml.h"  #include "llstl.h" +#include <sstream> +  static const char HTTP_VERSION_STR[] = "HTTP/1.0";  static const std::string CONTEXT_REQUEST("request");  static const std::string HTTP_VERB_GET("GET"); @@ -374,7 +376,7 @@ LLIOPipe::EStatus LLHTTPResponseHeader::process_impl(  class LLHTTPResponder : public LLIOPipe  {  public: -	LLHTTPResponder(const LLHTTPNode& tree); +	LLHTTPResponder(const LLHTTPNode& tree, const LLSD& ctx);  	~LLHTTPResponder();  protected: @@ -435,6 +437,7 @@ protected:  		STATE_SHORT_CIRCUIT  	}; +	LLSD mBuildContext;  	EState mState;  	U8* mLastRead;  	std::string mVerb; @@ -443,12 +446,14 @@ protected:  	std::string mQuery;  	std::string mVersion;  	S32 mContentLength; +	LLSD mHeaders;  	// handle the urls  	const LLHTTPNode& mRootNode;  }; -LLHTTPResponder::LLHTTPResponder(const LLHTTPNode& tree) : +LLHTTPResponder::LLHTTPResponder(const LLHTTPNode& tree, const LLSD& ctx) : +	mBuildContext(ctx),  	mState(STATE_NOTHING),  	mLastRead(NULL),  	mContentLength(0), @@ -636,6 +641,11 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  						lldebugs << "Content-Length: " << value << llendl;  						mContentLength = atoi(value.c_str());  					} +					else +					{ +						LLString::trimTail(value); +						mHeaders[name] = value; +					}  				}  			}  		} @@ -701,6 +711,11 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  			chain.push_back(LLIOPipe::ptr_t(new LLIOFlush));  			context[CONTEXT_REQUEST]["path"] = mPath;  			context[CONTEXT_REQUEST]["query-string"] = mQuery; +			context[CONTEXT_REQUEST]["remote-host"] +				= mBuildContext["remote-host"]; +			context[CONTEXT_REQUEST]["remote-port"] +				= mBuildContext["remote-port"]; +			context[CONTEXT_REQUEST]["headers"] = mHeaders;  			const LLChainIOFactory* protocolHandler  				= node->getProtocolHandler(); @@ -785,9 +800,10 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl( -void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, const LLHTTPNode& root) +void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, +		const LLHTTPNode& root, const LLSD& ctx)  { -	chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root))); +	chain.push_back(LLIOPipe::ptr_t(new LLHTTPResponder(root, ctx)));  } @@ -796,7 +812,7 @@ class LLHTTPResponseFactory : public LLChainIOFactory  public:  	bool build(LLPumpIO::chain_t& chain, LLSD ctx) const  	{ -		LLCreateHTTPPipe(chain, mTree); +		LLCreateHTTPPipe(chain, mTree, ctx);  		return true;  	} diff --git a/indra/llmessage/lliohttpserver.h b/indra/llmessage/lliohttpserver.h index 05dfdc4bf7..f11a1eccf6 100644 --- a/indra/llmessage/lliohttpserver.h +++ b/indra/llmessage/lliohttpserver.h @@ -31,7 +31,8 @@ LLHTTPNode& LLCreateHTTPServer(apr_pool_t* pool, LLPumpIO& pump, U16 port);  	 *   for example), use the helper templates below.  	 */ -void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, const LLHTTPNode& root); +void LLCreateHTTPPipe(LLPumpIO::chain_t& chain, +		const LLHTTPNode& root, const LLSD& ctx);  	/**< Create a pipe on the chain that handles HTTP requests.  	 *   The requests are served by the node tree given at root.  	 * diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h index 5cbe3d8743..6f7fbe652d 100644 --- a/indra/llmessage/lliopipe.h +++ b/indra/llmessage/lliopipe.h @@ -237,7 +237,7 @@ namespace boost  	}  	inline void intrusive_ptr_release(LLIOPipe* p)  	{ -		if(0 == --p->mReferenceCount) +		if(p && 0 == --p->mReferenceCount)  		{  			delete p;  		} diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp index 7649fef0cf..7c33153086 100644 --- a/indra/llmessage/lliosocket.cpp +++ b/indra/llmessage/lliosocket.cpp @@ -519,9 +519,20 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(  	if(llsocket)  	{  		PUMP_DEBUG; + +		apr_sockaddr_t* remote_addr; +		apr_socket_addr_get(&remote_addr, APR_REMOTE, socket); +		 +		char* remote_host_string; +		apr_sockaddr_ip_get(&remote_host_string, remote_addr); + +		LLSD context; +		context["remote-host"] = remote_host_string; +		context["remote-port"] = remote_addr->port; +  		LLPumpIO::chain_t chain;  		chain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(llsocket))); -		if(mReactor->build(chain, LLSD())) +		if(mReactor->build(chain, context))  		{  			chain.push_back(LLIOPipe::ptr_t(new LLIOSocketWriter(llsocket)));  			pump->addChain(chain, mResponseTimeout); diff --git a/indra/llmessage/llmessagebuilder.cpp b/indra/llmessage/llmessagebuilder.cpp new file mode 100644 index 0000000000..d467e6d808 --- /dev/null +++ b/indra/llmessage/llmessagebuilder.cpp @@ -0,0 +1,18 @@ +/**  + * @file llmessagebuilder.cpp + * @brief LLMessageBuilder class implementation + * + * Copyright (c) 2006-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "linden_common.h" + +#include "llmessagebuilder.h" + +//virtual +LLMessageBuilder::~LLMessageBuilder() +{ +	// even abstract base classes need a concrete destructor +} + diff --git a/indra/llmessage/llmessagebuilder.h b/indra/llmessage/llmessagebuilder.h new file mode 100644 index 0000000000..7ae09c54d5 --- /dev/null +++ b/indra/llmessage/llmessagebuilder.h @@ -0,0 +1,70 @@ +#ifndef LL_LLMESSAGEBUILDER_H +#define LL_LLMESSAGEBUILDER_H + +#include <string> + +#include "stdtypes.h" + +class LLMsgData; +class LLQuaternion; +class LLSD; +class LLUUID; +class LLVector3; +class LLVector3d; +class LLVector4; + +class LLMessageBuilder +{ +public: + +	//CLASS_LOG_TYPE(LLMessageBuilder); +	 +	virtual ~LLMessageBuilder(); +	virtual void newMessage(const char *name) = 0; + +	virtual void nextBlock(const char* blockname) = 0; +	virtual BOOL removeLastBlock() = 0; // TODO: babbage: remove this horror + +	/** All add* methods expect pointers to canonical strings. */ +	virtual void addBinaryData(const char *varname, const void *data,  +							   S32 size) = 0; +	virtual void addBOOL(const char* varname, BOOL b) = 0; +	virtual void addS8(const char *varname, S8 s) = 0; +	virtual void addU8(const char *varname, U8 u) = 0; +	virtual void addS16(const char *varname, S16 i) = 0; +	virtual void addU16(const char *varname, U16 i) = 0; +	virtual void addF32(const char *varname, F32 f) = 0; +	virtual void addS32(const char *varname, S32 s) = 0; +	virtual void addU32(const char *varname, U32 u) = 0; +	virtual void addU64(const char *varname, U64 lu) = 0; +	virtual void addF64(const char *varname, F64 d) = 0; +	virtual void addVector3(const char *varname, const LLVector3& vec) = 0; +	virtual void addVector4(const char *varname, const LLVector4& vec) = 0; +	virtual void addVector3d(const char *varname, const LLVector3d& vec) = 0; +	virtual void addQuat(const char *varname, const LLQuaternion& quat) = 0; +	virtual void addUUID(const char *varname, const LLUUID& uuid) = 0; +	virtual void addIPAddr(const char *varname, const U32 ip) = 0; +	virtual void addIPPort(const char *varname, const U16 port) = 0; +	virtual void addString(const char* varname, const char* s) = 0; +	virtual void addString(const char* varname, const std::string& s) = 0; + +	virtual BOOL isMessageFull(const char* blockname) const = 0; +	virtual void compressMessage(U8*& buf_ptr, U32& buffer_length) = 0; +	virtual S32 getMessageSize() = 0; + +	virtual BOOL isBuilt() const = 0; +	virtual BOOL isClear() const = 0; +	virtual U32 buildMessage(U8* buffer, U32 buffer_size) = 0;  +        /**< Return built message size */ +	virtual void clearMessage() = 0; + +	// TODO: babbage: remove this horror +	virtual void setBuilt(BOOL b) = 0; + +	virtual const char* getMessageName() const = 0; + +	virtual void copyFromMessageData(const LLMsgData& data) = 0; +	virtual void copyFromLLSD(const LLSD& data) = 0; +}; + +#endif //  LL_LLMESSAGEBUILDER_H diff --git a/indra/llmessage/llmessageconfig.cpp b/indra/llmessage/llmessageconfig.cpp new file mode 100644 index 0000000000..a2b0bc5efa --- /dev/null +++ b/indra/llmessage/llmessageconfig.cpp @@ -0,0 +1,210 @@ +/**  + * @file llmessageconfig.cpp + * @brief Live file handling for messaging + * + * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "linden_common.h" + +#include "llmessageconfig.h" +#include "llfile.h" +#include "lllivefile.h" +#include "llsd.h" +#include "llsdserialize.h" + +static const char messageConfigFileName[] = "message.xml"; +static const F32 messageConfigRefreshRate = 5.0; // seconds +static std::string sServerName = ""; +static std::string sConfigDir = ""; + +class LLMessageConfigFile : public LLLiveFile +{ +private: +	LLMessageConfigFile() +        : LLLiveFile(fileName(), messageConfigRefreshRate), +		  mChanged(false) +            { } + +    static std::string fileName(); +     +public: +	static LLMessageConfigFile& instance(); +		// return the singleton configuration file + +protected: +	/* virtual */ void loadFile(); +	void loadServerDefaults(const LLSD& data); +	void loadMessages(const LLSD& data); + +public: +    bool mChanged; +	 +	std::string mServerDefault; +	LLSD mMessages; +}; + +std::string LLMessageConfigFile::fileName() +{ +    std::ostringstream ostr; +	ostr << sConfigDir//gAppSimp->getOption("configdir").asString() +		<< "/" << messageConfigFileName; +	return ostr.str(); +} + +LLMessageConfigFile& LLMessageConfigFile::instance() +{ +	static LLMessageConfigFile the_file; +	the_file.checkAndReload(); +	return the_file; +} + +// virtual +void LLMessageConfigFile::loadFile() +{ +	LLSD data; +    { +        llifstream file(filename().c_str()); +        if (file.is_open()) +        { +			llinfos << "Loading message.xml file at " << fileName() << llendl; +            LLSDSerialize::fromXML(data, file); +        } + +        if (data.isUndefined()) +        { +            llinfos << "LLMessageConfigFile::loadFile: file missing," +				" ill-formed, or simply undefined; not changing the" +				" file" << llendl; +            return; +        } +    } +	loadServerDefaults(data); +	loadMessages(data); +} + +void LLMessageConfigFile::loadServerDefaults(const LLSD& data) +{ +	mServerDefault = data["serverDefaults"][sServerName].asString(); +	lldebugs << "loading default " << mServerDefault << llendl; +} + +void LLMessageConfigFile::loadMessages(const LLSD& data) +{ +	mMessages = data["messages"]; +	std::ostringstream out; +	LLSDXMLFormatter *formatter = new LLSDXMLFormatter; +	formatter->format(mMessages, out); +	lldebugs << "loading ... " << out.str() +			<< " LLMessageConfigFile::loadMessages loaded " +			<< mMessages.size() << " messages" << llendl; +} + + +//--------------------------------------------------------------- +// LLMessageConfig +//--------------------------------------------------------------- + +//static +void LLMessageConfig::initClass(const std::string& server_name, +								const std::string& config_dir) +{ +	sServerName = server_name; +	sConfigDir = config_dir; +	(void) LLMessageConfigFile::instance(); +	llinfos << "LLMessageConfig::intiClass config file " +			<< config_dir << "/" << messageConfigFileName << llendl; +} + +//static +bool LLMessageConfig::isServerDefaultBuilderLLSD() +{ +	if (sServerName.empty()) +	{ +		llerrs << "LLMessageConfig::isServerDefaultBuilderLLSD() before" +				<< " LLMessageConfig::initClass()" << llendl; +	} +	LLMessageConfigFile& file = LLMessageConfigFile::instance(); +	return (file.mServerDefault == "llsd"); +} + +//static +bool LLMessageConfig::isServerDefaultBuilderTemplate() +{ +	if (sServerName.empty()) +	{ +		llerrs << "LLMessageConfig::isServerDefaultBuilderTemplate() before" +				<< " LLMessageConfig::initClass()" << llendl; +	} +	LLMessageConfigFile& file = LLMessageConfigFile::instance(); +	return (file.mServerDefault == "template"); +} + +//static +bool LLMessageConfig::isMessageBuiltLLSD(const std::string& msg_name) +{ +	if (sServerName.empty()) +	{ +		llerrs << "LLMessageConfig::isMessageBuiltLLSD(name) before" +				<< " LLMessageConfig::initClass()" << llendl; +	} +	LLMessageConfigFile& file = LLMessageConfigFile::instance(); +	LLSD config = file.mMessages[msg_name]; +	if (!config.has("builder")) +	{ +		return isServerDefaultBuilderLLSD(); +	} +	return (config["builder"].asString() == "llsd"); +} + +//static +bool LLMessageConfig::isMessageBuiltTemplate(const std::string& msg_name) +{ +	if (sServerName.empty()) +	{ +		llerrs << "LLMessageConfig::isMessageBuiltTemplate(name) before" +				<< " LLMessageConfig::initClass()" << llendl; +	} +	LLMessageConfigFile& file = LLMessageConfigFile::instance(); +	LLSD config = file.mMessages[msg_name]; +	if (!config.has("builder")) +	{ +		return isServerDefaultBuilderTemplate(); +	} +	return (config["builder"].asString() == "template"); +} + +//static +bool LLMessageConfig::isMessageTrusted(const std::string& msg_name) +{ +	if (sServerName.empty()) +	{ +		llerrs << "LLMessageConfig::isMessageTrusted(name) before" +				<< " LLMessageConfig::initClass()" << llendl; +	} +	LLMessageConfigFile& file = LLMessageConfigFile::instance(); +	LLSD config = file.mMessages[msg_name]; +	if (!config.has("trusted-sender")) +	{ +		return false; +	} +	return config["trusted-sender"].asBoolean(); +} + +//static +bool LLMessageConfig::isValidUntrustedMessage(const std::string& msg_name) +{ +	if (sServerName.empty()) +	{ +		llerrs << "LLMessageConfig::isMessageTrusted(name) before" +				<< " LLMessageConfig::initClass()" << llendl; +	} +	LLMessageConfigFile& file = LLMessageConfigFile::instance(); +	LLSD config = file.mMessages[msg_name]; +	if (!config.has("trusted-sender")) +	{ +		return false; +	} +	return !(config["trusted-sender"].asBoolean()); +} diff --git a/indra/llmessage/llmessageconfig.h b/indra/llmessage/llmessageconfig.h new file mode 100644 index 0000000000..2fb6f2077e --- /dev/null +++ b/indra/llmessage/llmessageconfig.h @@ -0,0 +1,31 @@ +/**  + * @file llmessageconfig.h + * @brief Live file handling for messaging + * + * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_MESSAGECONFIG_H +#define LL_MESSAGECONFIG_H + +#include <string> + +class LLMessageConfig +{ +public: +	static void initClass(const std::string& server_name, +						  const std::string& config_dir); +		// force loading of config file during startup process +		// so it can be used for startup features + +	static bool isServerDefaultBuilderLLSD(); +	static bool isServerDefaultBuilderTemplate(); + +	// For individual messages +	static bool isMessageBuiltLLSD(const std::string& msg_name); +	static bool isMessageBuiltTemplate(const std::string& msg_name); +	static bool isMessageTrusted(const std::string& msg_name); +	static bool isValidUntrustedMessage(const std::string& msg_name); +}; +#endif // LL_MESSAGECONFIG_H diff --git a/indra/llmessage/llmessagereader.cpp b/indra/llmessage/llmessagereader.cpp new file mode 100644 index 0000000000..4824480e32 --- /dev/null +++ b/indra/llmessage/llmessagereader.cpp @@ -0,0 +1,35 @@ +#include "llmessagereader.h" + +static BOOL sTimeDecodes = FALSE; + +static F32 sTimeDecodesSpamThreshold = 0.05f; + +//virtual +LLMessageReader::~LLMessageReader() +{ +	// even abstract base classes need a concrete destructor +} + +//static  +void LLMessageReader::setTimeDecodes(BOOL b) +{ +	sTimeDecodes = b; +} + +//static  +void LLMessageReader::setTimeDecodesSpamThreshold(F32 seconds) +{ +	sTimeDecodesSpamThreshold = seconds; +} + +//static  +BOOL LLMessageReader::getTimeDecodes() +{ +	return sTimeDecodes; +} + +//static  +F32 LLMessageReader::getTimeDecodesSpamThreshold() +{ +	return sTimeDecodesSpamThreshold; +} diff --git a/indra/llmessage/llmessagereader.h b/indra/llmessage/llmessagereader.h new file mode 100644 index 0000000000..33ce9289f5 --- /dev/null +++ b/indra/llmessage/llmessagereader.h @@ -0,0 +1,59 @@ +#ifndef LL_LLMESSAGEREADER_H +#define LL_LLMESSAGEREADER_H + +#include "stdtypes.h" + +class LLHost; +class LLMessageBuilder; +class LLMsgData; +class LLQuaternion; +class LLUUID; +class LLVector3; +class LLVector3d; +class LLVector4; + +class LLMessageReader +{ + public: + +	virtual ~LLMessageReader(); + +	/** All get* methods expect pointers to canonical strings. */ +	virtual void getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX) = 0; +	virtual void getBOOL(const char *block, const char *var, BOOL &data, S32 blocknum = 0) = 0; +	virtual void getS8(const char *block, const char *var, S8 &data, S32 blocknum = 0) = 0; +	virtual void getU8(const char *block, const char *var, U8 &data, S32 blocknum = 0) = 0; +	virtual void getS16(const char *block, const char *var, S16 &data, S32 blocknum = 0) = 0; +	virtual void getU16(const char *block, const char *var, U16 &data, S32 blocknum = 0) = 0; +	virtual void getS32(const char *block, const char *var, S32 &data, S32 blocknum = 0) = 0; +	virtual void getF32(const char *block, const char *var, F32 &data, S32 blocknum = 0) = 0; +	virtual void getU32(const char *block, const char *var, U32 &data, S32 blocknum = 0) = 0; +	virtual void getU64(const char *block, const char *var, U64 &data, S32 blocknum = 0) = 0; +	virtual void getF64(const char *block, const char *var, F64 &data, S32 blocknum = 0) = 0; +	virtual void getVector3(const char *block, const char *var, LLVector3 &vec, S32 blocknum = 0) = 0; +	virtual void getVector4(const char *block, const char *var, LLVector4 &vec, S32 blocknum = 0) = 0; +	virtual void getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0) = 0; +	virtual void getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0) = 0; +	virtual void getUUID(const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0) = 0; +	virtual void getIPAddr(const char *block, const char *var, U32 &ip, S32 blocknum = 0) = 0; +	virtual void getIPPort(const char *block, const char *var, U16 &port, S32 blocknum = 0) = 0; +	virtual void getString(const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0) = 0; + +	virtual S32	getNumberOfBlocks(const char *blockname) = 0; +	virtual S32	getSize(const char *blockname, const char *varname) = 0; +	virtual S32	getSize(const char *blockname, S32 blocknum, const char *varname) = 0; + +	virtual void clearMessage() = 0; + +	virtual const char* getMessageName() const = 0; +	virtual S32 getMessageSize() const = 0; + +	virtual void copyToBuilder(LLMessageBuilder&) const = 0; + +	static void setTimeDecodes(BOOL b); +	static BOOL getTimeDecodes(); +	static void setTimeDecodesSpamThreshold(F32 seconds); +	static F32 getTimeDecodesSpamThreshold(); +}; + +#endif // LL_LLMESSAGEREADER_H diff --git a/indra/llmessage/llmessagetemplate.cpp b/indra/llmessage/llmessagetemplate.cpp new file mode 100644 index 0000000000..026843d6ec --- /dev/null +++ b/indra/llmessage/llmessagetemplate.cpp @@ -0,0 +1,146 @@ +#include "linden_common.h" + +#include "llmessagetemplate.h" + +#include "message.h" + +void LLMsgVarData::addData(const void *data, S32 size, EMsgVariableType type, S32 data_size) +{ +	mSize = size; +	mDataSize = data_size; +	if ( (type != MVT_VARIABLE) && (type != MVT_FIXED)  +		 && (mType != MVT_VARIABLE) && (mType != MVT_FIXED)) +	{ +		if (mType != type) +		{ +			llwarns << "Type mismatch in LLMsgVarData::addData for " << mName +					<< llendl; +		} +	} +	if(size) +	{ +		delete mData; // Delete it if it already exists +		mData = new U8[size]; +		htonmemcpy(mData, data, mType, size); +	} +} + +void LLMsgData::addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size) +{ +	// remember that if the blocknumber is > 0 then the number is appended to the name +	char *namep = (char *)blockname; +	LLMsgBlkData* block_data = mMemberBlocks[namep]; +	if (block_data->mBlockNumber) +	{ +		namep += block_data->mBlockNumber; +		block_data->addData(varname, data, size, type, data_size); +	} +	else +	{ +		block_data->addData(varname, data, size, type, data_size); +	} +} + +// LLMessageVariable functions and friends + +std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg) +{ +	s << "\t\t" << msg.mName << " ("; +	switch (msg.mType) +	{ +	case MVT_FIXED: +		s << "Fixed, " << msg.mSize << " bytes total)\n"; +		break; +	case MVT_VARIABLE: +		s << "Variable, " << msg.mSize << " bytes of size info)\n"; +		break; +	default: +		s << "Unknown\n"; +		break; +	} +	return s; +} + +// LLMessageBlock functions and friends + +std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg) +{ +	s << "\t" << msg.mName << " ("; +	switch (msg.mType) +	{ +	case MBT_SINGLE: +		s << "Fixed"; +		break; +	case MBT_MULTIPLE: +		s << "Multiple - " << msg.mNumber << " copies"; +		break; +	case MBT_VARIABLE: +		s << "Variable"; +		break; +	default: +		s << "Unknown"; +		break; +	} +	if (msg.mTotalSize != -1) +	{ +		s << ", " << msg.mTotalSize << " bytes each, " << msg.mNumber*msg.mTotalSize << " bytes total)\n"; +	} +	else +	{ +		s << ")\n"; +	} + + +	for (LLMessageBlock::message_variable_map_t::iterator iter = msg.mMemberVariables.begin(); +		 iter != msg.mMemberVariables.end(); iter++) +	{ +		LLMessageVariable& ci = *(iter->second); +		s << ci; +	} + +	return s; +} + +// LLMessageTemplate functions and friends + +std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg) +{ +	switch (msg.mFrequency) +	{ +	case MFT_HIGH: +		s << "========================================\n" << "Message #" << msg.mMessageNumber << "\n" << msg.mName << " ("; +		s << "High"; +		break; +	case MFT_MEDIUM: +		s << "========================================\n" << "Message #"; +		s << (msg.mMessageNumber & 0xFF) << "\n" << msg.mName << " ("; +		s << "Medium"; +		break; +	case MFT_LOW: +		s << "========================================\n" << "Message #"; +		s << (msg.mMessageNumber & 0xFFFF) << "\n" << msg.mName << " ("; +		s << "Low"; +		break; +	default: +		s << "Unknown"; +		break; +	} + +	if (msg.mTotalSize != -1) +	{ +		s << ", " << msg.mTotalSize << " bytes total)\n"; +	} +	else +	{ +		s << ")\n"; +	} +	 +	for (LLMessageTemplate::message_block_map_t::iterator iter = msg.mMemberBlocks.begin(); +		 iter != msg.mMemberBlocks.end(); iter++) +	{ +		LLMessageBlock* ci = iter->second; +		s << *ci; +	} + +	return s; +} diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h new file mode 100644 index 0000000000..8847ddc0d9 --- /dev/null +++ b/indra/llmessage/llmessagetemplate.h @@ -0,0 +1,356 @@ +#ifndef LL_LLMESSAGETEMPLATE_H +#define LL_LLMESSAGETEMPLATE_H + +#include "lldarray.h" +#include "message.h" // TODO: babbage: Remove... +#include "llstl.h" + +class LLMsgVarData +{ +public: +	LLMsgVarData() : mName(NULL), mSize(-1), mDataSize(-1), mData(NULL), mType(MVT_U8) +	{ +	} + +	LLMsgVarData(const char *name, EMsgVariableType type) : mSize(-1), mDataSize(-1), mData(NULL), mType(type) +	{ +		mName = (char *)name;  +	} + +	~LLMsgVarData()  +	{ +		// copy constructor just copies the mData pointer, so only delete mData explicitly +	} +	 +	void deleteData()  +	{ +		delete[] mData; +		mData = NULL; +	} +	 +	void addData(const void *indata, S32 size, EMsgVariableType type, S32 data_size = -1); + +	char *getName() const	{ return mName; } +	S32 getSize() const		{ return mSize; } +	void *getData()			{ return (void*)mData; } +	const void *getData() const { return (const void*)mData; } +	S32 getDataSize() const	{ return mDataSize; } +	EMsgVariableType getType() const	{ return mType; } + +protected: +	char				*mName; +	S32					mSize; +	S32					mDataSize; + +	U8					*mData; +	EMsgVariableType	mType; +}; + +class LLMsgBlkData +{ +public: +	LLMsgBlkData(const char *name, S32 blocknum) : mOffset(-1), mBlockNumber(blocknum), mTotalSize(-1)  +	{  +		mName = (char *)name;  +	} + +	~LLMsgBlkData() +	{ +		for (msg_var_data_map_t::iterator iter = mMemberVarData.begin(); +			 iter != mMemberVarData.end(); iter++) +		{ +			iter->deleteData(); +		} +	} + +	void addVariable(const char *name, EMsgVariableType type) +	{ +		LLMsgVarData tmp(name,type); +		mMemberVarData[name] = tmp; +	} + +	void addData(char *name, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1) +	{ +		LLMsgVarData* temp = &mMemberVarData[name]; // creates a new entry if one doesn't exist +		temp->addData(data, size, type, data_size); +	} + +	S32									mOffset; +	S32									mBlockNumber; +	typedef LLDynamicArrayIndexed<LLMsgVarData, const char *, 8> msg_var_data_map_t; +	msg_var_data_map_t					mMemberVarData; +	char								*mName; +	S32									mTotalSize; +}; + +class LLMsgData +{ +public: +	LLMsgData(const char *name) : mTotalSize(-1)  +	{  +		mName = (char *)name;  +	} +	~LLMsgData() +	{ +		for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer()); +	} + +	void addBlock(LLMsgBlkData *blockp) +	{ +		mMemberBlocks[blockp->mName] = blockp; +	} + +	void addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1); + +public: +	S32									mOffset; +	typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t; +	msg_blk_data_map_t					mMemberBlocks; +	char								*mName; +	S32									mTotalSize; +}; + +// LLMessage* classes store the template of messages +class LLMessageVariable +{ +public: +	LLMessageVariable() : mName(NULL), mType(MVT_NULL), mSize(-1) +	{ +	} + +	LLMessageVariable(char *name) : mType(MVT_NULL), mSize(-1) +	{ +		mName = name; +	} + +	LLMessageVariable(char *name, const EMsgVariableType type, const S32 size) : mType(type), mSize(size)  +	{ +		mName = gMessageStringTable.getString(name);  +	} +	 +	~LLMessageVariable() {} + +	friend std::ostream&	 operator<<(std::ostream& s, LLMessageVariable &msg); + +	EMsgVariableType getType() const				{ return mType; } +	S32	getSize() const								{ return mSize; } +	char *getName() const							{ return mName; } +protected: +	char				*mName; +	EMsgVariableType	mType; +	S32					mSize; +}; + + +typedef enum e_message_block_type +{ +	MBT_NULL, +	MBT_SINGLE, +	MBT_MULTIPLE, +	MBT_VARIABLE, +	MBT_EOF +} EMsgBlockType; + +class LLMessageBlock +{ +public: +	LLMessageBlock(char *name, EMsgBlockType type, S32 number = 1) : mType(type), mNumber(number), mTotalSize(0)  +	{  +		mName = gMessageStringTable.getString(name); +	} + +	~LLMessageBlock() +	{ +		for_each(mMemberVariables.begin(), mMemberVariables.end(), DeletePairedPointer()); +	} + +	void addVariable(char *name, const EMsgVariableType type, const S32 size) +	{ +		LLMessageVariable** varp = &mMemberVariables[name]; +		if (*varp != NULL) +		{ +			llerrs << name << " has already been used as a variable name!" << llendl; +		} +		*varp = new LLMessageVariable(name, type, size); +		if (((*varp)->getType() != MVT_VARIABLE) +			&&(mTotalSize != -1)) +		{ +			mTotalSize += (*varp)->getSize(); +		} +		else +		{ +			mTotalSize = -1; +		} +	} + +	EMsgVariableType getVariableType(char *name) +	{ +		return (mMemberVariables[name])->getType(); +	} + +	S32 getVariableSize(char *name) +	{ +		return (mMemberVariables[name])->getSize(); +	} + +	friend std::ostream&	 operator<<(std::ostream& s, LLMessageBlock &msg); + +	typedef std::map<const char *, LLMessageVariable*> message_variable_map_t; +	message_variable_map_t 					mMemberVariables; +	char									*mName; +	EMsgBlockType							mType; +	S32										mNumber; +	S32										mTotalSize; +}; + + +enum EMsgFrequency +{ +	MFT_NULL	= 0,  // value is size of message number in bytes +	MFT_HIGH	= 1, +	MFT_MEDIUM	= 2, +	MFT_LOW		= 4 +}; + +typedef enum e_message_trust +{ +	MT_TRUST, +	MT_NOTRUST +} EMsgTrust; + +enum EMsgEncoding +{ +	ME_UNENCODED, +	ME_ZEROCODED +}; + +class LLMessageTemplate +{ +public: +	LLMessageTemplate(const char *name, U32 message_number, EMsgFrequency freq) +		:  +		//mMemberBlocks(), +		mName(NULL), +		mFrequency(freq), +		mTrust(MT_NOTRUST), +		mEncoding(ME_ZEROCODED), +		mMessageNumber(message_number),  +		mTotalSize(0),  +		mReceiveCount(0), +		mReceiveBytes(0), +		mReceiveInvalid(0), +		mDecodeTimeThisFrame(0.f), +		mTotalDecoded(0), +		mTotalDecodeTime(0.f), +		mMaxDecodeTimePerMsg(0.f), +		mBanFromTrusted(false), +		mBanFromUntrusted(false), +		mHandlerFunc(NULL),  +		mUserData(NULL) +	{  +		mName = gMessageStringTable.getString(name); +	} + +	~LLMessageTemplate() +	{ +		for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer()); +	} + +	void addBlock(LLMessageBlock *blockp) +	{ +		LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName]; +		if (*member_blockp != NULL) +		{ +			llerrs << "Block " << blockp->mName +				<< "has already been used as a block name!" << llendl; +		} +		*member_blockp = blockp; +		if (  (mTotalSize != -1) +			&&(blockp->mTotalSize != -1) +			&&(  (blockp->mType == MBT_SINGLE) +			   ||(blockp->mType == MBT_MULTIPLE))) +		{ +			mTotalSize += blockp->mNumber*blockp->mTotalSize; +		} +		else +		{ +			mTotalSize = -1; +		} +	} + +	LLMessageBlock *getBlock(char *name) +	{ +		return mMemberBlocks[name]; +	} + +	// Trusted messages can only be recieved on trusted circuits. +	void setTrust(EMsgTrust t) +	{ +		mTrust = t; +	} + +	EMsgTrust getTrust(void) +	{ +		return mTrust; +	} + +	// controls for how the message should be encoded +	void setEncoding(EMsgEncoding e) +	{ +		mEncoding = e; +	} +	EMsgEncoding getEncoding() +	{ +		return mEncoding; +	} + +	void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data) +	{ +		mHandlerFunc = handler_func; +		mUserData = user_data; +	} + +	BOOL callHandlerFunc(LLMessageSystem *msgsystem) +	{ +		if (mHandlerFunc) +		{ +			mHandlerFunc(msgsystem, mUserData); +			return TRUE; +		} +		return FALSE; +	} + +	bool isBanned(bool trustedSource) +	{ +		return trustedSource ? mBanFromTrusted : mBanFromUntrusted; +	} + +	friend std::ostream&	 operator<<(std::ostream& s, LLMessageTemplate &msg); + +public: +	typedef std::map<char*, LLMessageBlock*> message_block_map_t; +	message_block_map_t						mMemberBlocks; +	char									*mName; +	EMsgFrequency							mFrequency; +	EMsgTrust								mTrust; +	EMsgEncoding							mEncoding; +	U32										mMessageNumber; +	S32										mTotalSize; +	U32										mReceiveCount;		// how many of this template have been received since last reset +	U32										mReceiveBytes;		// How many bytes received +	U32										mReceiveInvalid;	// How many "invalid" packets +	F32										mDecodeTimeThisFrame;	// Total seconds spent decoding this frame +	U32										mTotalDecoded;		// Total messages successfully decoded +	F32										mTotalDecodeTime;	// Total time successfully decoding messages +	F32										mMaxDecodeTimePerMsg; + +	bool									mBanFromTrusted; +	bool									mBanFromUntrusted; + +private: +	// message handler function (this is set by each application) +	void									(*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data); +	void									**mUserData; +}; + +#endif // LL_LLMESSAGETEMPLATE_H diff --git a/indra/llmessage/llmsgvariabletype.h b/indra/llmessage/llmsgvariabletype.h new file mode 100644 index 0000000000..360d949690 --- /dev/null +++ b/indra/llmessage/llmsgvariabletype.h @@ -0,0 +1,33 @@ +#ifndef LL_LLMSGVARIABLETYPE_H +#define LL_LLMSGVARIABLETYPE_H + +typedef enum e_message_variable_type +{ +	MVT_NULL, +	MVT_FIXED, +	MVT_VARIABLE, +	MVT_U8, +	MVT_U16, +	MVT_U32, +	MVT_U64, +	MVT_S8, +	MVT_S16, +	MVT_S32, +	MVT_S64, +	MVT_F32, +	MVT_F64, +	MVT_LLVector3, +	MVT_LLVector3d, +	MVT_LLVector4, +	MVT_LLQuaternion, +	MVT_LLUUID,	 +	MVT_BOOL, +	MVT_IP_ADDR, +	MVT_IP_PORT, +	MVT_U16Vec3, +	MVT_U16Quat, +	MVT_S16Array, +	MVT_EOL +} EMsgVariableType; + +#endif // LL_LLMSGVARIABLETYPE_H diff --git a/indra/llmessage/llpacketack.h b/indra/llmessage/llpacketack.h index 0874da6236..4c22dc2d62 100644 --- a/indra/llmessage/llpacketack.h +++ b/indra/llmessage/llpacketack.h @@ -44,6 +44,14 @@ public:  public:  	LLReliablePacketParams()  	{ +		clear(); +	}; + +	~LLReliablePacketParams() { }; + +	void clear() +	{ +		mHost.invalidate();  		mRetries = 0;  		mPingBasedRetry = TRUE;  		mTimeout = 0.f; @@ -52,8 +60,6 @@ public:  		mMessageName = NULL;  	}; -	~LLReliablePacketParams() { }; -  	void set (	const LLHost &host, S32 retries, BOOL ping_based_retry,  				F32 timeout,   				void (*callback)(void **,S32), void **callback_data, char *name ) @@ -117,7 +123,13 @@ public:  		}  	}; -	~LLReliablePacket(){ delete [] mBuffer; }; + +	~LLReliablePacket() +	{  +		mCallback = NULL; +		delete [] mBuffer; +		mBuffer = NULL; +	};  	friend class LLCircuitData;  protected: diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 1be6c21cc2..4fa3fab1c9 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -314,6 +314,12 @@ bool LLPumpIO::copyCurrentLinkInfo(links_t& links) const  void LLPumpIO::pump()  { +	pump(DEFAULT_POLL_TIMEOUT); +} + +//timeout is in microseconds +void LLPumpIO::pump(const S32& poll_timeout) +{  	LLMemType m1(LLMemType::MTYPE_IO_PUMP);  	LLFastTimer t1(LLFastTimer::FTM_PUMP);  	//llinfos << "LLPumpIO::pump()" << llendl; @@ -395,7 +401,7 @@ void LLPumpIO::pump()  		S32 count = 0;  		S32 client_id = 0;  		const apr_pollfd_t* poll_fd = NULL; -		apr_pollset_poll(mPollset, DEFAULT_POLL_TIMEOUT, &count, &poll_fd); +		apr_pollset_poll(mPollset, poll_timeout, &count, &poll_fd);  		PUMP_DEBUG;  		for(S32 i = 0; i < count; ++i)  		{ diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h index 50f7411298..5edfbdf8ee 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -227,6 +227,7 @@ public:  	 * chain has a file descriptor ready, <code>process()</code> will  	 * be called for all pipes which have requested it.  	 */ +	void pump(const S32& poll_timeout);  	void pump();  	/**  diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp new file mode 100755 index 0000000000..b7deb4817f --- /dev/null +++ b/indra/llmessage/llsdmessagebuilder.cpp @@ -0,0 +1,281 @@ +#include "linden_common.h" + +#include "llsdmessagebuilder.h" + +#include "llmessagetemplate.h" +#include "llquaternion.h" +#include "llsdutil.h" +#include "llsdserialize.h" +#include "u64.h" +#include "v3dmath.h" +#include "v3math.h" +#include "v4math.h" + +LLSDMessageBuilder::LLSDMessageBuilder() : +	mCurrentMessage(LLSD::emptyMap()), +	mCurrentBlock(NULL), +	mCurrentMessageName(""), +	mCurrentBlockName(""), +	mbSBuilt(FALSE), +	mbSClear(TRUE) +{ +} + +//virtual +LLSDMessageBuilder::~LLSDMessageBuilder() +{ +} + + +// virtual +void LLSDMessageBuilder::newMessage(const char *name) +{ +	mbSBuilt = FALSE; +	mbSClear = FALSE; + +	mCurrentMessage = LLSD::emptyMap(); +	mCurrentMessageName = (char *)name; +} + +// virtual +void LLSDMessageBuilder::clearMessage() +{ +	mbSBuilt = FALSE; +	mbSClear = TRUE; + +	mCurrentMessage = LLSD::emptyMap(); +	mCurrentMessageName = ""; +} + +// virtual +void LLSDMessageBuilder::nextBlock(const char* blockname) +{ +	LLSD& block = mCurrentMessage[blockname]; +	if(block.isUndefined()) +	{ +		block[0] = LLSD::emptyMap(); +		mCurrentBlock = &(block[0]); +	} +	else if(block.isArray()) +	{ +		block[block.size()] = LLSD::emptyMap(); +		mCurrentBlock = &(block[block.size() - 1]); +	} +	else +	{ +		llerrs << "existing block not array" << llendl; +	} +} + +// TODO: Remove this horror... +BOOL LLSDMessageBuilder::removeLastBlock() +{ +	/* TODO: finish implementing this */ +	return FALSE; +} + +void LLSDMessageBuilder::addBinaryData(const char *varname,  +									   const void *data, S32 size) +{ +	std::vector<U8> v; +	v.resize(size); +	memcpy(&(v[0]), reinterpret_cast<const U8*>(data), size); +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addS8(const char *varname, S8 v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addU8(const char *varname, U8 v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addS16(const char *varname, S16 v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addU16(const char *varname, U16 v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addF32(const char *varname, F32 v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addS32(const char *varname, S32 v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addU32(const char *varname, U32 v) +{ +	(*mCurrentBlock)[varname] = ll_sd_from_U32(v); +} + +void LLSDMessageBuilder::addU64(const char *varname, U64 v) +{ +	(*mCurrentBlock)[varname] = ll_sd_from_U64(v); +} + +void LLSDMessageBuilder::addF64(const char *varname, F64 v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addIPAddr(const char *varname, U32 v) +{ +	(*mCurrentBlock)[varname] = ll_sd_from_ipaddr(v); +} + +void LLSDMessageBuilder::addIPPort(const char *varname, U16 v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::addBOOL(const char* varname, BOOL v) +{ +	(*mCurrentBlock)[varname] = (v == TRUE); +} + +void LLSDMessageBuilder::addString(const char* varname, const char* v) +{ +	if (v) +		(*mCurrentBlock)[varname] = v;  /* Flawfinder: ignore */   +	else +		(*mCurrentBlock)[varname] = "";  +} + +void LLSDMessageBuilder::addString(const char* varname, const std::string& v) +{ +	if (v.size()) +		(*mCurrentBlock)[varname] = v;  +	else +		(*mCurrentBlock)[varname] = "";  +} + +void LLSDMessageBuilder::addVector3(const char *varname, const LLVector3& v) +{ +	(*mCurrentBlock)[varname] = ll_sd_from_vector3(v); +} + +void LLSDMessageBuilder::addVector4(const char *varname, const LLVector4& v) +{ +	(*mCurrentBlock)[varname] = ll_sd_from_vector4(v); +} + +void LLSDMessageBuilder::addVector3d(const char *varname, const LLVector3d& v) +{ +	(*mCurrentBlock)[varname] = ll_sd_from_vector3d(v); +} + +void LLSDMessageBuilder::addQuat(const char *varname, const LLQuaternion& v) +{ +	(*mCurrentBlock)[varname] = ll_sd_from_quaternion(v); +} + +void LLSDMessageBuilder::addUUID(const char *varname, const LLUUID& v) +{ +	(*mCurrentBlock)[varname] = v; +} + +void LLSDMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length) +{ +} + +BOOL LLSDMessageBuilder::isMessageFull(const char* blockname) const +{ +	return FALSE; +} + +// make sure that all the desired data is in place and then copy the data  +// into MAX_BUFFER_SIZEd buffer +U32 LLSDMessageBuilder::buildMessage(U8* buffer, U32 buffer_size) +{ +	return 0; +} + +void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data) +{ +	// copy the blocks +	// counting variables used to encode multiple block info +	S32 block_count = 0; +    char *block_name = NULL; + +	// loop through msg blocks to loop through variables, totalling up size +	// data and filling the new (send) message +	LLMsgData::msg_blk_data_map_t::const_iterator iter =  +		data.mMemberBlocks.begin(); +	LLMsgData::msg_blk_data_map_t::const_iterator end =  +		data.mMemberBlocks.end(); +	for(; iter != end; ++iter) +	{ +		const LLMsgBlkData* mbci = iter->second; +		if(!mbci) continue; + +		// do we need to encode a block code? +		if (block_count == 0) +		{ +			block_count = mbci->mBlockNumber; +			block_name = (char *)mbci->mName; +		} + +		// counting down mutliple blocks +		block_count--; + +		nextBlock(block_name); + +		// now loop through the variables +		LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin(); +		LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end(); +		 +		for(; dit != dend; ++dit) +		{ +			//const LLMsgVarData& mvci = *dit; + +			// TODO: Copy mvci data in to block: +			// (*mCurrentBlock)[varname] = v; +		} +	} +} + +//virtual +void LLSDMessageBuilder::copyFromLLSD(const LLSD& msg) +{ +	mCurrentMessage = msg; +	llinfos << LLSDXMLStreamer(mCurrentMessage) << llendl; +} + +const LLSD& LLSDMessageBuilder::getMessage() const +{ +	 return mCurrentMessage; +} + +//virtual +void LLSDMessageBuilder::setBuilt(BOOL b) { mbSBuilt = b; } + +//virtual  +BOOL LLSDMessageBuilder::isBuilt() const {return mbSBuilt;} + +//virtual  +BOOL LLSDMessageBuilder::isClear() const {return mbSClear;} + +//virtual  +S32 LLSDMessageBuilder::getMessageSize() +{ +	// babbage: size is unknown as message stored as LLSD. +	// return non-zero if pending data, as send can be skipped for 0 size. +	// return 1 to encourage senders checking size against splitting message. +	return mCurrentMessage.size()? 1 : 0; +} + +//virtual  +const char* LLSDMessageBuilder::getMessageName() const  +{ +	return mCurrentMessageName.c_str(); +} diff --git a/indra/llmessage/llsdmessagebuilder.h b/indra/llmessage/llsdmessagebuilder.h new file mode 100755 index 0000000000..f04194d12f --- /dev/null +++ b/indra/llmessage/llsdmessagebuilder.h @@ -0,0 +1,98 @@ +#ifndef LL_LLSDMESSAGEBUILDER_H +#define LL_LLSDMESSAGEBUILDER_H + +#include <map> + +#include "llmessagebuilder.h" +#include "llmsgvariabletype.h" +#include "llsd.h" + +class LLMessageTemplate; +class LLMsgData; + +class LLSDMessageBuilder : public LLMessageBuilder +{ +public: + +	//CLASS_LOG_TYPE(LLSDMessageBuilder); +	 +	LLSDMessageBuilder(); +	virtual ~LLSDMessageBuilder(); + +	virtual void newMessage(const char *name); + +	virtual void nextBlock(const char* blockname); +	virtual BOOL removeLastBlock(); // TODO: babbage: remove this horror... + +	/** All add* methods expect pointers to canonical varname strings. */ +	virtual void addBinaryData(const char *varname, const void *data,  +							   S32 size); +	virtual void addBOOL(const char* varname, BOOL b); +	virtual void addS8(const char *varname, S8 s); +	virtual void addU8(const char *varname, U8 u); +	virtual void addS16(const char *varname, S16 i); +	virtual void addU16(const char *varname, U16 i); +	virtual void addF32(const char *varname, F32 f); +	virtual void addS32(const char *varname, S32 s); +	virtual void addU32(const char *varname, U32 u); +	virtual void addU64(const char *varname, U64 lu); +	virtual void addF64(const char *varname, F64 d); +	virtual void addVector3(const char *varname, const LLVector3& vec); +	virtual void addVector4(const char *varname, const LLVector4& vec); +	virtual void addVector3d(const char *varname, const LLVector3d& vec); +	virtual void addQuat(const char *varname, const LLQuaternion& quat); +	virtual void addUUID(const char *varname, const LLUUID& uuid); +	virtual void addIPAddr(const char *varname, const U32 ip); +	virtual void addIPPort(const char *varname, const U16 port); +	virtual void addString(const char* varname, const char* s); +	virtual void addString(const char* varname, const std::string& s); + +	virtual BOOL isMessageFull(const char* blockname) const; +	virtual void compressMessage(U8*& buf_ptr, U32& buffer_length); + +	virtual BOOL isBuilt() const; +	virtual BOOL isClear() const; +	virtual U32 buildMessage(U8* buffer, U32 buffer_size);  +        /**< Return built message size */ +	 +	virtual void clearMessage(); + +	// TODO: babbage: remove this horror. +	virtual void setBuilt(BOOL b); + +	virtual S32 getMessageSize(); +	virtual const char* getMessageName() const; + +	virtual void copyFromMessageData(const LLMsgData& data); + +	virtual void copyFromLLSD(const LLSD& msg); + +	const LLSD& getMessage() const; +private: + +	/* mCurrentMessage is of the following format: +		mCurrentMessage = { 'block_name1' : [ { 'block1_field1' : 'b1f1_data', +												'block1_field2' : 'b1f2_data', +												... +												'block1_fieldn' : 'b1fn_data'}, +											{ 'block2_field1' : 'b2f1_data', +												'block2_field2' : 'b2f2_data', +												... +												'block2_fieldn' : 'b2fn_data'}, +											...											 +											{ 'blockm_field1' : 'bmf1_data', +												'blockm_field2' : 'bmf2_data', +												... +												'blockm_fieldn' : 'bmfn_data'} ], +							'block_name2' : ..., +							... +							'block_namem' } */ +	LLSD mCurrentMessage; +	LLSD* mCurrentBlock; +	std::string mCurrentMessageName; +	std::string mCurrentBlockName; +	BOOL mbSBuilt; +	BOOL mbSClear; +}; + +#endif // LL_LLSDMESSAGEBUILDER_H diff --git a/indra/llmessage/llsdmessagereader.cpp b/indra/llmessage/llsdmessagereader.cpp new file mode 100755 index 0000000000..6312bee0ab --- /dev/null +++ b/indra/llmessage/llsdmessagereader.cpp @@ -0,0 +1,264 @@ +#include "llsdmessagereader.h" +#include "llsdutil.h" +#include "llmessagebuilder.h" +#include "llsdmessagebuilder.h" + +LLSDMessageReader::LLSDMessageReader() +{ +} + +//virtual  +LLSDMessageReader::~LLSDMessageReader() +{ +} + + +LLSD getLLSD(const LLSD& input, const char* block, const char* var, S32 blocknum) +{ +	if(input[block].isArray()) +	{ +		return input[block][blocknum][var]; +	} +	return LLSD(); +} + +//virtual  +void LLSDMessageReader::getBinaryData(const char *block, const char *var,  +									  void *datap, S32 size, S32 blocknum,  +									  S32 max_size) +{ +	std::vector<U8> data = getLLSD(mMessage, block, var, blocknum); +	S32 data_size = (S32)data.size(); + +	if (size && data_size != size) +	{ +		return; +	} +	 +	if (max_size < data_size) +	{ +		data_size = max_size; +	} +	 +	memcpy(datap, &(data[0]), data_size); +} + +//virtual  +void LLSDMessageReader::getBOOL(const char *block, const char *var,  +								BOOL &data,  +								S32 blocknum) +{ +	data = getLLSD(mMessage, block, var, blocknum); +} + +//virtual  +void LLSDMessageReader::getS8(const char *block, const char *var, S8 &data,  +					   S32 blocknum) +{ +	data = getLLSD(mMessage, block, var, blocknum).asInteger(); +} + +//virtual  +void LLSDMessageReader::getU8(const char *block, const char *var, U8 &data,  +					   S32 blocknum) +{ +	data = getLLSD(mMessage, block, var, blocknum).asInteger(); +} + +//virtual  +void LLSDMessageReader::getS16(const char *block, const char *var, S16 &data,  +						S32 blocknum) +{ +	data = getLLSD(mMessage, block, var, blocknum).asInteger(); +} + +//virtual  +void LLSDMessageReader::getU16(const char *block, const char *var, U16 &data,  +						S32 blocknum) +{ +	data = getLLSD(mMessage, block, var, blocknum).asInteger(); +} + +//virtual  +void LLSDMessageReader::getS32(const char *block, const char *var, S32 &data,  +						S32 blocknum) +{ +	data = getLLSD(mMessage, block, var, blocknum); +} + +//virtual  +void LLSDMessageReader::getF32(const char *block, const char *var, F32 &data,  +						S32 blocknum) +{ +	data = (F32)getLLSD(mMessage, block, var, blocknum).asReal(); +} + +//virtual  +void LLSDMessageReader::getU32(const char *block, const char *var, U32 &data,  +						S32 blocknum) +{ +	data = ll_U32_from_sd(getLLSD(mMessage, block, var, blocknum)); +} + +//virtual  +void LLSDMessageReader::getU64(const char *block, const char *var, +								U64 &data, S32 blocknum) +{ +	data = ll_U64_from_sd(getLLSD(mMessage, block, var, blocknum)); +} + +//virtual  +void LLSDMessageReader::getF64(const char *block, const char *var, +								F64 &data, S32 blocknum) +{ +	data = getLLSD(mMessage, block, var, blocknum); +} + +//virtual  +void LLSDMessageReader::getVector3(const char *block, const char *var,  +							LLVector3 &vec, S32 blocknum) +{ +	vec = ll_vector3_from_sd(getLLSD(mMessage, block, var, blocknum)); +} + +//virtual  +void LLSDMessageReader::getVector4(const char *block, const char *var,  +							LLVector4 &vec, S32 blocknum) +{ +	vec = ll_vector4_from_sd(getLLSD(mMessage, block, var, blocknum)); +} + +//virtual  +void LLSDMessageReader::getVector3d(const char *block, const char *var,  +							 LLVector3d &vec, S32 blocknum) +{ +	vec = ll_vector3d_from_sd(getLLSD(mMessage, block, var, blocknum)); +} + +//virtual  +void LLSDMessageReader::getQuat(const char *block, const char *var, +								 LLQuaternion &q, S32 blocknum) +{ +	q = ll_quaternion_from_sd(getLLSD(mMessage, block, var, blocknum)); +} + +//virtual  +void LLSDMessageReader::getUUID(const char *block, const char *var, +								 LLUUID &uuid, S32 blocknum) +{ +	uuid = getLLSD(mMessage, block, var, blocknum); +} + +//virtual  +void LLSDMessageReader::getIPAddr(const char *block, const char *var, +								   U32 &ip, S32 blocknum) +{ +	ip = ll_ipaddr_from_sd(getLLSD(mMessage, block, var, blocknum)); +} + +//virtual  +void LLSDMessageReader::getIPPort(const char *block, const char *var, +								   U16 &port, S32 blocknum) +{ +	port = getLLSD(mMessage, block, var, blocknum).asInteger(); +} + +//virtual  +void LLSDMessageReader::getString(const char *block, const char *var,  +						   S32 buffer_size, char *buffer, S32 blocknum) +{ +	std::string data = getLLSD(mMessage, block, var, blocknum); +	 +	S32 data_size = data.size(); +	if (data_size >= buffer_size) +	{ +		data_size = buffer_size - 1; +	} +	memcpy(buffer, data.data(), data_size); +	buffer[data_size] = '\0'; +} + + +//virtual  +S32	LLSDMessageReader::getNumberOfBlocks(const char *blockname) +{ +	return mMessage[blockname].size(); +} + +S32 getElementSize(const LLSD& llsd) +{ +	LLSD::Type type = llsd.type(); +	switch(type) +	{ +	case LLSD::TypeBoolean: +		return sizeof(bool); +	case LLSD::TypeInteger: +		return sizeof(S32); +	case LLSD::TypeReal: +		return sizeof(F64); +	case LLSD::TypeString: +		return llsd.asString().size(); +	case LLSD::TypeUUID: +		return sizeof(LLUUID); +	case LLSD::TypeDate: +		return sizeof(LLDate); +	case LLSD::TypeURI: +		return sizeof(LLURI); +	case LLSD::TypeBinary: +	{ +		std::vector<U8> data = llsd; +		return data.size() * sizeof(U8); +	} +	case LLSD::TypeMap: +	case LLSD::TypeArray: +	case LLSD::TypeUndefined: +		return 0; +	} +	return 0; +} + +//virtual  +//Mainly used to find size of binary block of data +S32	LLSDMessageReader::getSize(const char *blockname, const char *varname) +{ +	return getElementSize(mMessage[blockname][0][varname]); +} + + +//virtual  +S32	LLSDMessageReader::getSize(const char *blockname, S32 blocknum,  +							   const char *varname) +{ +	return getElementSize(mMessage[blockname][blocknum][varname]); +} + +//virtual  +void LLSDMessageReader::clearMessage() +{ +	mMessage = LLSD(); +} + +//virtual  +const char* LLSDMessageReader::getMessageName() const +{ +	return mMessageName.c_str(); +} + +// virtual  +S32 LLSDMessageReader::getMessageSize() const +{ +	return 0; +} + +//virtual  +void LLSDMessageReader::copyToBuilder(LLMessageBuilder& builder) const +{ +	builder.copyFromLLSD(mMessage); +} + +void LLSDMessageReader::setMessage(const std::string& name, const LLSD& message) +{ +	mMessageName = name; +	// TODO: Validate +	mMessage = message; +} diff --git a/indra/llmessage/llsdmessagereader.h b/indra/llmessage/llsdmessagereader.h new file mode 100755 index 0000000000..57851941a2 --- /dev/null +++ b/indra/llmessage/llsdmessagereader.h @@ -0,0 +1,79 @@ +#ifndef LL_LLSDMESSAGEREADER_H +#define LL_LLSDMESSAGEREADER_H + +#include "llmessagereader.h" +#include "llsd.h" + +#include <map> + +class LLMessageTemplate; +class LLMsgData; + +class LLSDMessageReader : public LLMessageReader +{ +public: + +	LLSDMessageReader(); +	virtual ~LLSDMessageReader(); + +	/** All get* methods expect pointers to canonical strings. */ +	virtual void getBinaryData(const char *block, const char *var,  +							   void *datap, S32 size, S32 blocknum = 0,  +							   S32 max_size = S32_MAX); +	virtual void getBOOL(const char *block, const char *var, BOOL &data,  +						 S32 blocknum = 0); +	virtual void getS8(const char *block, const char *var, S8 &data,  +					   S32 blocknum = 0); +	virtual void getU8(const char *block, const char *var, U8 &data,  +					   S32 blocknum = 0); +	virtual void getS16(const char *block, const char *var, S16 &data,  +						S32 blocknum = 0); +	virtual void getU16(const char *block, const char *var, U16 &data,  +						S32 blocknum = 0); +	virtual void getS32(const char *block, const char *var, S32 &data,  +						S32 blocknum = 0); +	virtual void getF32(const char *block, const char *var, F32 &data,  +						S32 blocknum = 0); +	virtual void getU32(const char *block, const char *var, U32 &data,  +						S32 blocknum = 0); +	virtual void getU64(const char *block, const char *var, U64 &data,  +						S32 blocknum = 0); +	virtual void getF64(const char *block, const char *var, F64 &data,  +						S32 blocknum = 0); +	virtual void getVector3(const char *block, const char *var,  +							LLVector3 &vec, S32 blocknum = 0); +	virtual void getVector4(const char *block, const char *var,  +							LLVector4 &vec, S32 blocknum = 0); +	virtual void getVector3d(const char *block, const char *var,  +							 LLVector3d &vec, S32 blocknum = 0); +	virtual void getQuat(const char *block, const char *var, LLQuaternion &q,  +						 S32 blocknum = 0); +	virtual void getUUID(const char *block, const char *var, LLUUID &uuid,  +						 S32 blocknum = 0); +	virtual void getIPAddr(const char *block, const char *var, U32 &ip,  +						   S32 blocknum = 0); +	virtual void getIPPort(const char *block, const char *var, U16 &port,  +						   S32 blocknum = 0); +	virtual void getString(const char *block, const char *var,  +						   S32 buffer_size, char *buffer, S32 blocknum = 0); + +	virtual S32	getNumberOfBlocks(const char *blockname); +	virtual S32	getSize(const char *blockname, const char *varname); +	virtual S32	getSize(const char *blockname, S32 blocknum,  +						const char *varname); + +	virtual void clearMessage(); + +	virtual const char* getMessageName() const; +	virtual S32 getMessageSize() const; + +	virtual void copyToBuilder(LLMessageBuilder&) const; + +	void setMessage(const std::string& name, const LLSD& msg); + +private: +	std::string mMessageName; +	LLSD mMessage; +}; + +#endif // LL_LLSDMESSAGEREADER_H diff --git a/indra/llmessage/llservice.h b/indra/llmessage/llservice.h index e243e710d6..fe6fa56477 100644 --- a/indra/llmessage/llservice.h +++ b/indra/llmessage/llservice.h @@ -71,7 +71,7 @@ namespace boost  	}  	inline void intrusive_ptr_release(LLServiceCreator* p)  	{ -		if(0 == --p->mReferenceCount) +		if(p && 0 == --p->mReferenceCount)  		{  			delete p;  		} diff --git a/indra/llmessage/llservicebuilder.cpp b/indra/llmessage/llservicebuilder.cpp new file mode 100644 index 0000000000..fbcf38ae35 --- /dev/null +++ b/indra/llmessage/llservicebuilder.cpp @@ -0,0 +1,115 @@ +/**  +* @file llservicebuilder.cpp +* @brief Implementation of the LLServiceBuilder class. +* +* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. +* $License$ +*/ + +#include "llapp.h" +#include "llfile.h" +#include "llservicebuilder.h" +#include "llsd.h" +#include "llsdserialize.h" + +void LLServiceBuilder::loadServiceDefinitionsFromFile( +	const std::string& service_filename) +{ +	llifstream service_file(service_filename.c_str(), std::ios::binary); +	if(service_file.is_open()) +	{ +		LLSD service_data; +		LLSDSerialize::fromXML(service_data, service_file); +		service_file.close(); +		// Load service  +		LLSD service_map = service_data["services"]; +		for(LLSD::array_iterator array_itr = service_map.beginArray(); +			array_itr != service_map.endArray(); +			++array_itr) +		{	 +			LLSD service_llsd = (*array_itr)["service-builder"]; +			std::string service_name = (*array_itr)["name"].asString(); +			createServiceDefinition(service_name, service_llsd); +		} +		llinfos << "loaded config file: " << service_filename << llendl; +	} +	else +	{ +		llwarns << "unable to find config file: " << service_filename << llendl; +	} +} + +void LLServiceBuilder::createServiceDefinition( +	const std::string& service_name, +	LLSD& service_llsd) +{ +	if(service_llsd.isString()) +	{ +		mServiceMap[ service_name ] = service_llsd.asString(); +	}			 +	else if(service_llsd.isMap()) +	{ +		for(LLSD::map_iterator map_itr = service_llsd.beginMap(); +			map_itr != service_llsd.endMap(); +			++map_itr) +		{ +			std::string compound_builder_name = service_name; +			compound_builder_name.append("-"); +			compound_builder_name.append((*map_itr).first); +			mServiceMap[ compound_builder_name ] = (*map_itr).second.asString(); +		} +	} +} + +std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) +{ +	std::ostringstream service_url; +	// Find the service builder +	if(mServiceMap.find(service_name) != mServiceMap.end()) +	{ +		// construct the service builder url +		LLApp* app = LLApp::instance(); +		if(app) +		{ +			LLSD base_url = app->getOption("services-base-url"); +			service_url << base_url.asString(); +		} +		service_url << mServiceMap[service_name]; +	} +	else +	{ +		llwarns << "Cannot find service " << service_name << llendl; +	} +	return service_url.str(); +} + +std::string LLServiceBuilder::buildServiceURI( +	const std::string& service_name, +	const LLSD& option_map) +{ +	std::string service_url = buildServiceURI(service_name); + +	// Find the Service Name +	if(!service_url.empty() && option_map.isMap()) +	{ +		// Do brace replacements - NOT CURRENTLY RECURSIVE +		for(LLSD::map_const_iterator option_itr = option_map.beginMap(); +			option_itr != option_map.endMap(); +			++option_itr) +		{ +			std::string variable_name = "{$"; +			variable_name.append((*option_itr).first); +			variable_name.append("}"); +			std::string::size_type find_pos = service_url.find(variable_name); +			if(find_pos != std::string::npos) +			{ +				service_url.replace( +					find_pos, +					variable_name.length(), +					(*option_itr).second.asString()); +			} +		} +	} + +	return service_url; +} diff --git a/indra/llmessage/llservicebuilder.h b/indra/llmessage/llservicebuilder.h new file mode 100644 index 0000000000..2692ffe1e5 --- /dev/null +++ b/indra/llmessage/llservicebuilder.h @@ -0,0 +1,73 @@ +/**  +* @file llservicebuilder.h +* @brief Declaration of the LLServiceBuilder class. +* +* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. +* $License$ +*/ + +#ifndef LLSERVICEBUILDER_H +#define LLSERVICEBUILDER_H + +#include <string> +#include <map> +#include "llerror.h" + +class LLSD; + +/**  + * @class LLServiceBuilder + * @brief This class builds urls for us to use when making web service calls. + */ + +class LLServiceBuilder +{ +	LOG_CLASS(LLServiceBuilder); +public: +	LLServiceBuilder(void) {} +	~LLServiceBuilder(void) {} + +	/**  +	 * @brief Initialize this object with the service definitions. +	 * +	 * @param service_filename The services definition files -- services.xml. +	 */ +	void loadServiceDefinitionsFromFile(const std::string& service_filename); + +	/**  +	 * @brief Build a service url if the url needs no construction parameters. +	 * +	 * @param service_name The name of the service you want to call. +	 */ +	std::string buildServiceURI(const std::string& service_name); + +	/**  +	 * @brief Build a service url if the url with construction parameters. +	 * +	 * The parameter substitution supports string substituition from RUSS: +	 * [[Recursive_URL_Substitution_Syntax]] +	 * @param service_name The name of the service you want to call. +	 * @param option_map The parameters in a map of name:value for the service. +	 */ +	std::string buildServiceURI( +		const std::string& service_name, +		const LLSD& option_map);	 + +public: +	/**  +	 * @brief Helper method which builds construction state for a service +	 * +	 * This method should probably be protected, but we need to test this +	 * method. +	 */ +	void createServiceDefinition( +		const std::string& service_name, +		LLSD& service_url); + +protected: +	std::map<std::string, std::string> mServiceMap; +}; + + + +#endif diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp new file mode 100644 index 0000000000..806f03422d --- /dev/null +++ b/indra/llmessage/lltemplatemessagebuilder.cpp @@ -0,0 +1,856 @@ +#include "linden_common.h" + +#include "lltemplatemessagebuilder.h" + +#include "llmessagetemplate.h" +#include "llquaternion.h" +#include "u64.h" +#include "v3dmath.h" +#include "v3math.h" +#include "v4math.h" + +LLTemplateMessageBuilder::LLTemplateMessageBuilder(message_template_name_map_t& name_template_map) : +	mCurrentSMessageData(NULL), +	mCurrentSMessageTemplate(NULL), +	mCurrentSDataBlock(NULL), +	mCurrentSMessageName(NULL), +	mCurrentSBlockName(NULL), +	mbSBuilt(FALSE), +	mbSClear(TRUE), +	mCurrentSendTotal(0), +	mMessageTemplates(name_template_map) +{ +} + +//virtual +LLTemplateMessageBuilder::~LLTemplateMessageBuilder() +{ +	delete mCurrentSMessageData; +	mCurrentSMessageData = NULL; +} + + +// virtual +void LLTemplateMessageBuilder::newMessage(const char *name) +{ +	mbSBuilt = FALSE; +	mbSClear = FALSE; + +	mCurrentSendTotal = 0; + +	delete mCurrentSMessageData; +	mCurrentSMessageData = NULL; + +	char *namep = (char *)name;  + +	if (mMessageTemplates.count(namep) > 0) +	{ +		mCurrentSMessageTemplate = mMessageTemplates[namep]; +		if (mCurrentSMessageData) +		{ +			delete mCurrentSMessageData; +		} +		mCurrentSMessageData = new LLMsgData(namep); +		mCurrentSMessageName = namep; +		mCurrentSDataBlock = NULL; +		mCurrentSBlockName = NULL; + +		// add at one of each block +		LLMessageTemplate* msg_template = mMessageTemplates[namep]; +		for (LLMessageTemplate::message_block_map_t::iterator iter = msg_template->mMemberBlocks.begin(); +			 iter != msg_template->mMemberBlocks.end(); iter++) +		{ +			LLMessageBlock* ci = iter->second; +			LLMsgBlkData	*tblockp; +			tblockp = new LLMsgBlkData(ci->mName, 0); +			mCurrentSMessageData->addBlock(tblockp); +		} +	} +	else +	{ +		llerrs << "newMessage - Message " << name << " not registered" << llendl; +	} +} + +// virtual +void LLTemplateMessageBuilder::clearMessage() +{ +	mbSBuilt = FALSE; +	mbSClear = TRUE; + +	mCurrentSendTotal = 0; + +	mCurrentSMessageTemplate = NULL; + +	delete mCurrentSMessageData; +	mCurrentSMessageData = NULL; + +	mCurrentSMessageName = NULL; +	mCurrentSDataBlock = NULL; +	mCurrentSBlockName = NULL; +} + +// virtual +void LLTemplateMessageBuilder::nextBlock(const char* blockname) +{ +	char *bnamep = (char *)blockname;  + +	if (!mCurrentSMessageTemplate) +	{ +		llerrs << "newMessage not called prior to setBlock" << llendl; +		return; +	} + +	// now, does this block exist? +	LLMessageTemplate::message_block_map_t::iterator temp_iter = mCurrentSMessageTemplate->mMemberBlocks.find(bnamep); +	if (temp_iter == mCurrentSMessageTemplate->mMemberBlocks.end()) +	{ +		llerrs << "LLTemplateMessageBuilder::nextBlock " << bnamep +			<< " not a block in " << mCurrentSMessageTemplate->mName << llendl; +		return; +	} +	 +	LLMessageBlock* template_data = temp_iter->second; +	 +	// ok, have we already set this block? +	LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep]; +	if (block_data->mBlockNumber == 0) +	{ +		// nope! set this as the current block +		block_data->mBlockNumber = 1; +		mCurrentSDataBlock = block_data; +		mCurrentSBlockName = bnamep; + +		// add placeholders for each of the variables +		for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin(); +			 iter != template_data->mMemberVariables.end(); iter++) +		{ +			LLMessageVariable& ci = *(iter->second); +			mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); +		} +		return; +	} +	else +	{ +		// already have this block. . .  +		// are we supposed to have a new one? + +		// if the block is type MBT_SINGLE this is bad! +		if (template_data->mType == MBT_SINGLE) +		{ +			llerrs << "LLTemplateMessageBuilder::nextBlock called multiple times" +				<< " for " << bnamep << " but is type MBT_SINGLE" << llendl; +			return; +		} + + +		// if the block is type MBT_MULTIPLE then we need a known number,  +		// make sure that we're not exceeding it +		if (  (template_data->mType == MBT_MULTIPLE) +			&&(mCurrentSDataBlock->mBlockNumber == template_data->mNumber)) +		{ +			llerrs << "LLTemplateMessageBuilder::nextBlock called " +				<< mCurrentSDataBlock->mBlockNumber << " times for " << bnamep +				<< " exceeding " << template_data->mNumber +				<< " specified in type MBT_MULTIPLE." << llendl; +			return; +		} + +		// ok, we can make a new one +		// modify the name to avoid name collision by adding number to end +		S32  count = block_data->mBlockNumber; + +		// incrememt base name's count +		block_data->mBlockNumber++; + +		if (block_data->mBlockNumber > MAX_BLOCKS) +		{ +			llerrs << "Trying to pack too many blocks into MBT_VARIABLE type " +				   << "(limited to " << MAX_BLOCKS << ")" << llendl; +		} + +		// create new name +		// Nota Bene: if things are working correctly,  +		// mCurrentMessageData->mMemberBlocks[blockname]->mBlockNumber ==  +		// mCurrentDataBlock->mBlockNumber + 1 + +		char *nbnamep = bnamep + count; +	 +		mCurrentSDataBlock = new LLMsgBlkData(bnamep, count); +		mCurrentSDataBlock->mName = nbnamep; +		mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock; + +		// add placeholders for each of the variables +		for (LLMessageBlock::message_variable_map_t::iterator +				 iter = template_data->mMemberVariables.begin(), +				 end = template_data->mMemberVariables.end(); +			 iter != end; iter++) +		{ +			LLMessageVariable& ci = *(iter->second); +			mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); +		} +		return; +	} +} + +// TODO: Remove this horror... +BOOL LLTemplateMessageBuilder::removeLastBlock() +{ +	if (mCurrentSBlockName) +	{ +		if (  (mCurrentSMessageData) +			&&(mCurrentSMessageTemplate)) +		{ +			if (mCurrentSMessageData->mMemberBlocks[mCurrentSBlockName]->mBlockNumber >= 1) +			{ +				// At least one block for the current block name. + +				// Store the current block name for future reference. +				char *block_name = mCurrentSBlockName; + +				// Decrement the sent total by the size of the +				// data in the message block that we're currently building. + +				LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]; +				 +				for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin(); +					 iter != template_data->mMemberVariables.end(); iter++) +				{ +					LLMessageVariable& ci = *(iter->second); +					mCurrentSendTotal -= ci.getSize(); +				} + + +				// Now we want to find the block that we're blowing away. + +				// Get the number of blocks. +				LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[block_name]; +				S32 num_blocks = block_data->mBlockNumber; + +				// Use the same (suspect?) algorithm that's used to generate +				// the names in the nextBlock method to find it. +				char *block_getting_whacked = block_name + num_blocks - 1; +				LLMsgBlkData* whacked_data = mCurrentSMessageData->mMemberBlocks[block_getting_whacked]; +				delete whacked_data; +				mCurrentSMessageData->mMemberBlocks.erase(block_getting_whacked); + +				if (num_blocks <= 1) +				{ +					// we just blew away the last one, so return FALSE +					llwarns << "not blowing away the only block of message " +							<< mCurrentSMessageName +							<< ". Block: " << block_name +							<< ". Number: " << num_blocks +							<< llendl; +					return FALSE; +				} +				else +				{ +					// Decrement the counter. +					block_data->mBlockNumber--; +					return TRUE; +				} +			} +		} +	} +	return FALSE; +} + +// add data to variable in current block +void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EMsgVariableType type, S32 size) +{ +	char *vnamep = (char *)varname;  + +	// do we have a current message? +	if (!mCurrentSMessageTemplate) +	{ +		llerrs << "newMessage not called prior to addData" << llendl; +		return; +	} + +	// do we have a current block? +	if (!mCurrentSDataBlock) +	{ +		llerrs << "setBlock not called prior to addData" << llendl; +		return; +	} + +	// kewl, add the data if it exists +	LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep]; +	if (!var_data || !var_data->getName()) +	{ +		llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl; +		return; +	} + +	// ok, it seems ok. . . are we the correct size? +	if (var_data->getType() == MVT_VARIABLE) +	{ +		// Variable 1 can only store 255 bytes, make sure our data is smaller +		if ((var_data->getSize() == 1) && +			(size > 255)) +		{ +			llwarns << "Field " << varname << " is a Variable 1 but program " +			       << "attempted to stuff more than 255 bytes in " +			       << "(" << size << ").  Clamping size and truncating data." << llendl; +			size = 255; +			char *truncate = (char *)data; +			truncate[255] = 0; +		} + +		// no correct size for MVT_VARIABLE, instead we need to tell how many bytes the size will be encoded as +		mCurrentSDataBlock->addData(vnamep, data, size, type, var_data->getSize()); +		mCurrentSendTotal += size; +	} +	else +	{ +		if (size != var_data->getSize()) +		{ +			llerrs << varname << " is type MVT_FIXED but request size " << size << " doesn't match template size " +				   << var_data->getSize() << llendl; +			return; +		} +		// alright, smash it in +		mCurrentSDataBlock->addData(vnamep, data, size, type); +		mCurrentSendTotal += size; +	} +} + +// add data to variable in current block - fails if variable isn't MVT_FIXED +void LLTemplateMessageBuilder::addData(const char *varname, const void *data, EMsgVariableType type) +{ +	char *vnamep = (char *)varname;  + +	// do we have a current message? +	if (!mCurrentSMessageTemplate) +	{ +		llerrs << "newMessage not called prior to addData" << llendl; +		return; +	} + +	// do we have a current block? +	if (!mCurrentSDataBlock) +	{ +		llerrs << "setBlock not called prior to addData" << llendl; +		return; +	} + +	// kewl, add the data if it exists +	LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep]; +	if (!var_data->getName()) +	{ +		llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl; +		return; +	} + +	// ok, it seems ok. . . are we MVT_VARIABLE? +	if (var_data->getType() == MVT_VARIABLE) +	{ +		// nope +		llerrs << vnamep << " is type MVT_VARIABLE. Call using addData(name, data, size)" << llendl; +		return; +	} +	else +	{ +		mCurrentSDataBlock->addData(vnamep, data, var_data->getSize(), type); +		mCurrentSendTotal += var_data->getSize(); +	} +} + +void LLTemplateMessageBuilder::addBinaryData(const char *varname,  +											const void *data, S32 size) +{ +	addData(varname, data, MVT_FIXED, size); +} + +void LLTemplateMessageBuilder::addS8(const char *varname, S8 s) +{ +	addData(varname, &s, MVT_S8, sizeof(s)); +} + +void LLTemplateMessageBuilder::addU8(const char *varname, U8 u) +{ +	addData(varname, &u, MVT_U8, sizeof(u)); +} + +void LLTemplateMessageBuilder::addS16(const char *varname, S16 i) +{ +	addData(varname, &i, MVT_S16, sizeof(i)); +} + +void LLTemplateMessageBuilder::addU16(const char *varname, U16 i) +{ +	addData(varname, &i, MVT_U16, sizeof(i)); +} + +void LLTemplateMessageBuilder::addF32(const char *varname, F32 f) +{ +	addData(varname, &f, MVT_F32, sizeof(f)); +} + +void LLTemplateMessageBuilder::addS32(const char *varname, S32 s) +{ +	addData(varname, &s, MVT_S32, sizeof(s)); +} + +void LLTemplateMessageBuilder::addU32(const char *varname, U32 u) +{ +	addData(varname, &u, MVT_U32, sizeof(u)); +} + +void LLTemplateMessageBuilder::addU64(const char *varname, U64 lu) +{ +	addData(varname, &lu, MVT_U64, sizeof(lu)); +} + +void LLTemplateMessageBuilder::addF64(const char *varname, F64 d) +{ +	addData(varname, &d, MVT_F64, sizeof(d)); +} + +void LLTemplateMessageBuilder::addIPAddr(const char *varname, U32 u) +{ +	addData(varname, &u, MVT_IP_ADDR, sizeof(u)); +} + +void LLTemplateMessageBuilder::addIPPort(const char *varname, U16 u) +{ +	u = htons(u); +	addData(varname, &u, MVT_IP_PORT, sizeof(u)); +} + +void LLTemplateMessageBuilder::addBOOL(const char* varname, BOOL b) +{ +	// Can't just cast a BOOL (actually a U32) to a U8. +	// In some cases the low order bits will be zero. +	U8 temp = (b != 0); +	addData(varname, &temp, MVT_BOOL, sizeof(temp)); +} + +void LLTemplateMessageBuilder::addString(const char* varname, const char* s) +{ +	if (s) +		addData( varname, (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1);  /* Flawfinder: ignore */   +	else +		addData( varname, NULL, MVT_VARIABLE, 0);  +} + +void LLTemplateMessageBuilder::addString(const char* varname, const std::string& s) +{ +	if (s.size()) +		addData( varname, (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);  +	else +		addData( varname, NULL, MVT_VARIABLE, 0);  +} + +void LLTemplateMessageBuilder::addVector3(const char *varname, const LLVector3& vec) +{ +	addData(varname, vec.mV, MVT_LLVector3, sizeof(vec.mV)); +} + +void LLTemplateMessageBuilder::addVector4(const char *varname, const LLVector4& vec) +{ +	addData(varname, vec.mV, MVT_LLVector4, sizeof(vec.mV)); +} + +void LLTemplateMessageBuilder::addVector3d(const char *varname, const LLVector3d& vec) +{ +	addData(varname, vec.mdV, MVT_LLVector3d, sizeof(vec.mdV)); +} + +void LLTemplateMessageBuilder::addQuat(const char *varname, const LLQuaternion& quat) +{ +	addData(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3)); +} + +void LLTemplateMessageBuilder::addUUID(const char *varname, const LLUUID& uuid) +{ +	addData(varname, uuid.mData, MVT_LLUUID, sizeof(uuid.mData)); +} + +static S32 zero_code(U8 **data, U32 *data_size) +{ +	// Encoded send buffer needs to be slightly larger since the zero +	// coding can potentially increase the size of the send data. +	static U8 encodedSendBuffer[2 * MAX_BUFFER_SIZE]; + +	S32 count = *data_size; +	 +	S32 net_gain = 0; +	U8 num_zeroes = 0; +	 +	U8 *inptr = (U8 *)*data; +	U8 *outptr = (U8 *)encodedSendBuffer; + +// skip the packet id field + +	for (U32 i=0;i<LL_PACKET_ID_SIZE;i++) +	{ +		count--; +		*outptr++ = *inptr++; +	} + +// build encoded packet, keeping track of net size gain + +// sequential zero bytes are encoded as 0 [U8 count]  +// with 0 0 [count] representing wrap (>256 zeroes) + +	while (count--) +	{ +		if (!(*inptr))   // in a zero count +		{ +			if (num_zeroes) +			{ +				if (++num_zeroes > 254) +				{ +					*outptr++ = num_zeroes; +					num_zeroes = 0; +				} +				net_gain--;   // subseqent zeroes save one +			} +			else +			{ +				*outptr++ = 0; +				net_gain++;  // starting a zero count adds one +				num_zeroes = 1; +			} +			inptr++; +		} +		else +		{ +			if (num_zeroes) +			{ +				*outptr++ = num_zeroes; +				num_zeroes = 0; +			} +			*outptr++ = *inptr++; +		} +	} + +	if (num_zeroes) +	{ +		*outptr++ = num_zeroes; +	} + +	if (net_gain < 0) +	{ +		// TODO: babbage: reinstate stat collecting... +		//mCompressedPacketsOut++; +		//mUncompressedBytesOut += *data_size; + +		*data = encodedSendBuffer; +		*data_size += net_gain; +		encodedSendBuffer[0] |= LL_ZERO_CODE_FLAG;          // set the head bit to indicate zero coding + +		//mCompressedBytesOut += *data_size; + +	} +	//mTotalBytesOut += *data_size; + +	return(net_gain); +} + +void LLTemplateMessageBuilder::compressMessage(U8*& buf_ptr, U32& buffer_length) +{ +	if(ME_ZEROCODED == mCurrentSMessageTemplate->getEncoding()) +	{ +		zero_code(&buf_ptr, &buffer_length); +	} +} + +BOOL LLTemplateMessageBuilder::isMessageFull(const char* blockname) const +{ +	if(mCurrentSendTotal > MTUBYTES) +	{ +		return TRUE; +	} +	if(!blockname) +	{ +		return FALSE; +	} +	char* bnamep = (char*)blockname; +	S32 max; + +	LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[bnamep]; +	 +	switch(template_data->mType) +	{ +	case MBT_SINGLE: +		max = 1; +		break; +	case MBT_MULTIPLE: +		max = template_data->mNumber; +		break; +	case MBT_VARIABLE: +	default: +		max = MAX_BLOCKS; +		break; +	} +	if(mCurrentSMessageData->mMemberBlocks[bnamep]->mBlockNumber >= max) +	{ +		return TRUE; +	} +	return FALSE; +} + + +// make sure that all the desired data is in place and then copy the data into MAX_BUFFER_SIZEd buffer +U32 LLTemplateMessageBuilder::buildMessage(U8* buffer, U32 buffer_size) +{ +	// basic algorithm is to loop through the various pieces, building +	// size and offset info if we encounter a -1 for mSize at any +	// point that variable wasn't given data + +	// do we have a current message? +	if (!mCurrentSMessageTemplate) +	{ +		llerrs << "newMessage not called prior to buildMessage" << llendl; +		return 0; +	} + +	// zero out some useful values + +	// leave room for circuit counter +	U32 result = LL_PACKET_ID_SIZE; + +	// encode message number and adjust total_offset +	if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH) +	{ +// old, endian-dependant way +//		memcpy(&buffer[result], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8)); + +// new, independant way +		buffer[result] = (U8)mCurrentSMessageTemplate->mMessageNumber; +		result += sizeof(U8); +	} +	else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM) +	{ +		U8 temp = 255; +		memcpy(&buffer[result], &temp, sizeof(U8));  /*Flawfinder: ignore*/ +		result += sizeof(U8); + +		// mask off unsightly bits +		temp = mCurrentSMessageTemplate->mMessageNumber & 255; +		memcpy(&buffer[result], &temp, sizeof(U8));  /*Flawfinder: ignore*/ +		result += sizeof(U8); +	} +	else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW) +	{ +		U8 temp = 255; +		U16  message_num; +		memcpy(&buffer[result], &temp, sizeof(U8));  /*Flawfinder: ignore*/ +		result += sizeof(U8); +		memcpy(&buffer[result], &temp, sizeof(U8));  /*Flawfinder: ignore*/ +		result += sizeof(U8); + +		// mask off unsightly bits +		message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF; + +	    // convert to network byte order +		message_num = htons(message_num); +		memcpy(&buffer[result], &message_num, sizeof(U16)); /*Flawfinder: ignore*/ +		result += sizeof(U16); +	} +	else +	{ +		llerrs << "unexpected message frequency in buildMessage" << llendl; +		return 0; +	} + +	// counting variables used to encode multiple block info +	S32 block_count = 0; +	U8  temp_block_number; + +	// loop through msg blocks to loop through variables, +	// totalling up size data and copying into buffer +	for (LLMsgData::msg_blk_data_map_t::iterator +			 iter = mCurrentSMessageData->mMemberBlocks.begin(), +			 end = mCurrentSMessageData->mMemberBlocks.end(); +		 iter != end; iter++) +	{ +		LLMsgBlkData* mbci = iter->second; +		// do we need to encode a block code? +		if (block_count == 0) +		{ +			block_count = mbci->mBlockNumber; + +			LLMessageBlock* template_data = +				mCurrentSMessageTemplate->mMemberBlocks[mbci->mName]; +			 +			// ok, if this is the first block of a repeating pack, set +			// block_count and, if it's type MBT_VARIABLE encode a byte +			// for how many there are +			if (template_data->mType == MBT_VARIABLE) +			{ +				// remember that mBlockNumber is a S32 +				temp_block_number = (U8)mbci->mBlockNumber; +				if ((S32)(result + sizeof(U8)) < MAX_BUFFER_SIZE) +				{ +				    memcpy(&buffer[result], &temp_block_number, sizeof(U8)); +				    result += sizeof(U8); +				} +				else +				{ +				    // Just reporting error is likely not enough. Need +				    // to check how to abort or error out gracefully +				    // from this function. XXXTBD +				    llerrs << "buildMessage failed. Message excedding " +						   << "sendBuffersize." << llendl; +				} +			} +			else if (template_data->mType == MBT_MULTIPLE) +			{ +				if (block_count != template_data->mNumber) +				{ +					// nope!  need to fill it in all the way! +					llerrs << "Block " << mbci->mName +						<< " is type MBT_MULTIPLE but only has data for " +						<< block_count << " out of its " +						<< template_data->mNumber << " blocks" << llendl; +				} +			} +		} + +		// counting down multiple blocks +		block_count--; + +		// now loop through the variables +		for (LLMsgBlkData::msg_var_data_map_t::iterator iter = mbci->mMemberVarData.begin(); +			 iter != mbci->mMemberVarData.end(); iter++) +		{ +			LLMsgVarData& mvci = *iter; +			if (mvci.getSize() == -1) +			{ +				// oops, this variable wasn't ever set! +				llerrs << "The variable " << mvci.getName() << " in block " +					<< mbci->mName << " of message " +					<< mCurrentSMessageData->mName +					<< " wasn't set prior to buildMessage call" << llendl; +			} +			else +			{ +				S32 data_size = mvci.getDataSize(); +				if(data_size > 0) +				{ +					// The type is MVT_VARIABLE, which means that we +					// need to encode a size argument. Otherwise, +					// there is no need. +					S32 size = mvci.getSize(); +					U8 sizeb; +					U16 sizeh; +					switch(data_size) +					{ +					case 1: +						sizeb = size; +						htonmemcpy(&buffer[result], &sizeb, MVT_U8, 1); +						break; +					case 2: +						sizeh = size; +						htonmemcpy(&buffer[result], &sizeh, MVT_U16, 2); +						break; +					case 4: +						htonmemcpy(&buffer[result], &size, MVT_S32, 4); +						break; +					default: +						llerrs << "Attempting to build variable field with unknown size of " << size << llendl; +						break; +					} +					result += mvci.getDataSize(); +				} + +				// if there is any data to pack, pack it +				if((mvci.getData() != NULL) && mvci.getSize()) +				{ +					if(result + mvci.getSize() < buffer_size) +					{ +					    memcpy( +							&buffer[result], +							mvci.getData(), +							mvci.getSize()); +					    result += mvci.getSize(); +					} +					else +					{ +					    // Just reporting error is likely not +					    // enough. Need to check how to abort or error +					    // out gracefully from this function. XXXTBD +						llerrs << "LLMessageSystem::buildMessage failed. " +							<< "Attempted to pack " +							<< result + mvci.getSize() +							<< " bytes into a buffer with size " +							<< buffer_size << "." << llendl +					}						 +				} +			} +		} +	} +	mbSBuilt = TRUE; + +	return result; +} + +void LLTemplateMessageBuilder::copyFromMessageData(const LLMsgData& data) +{ +	// copy the blocks +	// counting variables used to encode multiple block info +	S32 block_count = 0; +    char *block_name = NULL; + +	// loop through msg blocks to loop through variables, totalling up size +	// data and filling the new (send) message +	LLMsgData::msg_blk_data_map_t::const_iterator iter =  +		data.mMemberBlocks.begin(); +	LLMsgData::msg_blk_data_map_t::const_iterator end =  +		data.mMemberBlocks.end(); +	for(; iter != end; ++iter) +	{ +		const LLMsgBlkData* mbci = iter->second; +		if(!mbci) continue; + +		// do we need to encode a block code? +		if (block_count == 0) +		{ +			block_count = mbci->mBlockNumber; +			block_name = (char *)mbci->mName; +		} + +		// counting down mutliple blocks +		block_count--; + +		nextBlock(block_name); + +		// now loop through the variables +		LLMsgBlkData::msg_var_data_map_t::const_iterator dit = mbci->mMemberVarData.begin(); +		LLMsgBlkData::msg_var_data_map_t::const_iterator dend = mbci->mMemberVarData.end(); +		 +		for(; dit != dend; ++dit) +		{ +			const LLMsgVarData& mvci = *dit; +			addData(mvci.getName(), mvci.getData(), mvci.getType(), mvci.getSize()); +		} +	} +} + +//virtual  +void LLTemplateMessageBuilder::copyFromLLSD(const LLSD&) +{ +	// TODO +} + +//virtual +void LLTemplateMessageBuilder::setBuilt(BOOL b) { mbSBuilt = b; } + +//virtual  +BOOL LLTemplateMessageBuilder::isBuilt() const {return mbSBuilt;} + +//virtual  +BOOL LLTemplateMessageBuilder::isClear() const {return mbSClear;} + +//virtual  +S32 LLTemplateMessageBuilder::getMessageSize() {return mCurrentSendTotal;} + +//virtual  +const char* LLTemplateMessageBuilder::getMessageName() const  +{ +	return mCurrentSMessageName; +} diff --git a/indra/llmessage/lltemplatemessagebuilder.h b/indra/llmessage/lltemplatemessagebuilder.h new file mode 100644 index 0000000000..ae533288fb --- /dev/null +++ b/indra/llmessage/lltemplatemessagebuilder.h @@ -0,0 +1,88 @@ +#ifndef LL_LLTEMPLATEMESSAGEBUILDER_H +#define LL_LLTEMPLATEMESSAGEBUILDER_H + +#include <map> + +#include "llmessagebuilder.h" +#include "llmsgvariabletype.h" + +class LLMsgData; +class LLMessageTemplate; +class LLMsgBlkData; +class LLMessageTemplate; + +class LLTemplateMessageBuilder : public LLMessageBuilder +{ +public: +	 +	typedef std::map<const char *, LLMessageTemplate*> message_template_name_map_t; + +	LLTemplateMessageBuilder(message_template_name_map_t&); +	virtual ~LLTemplateMessageBuilder(); + +	virtual void newMessage(const char *name); + +	virtual void nextBlock(const char* blockname); +	virtual BOOL removeLastBlock(); // TODO: babbage: remove this horror... + +	/** All add* methods expect pointers to canonical varname strings. */ +	virtual void addBinaryData(const char *varname, const void *data,  +							   S32 size); +	virtual void addBOOL(const char* varname, BOOL b); +	virtual void addS8(const char *varname, S8 s); +	virtual void addU8(const char *varname, U8 u); +	virtual void addS16(const char *varname, S16 i); +	virtual void addU16(const char *varname, U16 i); +	virtual void addF32(const char *varname, F32 f); +	virtual void addS32(const char *varname, S32 s); +	virtual void addU32(const char *varname, U32 u); +	virtual void addU64(const char *varname, U64 lu); +	virtual void addF64(const char *varname, F64 d); +	virtual void addVector3(const char *varname, const LLVector3& vec); +	virtual void addVector4(const char *varname, const LLVector4& vec); +	virtual void addVector3d(const char *varname, const LLVector3d& vec); +	virtual void addQuat(const char *varname, const LLQuaternion& quat); +	virtual void addUUID(const char *varname, const LLUUID& uuid); +	virtual void addIPAddr(const char *varname, const U32 ip); +	virtual void addIPPort(const char *varname, const U16 port); +	virtual void addString(const char* varname, const char* s); +	virtual void addString(const char* varname, const std::string& s); + +	virtual BOOL isMessageFull(const char* blockname) const; +	virtual void compressMessage(U8*& buf_ptr, U32& buffer_length); + +	virtual BOOL isBuilt() const; +	virtual BOOL isClear() const; +	virtual U32 buildMessage(U8* buffer, U32 buffer_size);  +        /**< Return built message size */ +	 +	virtual void clearMessage(); + +	// TODO: babbage: remove this horror. +	virtual void setBuilt(BOOL b); + +	virtual S32 getMessageSize(); +	virtual const char* getMessageName() const; + +	virtual void copyFromMessageData(const LLMsgData& data); +	virtual void copyFromLLSD(const LLSD&); + +private: +	void addData(const char *varname, const void *data,  +					 EMsgVariableType type, S32 size); +	 +	void addData(const char *varname, const void *data,  +						EMsgVariableType type); + +	LLMsgData* mCurrentSMessageData; +	LLMessageTemplate* mCurrentSMessageTemplate; +	LLMsgBlkData* mCurrentSDataBlock; +	char* mCurrentSMessageName; +	char* mCurrentSBlockName; +	BOOL mbSBuilt; +	BOOL mbSClear; +	S32	 mCurrentSendTotal; +	message_template_name_map_t& mMessageTemplates; +}; + +#endif // LL_LLTEMPLATEMESSAGEBUILDER_H diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp new file mode 100644 index 0000000000..892efb8697 --- /dev/null +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -0,0 +1,750 @@ +#include "lltemplatemessagereader.h" + +#include "llfasttimer.h" +#include "llmessagebuilder.h" +#include "llmessagetemplate.h" +#include "llquaternion.h" +#include "message.h" +#include "u64.h" +#include "v3dmath.h" +#include "v3math.h" +#include "v4math.h" + +LLTemplateMessageReader::LLTemplateMessageReader(message_template_number_map_t& +												 number_template_map) : +	mReceiveSize(0), +	mCurrentRMessageTemplate(NULL), +	mCurrentRMessageData(NULL), +	mMessageNumbers(number_template_map) +{ +} + +//virtual  +LLTemplateMessageReader::~LLTemplateMessageReader() +{ +	delete mCurrentRMessageData; +	mCurrentRMessageData = NULL; +} + +//virtual +void LLTemplateMessageReader::clearMessage() +{ +	mReceiveSize = -1; +	mCurrentRMessageTemplate = NULL; +	delete mCurrentRMessageData; +	mCurrentRMessageData = NULL; +} + +void LLTemplateMessageReader::getData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum, S32 max_size) +{ +	// is there a message ready to go? +	if (mReceiveSize == -1) +	{ +		llerrs << "No message waiting for decode 2!" << llendl; +		return; +	} + +	if (!mCurrentRMessageData) +	{ +		llerrs << "Invalid mCurrentMessageData in getData!" << llendl; +		return; +	} + +	char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash.  The bnamep is never derefference +	char *vnamep = (char *)varname;  + +	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); + +	if (iter == mCurrentRMessageData->mMemberBlocks.end()) +	{ +		llerrs << "Block " << blockname << " #" << blocknum +			<< " not in message " << mCurrentRMessageData->mName << llendl; +		return; +	} + +	LLMsgBlkData *msg_block_data = iter->second; +	LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; + +	if (!vardata.getName()) +	{ +		llerrs << "Variable "<< vnamep << " not in message " +			<< mCurrentRMessageData->mName<< " block " << bnamep << llendl; +		return; +	} + +	if (size && size != vardata.getSize()) +	{ +		llerrs << "Msg " << mCurrentRMessageData->mName  +			<< " variable " << vnamep +			<< " is size " << vardata.getSize() +			<< " but copying into buffer of size " << size +			<< llendl; +		return; +	} + + +	const S32 vardata_size = vardata.getSize(); +	if( max_size >= vardata_size ) +	{    +		switch( vardata_size ) +		{  +		case 1: +			*((U8*)datap) = *((U8*)vardata.getData()); +			break; +		case 2: +			*((U16*)datap) = *((U16*)vardata.getData()); +			break; +		case 4: +			*((U32*)datap) = *((U32*)vardata.getData()); +			break; +		case 8: +			((U32*)datap)[0] = ((U32*)vardata.getData())[0]; +			((U32*)datap)[1] = ((U32*)vardata.getData())[1]; +			break; +		default: +			memcpy(datap, vardata.getData(), vardata_size); +			break; +		} +	} +	else +	{ +		llwarns << "Msg " << mCurrentRMessageData->mName  +			<< " variable " << vnamep +			<< " is size " << vardata.getSize() +			<< " but truncated to max size of " << max_size +			<< llendl; + +		memcpy(datap, vardata.getData(), max_size); +	} +} + +S32 LLTemplateMessageReader::getNumberOfBlocks(const char *blockname) +{ +	// is there a message ready to go? +	if (mReceiveSize == -1) +	{ +		llerrs << "No message waiting for decode 3!" << llendl; +		return -1; +	} + +	if (!mCurrentRMessageData) +	{ +		llerrs << "Invalid mCurrentRMessageData in getData!" << llendl; +		return -1; +	} + +	char *bnamep = (char *)blockname;  + +	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); +	 +	if (iter == mCurrentRMessageData->mMemberBlocks.end()) +	{ +//		sprintf(errmsg, "Block %s not in message %s", bnamep, mCurrentRMessageData->mName); +//		llerrs << errmsg << llendl; +//		return -1; +		return 0; +	} + +	return (iter->second)->mBlockNumber; +} + +S32 LLTemplateMessageReader::getSize(const char *blockname, const char *varname) +{ +	// is there a message ready to go? +	if (mReceiveSize == -1) +	{ +		llerrs << "No message waiting for decode 4!" << llendl; +		return -1; +	} + +	if (!mCurrentRMessageData) +	{ +		llerrs << "Invalid mCurrentRMessageData in getData!" << llendl; +		return -1; +	} + +	char *bnamep = (char *)blockname;  + +	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); +	 +	if (iter == mCurrentRMessageData->mMemberBlocks.end()) +	{ +		llerrs << "Block " << bnamep << " not in message " +			<< mCurrentRMessageData->mName << llendl; +		return -1; +	} + +	char *vnamep = (char *)varname;  + +	LLMsgBlkData* msg_data = iter->second; +	LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep]; +	 +	if (!vardata.getName()) +	{ +		llerrs << "Variable " << varname << " not in message " +			<< mCurrentRMessageData->mName << " block " << bnamep << llendl; +		return -1; +	} + +	if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE) +	{ +		llerrs << "Block " << bnamep << " isn't type MBT_SINGLE," +			" use getSize with blocknum argument!" << llendl; +		return -1; +	} + +	return vardata.getSize(); +} + +S32 LLTemplateMessageReader::getSize(const char *blockname, S32 blocknum, const char *varname) +{ +	// is there a message ready to go? +	if (mReceiveSize == -1) +	{ +		llerrs << "No message waiting for decode 5!" << llendl; +		return -1; +	} + +	if (!mCurrentRMessageData) +	{ +		llerrs << "Invalid mCurrentRMessageData in getData!" << llendl; +		return -1; +	} + +	char *bnamep = (char *)blockname + blocknum;  +	char *vnamep = (char *)varname;  + +	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); +	 +	if (iter == mCurrentRMessageData->mMemberBlocks.end()) +	{ +		llerrs << "Block " << bnamep << " not in message " +			<< mCurrentRMessageData->mName << llendl; +		return -1; +	} + +	LLMsgBlkData* msg_data = iter->second; +	LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep]; +	 +	if (!vardata.getName()) +	{ +		llerrs << "Variable " << vnamep << " not in message " +			<<  mCurrentRMessageData->mName << " block " << bnamep << llendl; +		return -1; +	} + +	return vardata.getSize(); +} + +void LLTemplateMessageReader::getBinaryData(const char *blockname,  +											const char *varname, void *datap,  +											S32 size, S32 blocknum,  +											S32 max_size) +{ +	getData(blockname, varname, datap, size, blocknum, max_size); +} + +void LLTemplateMessageReader::getS8(const char *block, const char *var,  +										S8 &u, S32 blocknum) +{ +	getData(block, var, &u, sizeof(S8), blocknum); +} + +void LLTemplateMessageReader::getU8(const char *block, const char *var,  +										U8 &u, S32 blocknum) +{ +	getData(block, var, &u, sizeof(U8), blocknum); +} + +void LLTemplateMessageReader::getBOOL(const char *block, const char *var,  +										  BOOL &b, S32 blocknum ) +{ +	U8 value; +	getData(block, var, &value, sizeof(U8), blocknum); +	b = (BOOL) value; +} + +void LLTemplateMessageReader::getS16(const char *block, const char *var,  +										 S16 &d, S32 blocknum) +{ +	getData(block, var, &d, sizeof(S16), blocknum); +} + +void LLTemplateMessageReader::getU16(const char *block, const char *var,  +										 U16 &d, S32 blocknum) +{ +	getData(block, var, &d, sizeof(U16), blocknum); +} + +void LLTemplateMessageReader::getS32(const char *block, const char *var,  +										 S32 &d, S32 blocknum) +{ +	getData(block, var, &d, sizeof(S32), blocknum); +} + +void LLTemplateMessageReader::getU32(const char *block, const char *var,  +									 U32 &d, S32 blocknum) +{ +	getData(block, var, &d, sizeof(U32), blocknum); +} + +void LLTemplateMessageReader::getU64(const char *block, const char *var,  +									 U64 &d, S32 blocknum) +{ +	getData(block, var, &d, sizeof(U64), blocknum); +} + +void LLTemplateMessageReader::getF32(const char *block, const char *var,  +									 F32 &d, S32 blocknum) +{ +	getData(block, var, &d, sizeof(F32), blocknum); + +	if( !llfinite( d ) ) +	{ +		llwarns << "non-finite in getF32Fast " << block << " " << var  +				<< llendl; +		d = 0; +	} +} + +void LLTemplateMessageReader::getF64(const char *block, const char *var,  +									 F64 &d, S32 blocknum) +{ +	getData(block, var, &d, sizeof(F64), blocknum); + +	if( !llfinite( d ) ) +	{ +		llwarns << "non-finite in getF64Fast " << block << " " << var  +				<< llendl; +		d = 0; +	} +} + +void LLTemplateMessageReader::getVector3(const char *block, const char *var,  +										 LLVector3 &v, S32 blocknum ) +{ +	getData(block, var, v.mV, sizeof(v.mV), blocknum); + +	if( !v.isFinite() ) +	{ +		llwarns << "non-finite in getVector3Fast " << block << " "  +				<< var << llendl; +		v.zeroVec(); +	} +} + +void LLTemplateMessageReader::getVector4(const char *block, const char *var,  +										 LLVector4 &v, S32 blocknum) +{ +	getData(block, var, v.mV, sizeof(v.mV), blocknum); + +	if( !v.isFinite() ) +	{ +		llwarns << "non-finite in getVector4Fast " << block << " "  +				<< var << llendl; +		v.zeroVec(); +	} +} + +void LLTemplateMessageReader::getVector3d(const char *block, const char *var,  +										  LLVector3d &v, S32 blocknum ) +{ +	getData(block, var, v.mdV, sizeof(v.mdV), blocknum); + +	if( !v.isFinite() ) +	{ +		llwarns << "non-finite in getVector3dFast " << block << " "  +				<< var << llendl; +		v.zeroVec(); +	} + +} + +void LLTemplateMessageReader::getQuat(const char *block, const char *var,  +									  LLQuaternion &q, S32 blocknum) +{ +	LLVector3 vec; +	getData(block, var, vec.mV, sizeof(vec.mV), blocknum); +	if( vec.isFinite() ) +	{ +		q.unpackFromVector3( vec ); +	} +	else +	{ +		llwarns << "non-finite in getQuatFast " << block << " " << var  +				<< llendl; +		q.loadIdentity(); +	} +} + +void LLTemplateMessageReader::getUUID(const char *block, const char *var,  +									  LLUUID &u, S32 blocknum) +{ +	getData(block, var, u.mData, sizeof(u.mData), blocknum); +} + +inline void LLTemplateMessageReader::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum) +{ +	getData(block, var, &u, sizeof(U32), blocknum); +} + +inline void LLTemplateMessageReader::getIPPort(const char *block, const char *var, U16 &u, S32 blocknum) +{ +	getData(block, var, &u, sizeof(U16), blocknum); +	u = ntohs(u); +} + +inline void LLTemplateMessageReader::getString(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum ) +{ +	s[0] = '\0'; +	getData(block, var, s, 0, blocknum, buffer_size); +	s[buffer_size - 1] = '\0'; +} + +//virtual  +S32 LLTemplateMessageReader::getMessageSize() const +{ +	return mReceiveSize; +} + +// Returns template for the message contained in buffer +BOOL LLTemplateMessageReader::decodeTemplate(   +		const U8* buffer, S32 buffer_size,  // inputs +		LLMessageTemplate** msg_template ) // outputs +{ +	const U8* header = buffer + LL_PACKET_ID_SIZE; + +	// is there a message ready to go? +	if (buffer_size <= 0) +	{ +		llwarns << "No message waiting for decode!" << llendl; +		return(FALSE); +	} + +	U32 num = 0; + +	if (header[0] != 255) +	{ +		// high frequency message +		num = header[0]; +	} +	else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255)) +	{ +		// medium frequency message +		num = (255 << 8) | header[1]; +	} +	else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255)) +	{ +		// low frequency message +		U16	message_id_U16 = 0; +		// I think this check busts the message system. +		// it appears that if there is a NULL in the message #, it won't copy it.... +		// what was the goal? +		//if(header[2]) +		memcpy(&message_id_U16, &header[2], 2); + +		// dependant on endian-ness: +		//		U32	temp = (255 << 24) | (255 << 16) | header[2]; + +		// independant of endian-ness: +		message_id_U16 = ntohs(message_id_U16); +		num = 0xFFFF0000 | message_id_U16; +	} +	else // bogus packet received (too short) +	{ +		llwarns << "Packet with unusable length received (too short): " +				<< buffer_size << llendl; +		return(FALSE); +	} + +	LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num); +	if (temp) +	{ +		*msg_template = temp; +	} +	else +	{ +		llwarns << "Message #" << std::hex << num << std::dec +			<< " received but not registered!" << llendl; +		gMessageSystem->callExceptionFunc(MX_UNREGISTERED_MESSAGE); +		return(FALSE); +	} + +	return(TRUE); +} + +void LLTemplateMessageReader::logRanOffEndOfPacket( const LLHost& host ) +{ +	// we've run off the end of the packet! +	llwarns << "Ran off end of packet " << mCurrentRMessageTemplate->mName +//			<< " with id " << mCurrentRecvPacketID  +			<< " from " << host +			<< llendl; +	if(gMessageSystem->mVerboseLog) +	{ +		llinfos << "MSG: -> " << host << "\tREAD PAST END:\t" +//				<< mCurrentRecvPacketID << " " +				<< getMessageName() << llendl; +	} +	gMessageSystem->callExceptionFunc(MX_RAN_OFF_END_OF_PACKET); +} + +// decode a given message +BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender ) +{ +	llassert( mReceiveSize >= 0 ); +	llassert( mCurrentRMessageTemplate); +	llassert( !mCurrentRMessageData ); +	delete mCurrentRMessageData; // just to make sure + +	S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency); + +	// create base working data set +	mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName); +	 +	// loop through the template building the data structure as we go +	for (LLMessageTemplate::message_block_map_t::iterator iter = mCurrentRMessageTemplate->mMemberBlocks.begin(); +		 iter != mCurrentRMessageTemplate->mMemberBlocks.end(); iter++) +	{ +		LLMessageBlock* mbci = iter->second; +		U8	repeat_number; +		S32	i; + +		// how many of this block? + +		if (mbci->mType == MBT_SINGLE) +		{ +			// just one +			repeat_number = 1; +		} +		else if (mbci->mType == MBT_MULTIPLE) +		{ +			// a known number +			repeat_number = mbci->mNumber; +		} +		else if (mbci->mType == MBT_VARIABLE) +		{ +			// need to read the number from the message +			// repeat number is a single byte +			if (decode_pos >= mReceiveSize) +			{ +				logRanOffEndOfPacket( sender ); +				return FALSE; +			} +			repeat_number = buffer[decode_pos]; +			decode_pos++; +		} +		else +		{ +			llerrs << "Unknown block type" << llendl; +			return FALSE; +		} + +		LLMsgBlkData* cur_data_block = NULL; + +		// now loop through the block +		for (i = 0; i < repeat_number; i++) +		{ +			if (i) +			{ +				// build new name to prevent collisions +				// TODO: This should really change to a vector +				cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number); +				cur_data_block->mName = mbci->mName + i; +			} +			else +			{ +				cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number); +			} + +			// add the block to the message +			mCurrentRMessageData->addBlock(cur_data_block); + +			// now read the variables +			for (LLMessageBlock::message_variable_map_t::iterator iter = mbci->mMemberVariables.begin(); +				 iter != mbci->mMemberVariables.end(); iter++) +			{ +				LLMessageVariable& mvci = *(iter->second); +				// ok, build out the variables +				// add variable block +				cur_data_block->addVariable(mvci.getName(), mvci.getType()); + +				// what type of variable? +				if (mvci.getType() == MVT_VARIABLE) +				{ +					// variable, get the number of bytes to read from the template +					S32 data_size = mvci.getSize(); +					U8 tsizeb = 0; +					U16 tsizeh = 0; +					U32 tsize = 0; + +					if ((decode_pos + data_size) > mReceiveSize) +					{ +						logRanOffEndOfPacket( sender ); +						return FALSE; +					} +					switch(data_size) +					{ +					case 1: +						htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1); +						tsize = tsizeb; +						break; +					case 2: +						htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2); +						tsize = tsizeh; +						break; +					case 4: +						htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U32, 4); +						break; +					default: +						llerrs << "Attempting to read variable field with unknown size of " << data_size << llendl; +						break; +						 +					} +					decode_pos += data_size; + +					if ((decode_pos + (S32)tsize) > mReceiveSize) +					{ +						logRanOffEndOfPacket( sender ); +						return FALSE; +					} +					cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType()); +					decode_pos += tsize; +				} +				else +				{ +					// fixed! +					// so, copy data pointer and set data size to fixed size + +					if ((decode_pos + mvci.getSize()) > mReceiveSize) +					{ +						logRanOffEndOfPacket( sender ); +						return FALSE; +					} + +					cur_data_block->addData(mvci.getName(), &buffer[decode_pos], mvci.getSize(), mvci.getType()); +					decode_pos += mvci.getSize(); +				} +			} +		} +	} + +	if (mCurrentRMessageData->mMemberBlocks.empty() +		&& !mCurrentRMessageTemplate->mMemberBlocks.empty()) +	{ +		lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl; +		return FALSE; +	} + +	{ +		static LLTimer decode_timer; + +		if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback()) +		{ +			decode_timer.reset(); +		} + +		//	if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion ) +		//	{ +		//		VTResume();  // VTune +		//	} + +		{ +			LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES); +			if( !mCurrentRMessageTemplate->callHandlerFunc(gMessageSystem) ) +			{ +				llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl; +			} +		} + +		//	if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion ) +		//	{ +		//		VTPause();	// VTune +		//	} + +		if(LLMessageReader::getTimeDecodes() || gMessageSystem->getTimingCallback()) +		{ +			F32 decode_time = decode_timer.getElapsedTimeF32(); + +			if (gMessageSystem->getTimingCallback()) +			{ +				(gMessageSystem->getTimingCallback())(mCurrentRMessageTemplate->mName, +								decode_time, +								gMessageSystem->getTimingCallbackData()); +			} + +			if (LLMessageReader::getTimeDecodes()) +			{ +				mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time; + +				mCurrentRMessageTemplate->mTotalDecoded++; +				mCurrentRMessageTemplate->mTotalDecodeTime += decode_time; + +				if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time ) +				{ +					mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time; +				} + + +				if(decode_time > LLMessageReader::getTimeDecodesSpamThreshold()) +				{ +					lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" << +						mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " << +						(mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << llendl; +				} +			} +		} +	} +	return TRUE; +} + +BOOL LLTemplateMessageReader::validateMessage(const U8* buffer,  +											  S32 buffer_size,  +											  const LLHost& sender) +{ +	mReceiveSize = buffer_size; +	BOOL result = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); +	if(result) +	{ +		mCurrentRMessageTemplate->mReceiveCount++; +		lldebugst(LLERR_MESSAGE) << "MessageRecvd:"  +								 << mCurrentRMessageTemplate->mName  +								 << " from " << sender << llendl; +	} +	return result; +} + +BOOL LLTemplateMessageReader::readMessage(const U8* buffer,  +										  const LLHost& sender) +{ +	return decodeData(buffer, sender); +} + +//virtual  +const char* LLTemplateMessageReader::getMessageName() const +{ +	static char empty_string[] = ""; +	return mCurrentRMessageTemplate ? mCurrentRMessageTemplate->mName : empty_string; +} + +//virtual  +bool LLTemplateMessageReader::isTrusted() const +{ +	return mCurrentRMessageTemplate->getTrust() == MT_TRUST; +} + +//virtual  +bool LLTemplateMessageReader::isBanned(bool trustedSource) const +{ +	return mCurrentRMessageTemplate->isBanned(trustedSource); +} + +//virtual  +void LLTemplateMessageReader::copyToBuilder(LLMessageBuilder& builder) const +{ +	if(NULL == mCurrentRMessageTemplate) +    { +        return; +    } +	builder.copyFromMessageData(*mCurrentRMessageData); +} diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h new file mode 100644 index 0000000000..dd5ee393fe --- /dev/null +++ b/indra/llmessage/lltemplatemessagereader.h @@ -0,0 +1,98 @@ +#ifndef LL_LLTEMPLATEMESSAGEREADER_H +#define LL_LLTEMPLATEMESSAGEREADER_H + +#include "llmessagereader.h" + +#include <map> + +class LLMessageTemplate; +class LLMsgData; + +class LLTemplateMessageReader : public LLMessageReader +{ +public: + +	typedef std::map<U32, LLMessageTemplate*> message_template_number_map_t; + +	LLTemplateMessageReader(message_template_number_map_t&); +	virtual ~LLTemplateMessageReader(); + +	/** All get* methods expect pointers to canonical strings. */ +	virtual void getBinaryData(const char *blockname, const char *varname,  +							   void *datap, S32 size, S32 blocknum = 0,  +							   S32 max_size = S32_MAX); +	virtual void getBOOL(const char *block, const char *var, BOOL &data,  +						 S32 blocknum = 0); +	virtual void getS8(const char *block, const char *var, S8 &data,  +					   S32 blocknum = 0); +	virtual void getU8(const char *block, const char *var, U8 &data,  +					   S32 blocknum = 0); +	virtual void getS16(const char *block, const char *var, S16 &data,  +						S32 blocknum = 0); +	virtual void getU16(const char *block, const char *var, U16 &data,  +						S32 blocknum = 0); +	virtual void getS32(const char *block, const char *var, S32 &data,  +						S32 blocknum = 0); +	virtual void getF32(const char *block, const char *var, F32 &data,  +						S32 blocknum = 0); +	virtual void getU32(const char *block, const char *var, U32 &data,  +						S32 blocknum = 0); +	virtual void getU64(const char *block, const char *var, U64 &data,  +						S32 blocknum = 0); +	virtual void getF64(const char *block, const char *var, F64 &data,  +						S32 blocknum = 0); +	virtual void getVector3(const char *block, const char *var,  +							LLVector3 &vec, S32 blocknum = 0); +	virtual void getVector4(const char *block, const char *var,  +							LLVector4 &vec, S32 blocknum = 0); +	virtual void getVector3d(const char *block, const char *var,  +							 LLVector3d &vec, S32 blocknum = 0); +	virtual void getQuat(const char *block, const char *var, LLQuaternion &q,  +						 S32 blocknum = 0); +	virtual void getUUID(const char *block, const char *var, LLUUID &uuid,  +						 S32 blocknum = 0); +	virtual void getIPAddr(const char *block, const char *var, U32 &ip,  +						   S32 blocknum = 0); +	virtual void getIPPort(const char *block, const char *var, U16 &port,  +						   S32 blocknum = 0); +	virtual void getString(const char *block, const char *var,  +						   S32 buffer_size, char *buffer, S32 blocknum = 0); + +	virtual S32	getNumberOfBlocks(const char *blockname); +	virtual S32	getSize(const char *blockname, const char *varname); +	virtual S32	getSize(const char *blockname, S32 blocknum,  +						const char *varname); + +	virtual void clearMessage(); + +	virtual const char* getMessageName() const; +	virtual S32 getMessageSize() const; + +	virtual void copyToBuilder(LLMessageBuilder&) const; + +	BOOL validateMessage(const U8* buffer, S32 buffer_size,  +						 const LLHost& sender); +	BOOL readMessage(const U8* buffer, const LLHost& sender); + +	bool isTrusted() const; +	bool isBanned(bool trusted_source) const; + +private: + +	void getData(const char *blockname, const char *varname, void *datap,  +				 S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX); + +	BOOL decodeTemplate(const U8* buffer, S32 buffer_size,  // inputs +						LLMessageTemplate** msg_template ); // outputs + +	void logRanOffEndOfPacket( const LLHost& host ); + +	BOOL decodeData(const U8* buffer, const LLHost& sender ); + +	S32	mReceiveSize; +	LLMessageTemplate* mCurrentRMessageTemplate; +	LLMsgData* mCurrentRMessageData; +	message_template_number_map_t& mMessageNumbers; +}; + +#endif // LL_LLTEMPLATEMESSAGEREADER_H diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 6fb319326b..78d12cbda9 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -36,9 +36,20 @@  #include "lldarray.h"  #include "lldir.h"  #include "llerror.h" +#include "llerrorlegacy.h"  #include "llfasttimer.h" +#include "llhttpclient.h" +#include "llhttpsender.h"  #include "llmd5.h" +#include "llmessagebuilder.h" +#include "llmessageconfig.h" +#include "llpumpio.h" +#include "lltemplatemessagebuilder.h" +#include "lltemplatemessagereader.h" +#include "llmessagetemplate.h"  #include "llsd.h" +#include "llsdmessagebuilder.h" +#include "llsdmessagereader.h"  #include "lltransfermanager.h"  #include "lluuid.h"  #include "llxfermanager.h" @@ -55,405 +66,6 @@  static const F32 CIRCUIT_DUMP_TIMEOUT = 30.f;  static const S32 TRUST_TIME_WINDOW = 3; -class LLMsgVarData -{ -public: -	LLMsgVarData() : mName(NULL), mSize(-1), mDataSize(-1), mData(NULL), mType(MVT_U8) -	{ -	} - -	LLMsgVarData(const char *name, EMsgVariableType type) : mSize(-1), mDataSize(-1), mData(NULL), mType(type) -	{ -		mName = (char *)name;  -	} - -	~LLMsgVarData()  -	{ -		// copy constructor just copies the mData pointer, so only delete mData explicitly -	} -	 -	void deleteData()  -	{ -		delete[] mData; -		mData = NULL; -	} -	 -	void addData(const void *indata, S32 size, EMsgVariableType type, S32 data_size = -1); - -	char *getName() const	{ return mName; } -	S32 getSize() const		{ return mSize; } -	void *getData()			{ return (void*)mData; } -	S32 getDataSize() const	{ return mDataSize; } -	EMsgVariableType getType() const	{ return mType; } - -protected: -	char				*mName; -	S32					mSize; -	S32					mDataSize; - -	U8					*mData; -	EMsgVariableType	mType; -}; - - -class LLMsgBlkData -{ -public: -	LLMsgBlkData(const char *name, S32 blocknum) : mOffset(-1), mBlockNumber(blocknum), mTotalSize(-1)  -	{  -		mName = (char *)name;  -	} - -	~LLMsgBlkData() -	{ -		for (msg_var_data_map_t::iterator iter = mMemberVarData.begin(); -			 iter != mMemberVarData.end(); iter++) -		{ -			iter->deleteData(); -		} -	} - -	void addVariable(const char *name, EMsgVariableType type) -	{ -		LLMsgVarData tmp(name,type); -		mMemberVarData[name] = tmp; -	} - -	void addData(char *name, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1) -	{ -		LLMsgVarData* temp = &mMemberVarData[name]; // creates a new entry if one doesn't exist -		temp->addData(data, size, type, data_size); -	} - -	S32									mOffset; -	S32									mBlockNumber; -	typedef LLDynamicArrayIndexed<LLMsgVarData, const char *, 8> msg_var_data_map_t; -	msg_var_data_map_t					mMemberVarData; -	char								*mName; -	S32									mTotalSize; -}; - - -class LLMsgData -{ -public: -	LLMsgData(const char *name) : mTotalSize(-1)  -	{  -		mName = (char *)name;  -	} -	~LLMsgData() -	{ -		for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer()); -	} - -	void addBlock(LLMsgBlkData *blockp) -	{ -		mMemberBlocks[blockp->mName] = blockp; -	} - -	void addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size = -1); - -public: -	S32									mOffset; -	typedef std::map<char*, LLMsgBlkData*> msg_blk_data_map_t; -	msg_blk_data_map_t					mMemberBlocks; -	char								*mName; -	S32									mTotalSize; -}; - -inline void LLMsgVarData::addData(const void *data, S32 size, EMsgVariableType type, S32 data_size) -{ -	mSize = size; -	mDataSize = data_size; -	if ( (type != MVT_VARIABLE) && (type != MVT_FIXED)  -		 && (mType != MVT_VARIABLE) && (mType != MVT_FIXED)) -	{ -		if (mType != type) -		{ -			llwarns << "Type mismatch in addData for " << mName -					<< " message: " << gMessageSystem->getCurrentSMessageName() -					<< " block: " << gMessageSystem->getCurrentSBlockName() -					<< llendl; -		} -	} -	if(size) -	{ -		delete mData; // Delete it if it already exists -		mData = new U8[size]; -		htonmemcpy(mData, data, mType, size); -	} -} - - - -inline void LLMsgData::addDataFast(char *blockname, char *varname, const void *data, S32 size, EMsgVariableType type, S32 data_size) -{ -	// remember that if the blocknumber is > 0 then the number is appended to the name -	char *namep = (char *)blockname; -	LLMsgBlkData* block_data = mMemberBlocks[namep]; -	if (block_data->mBlockNumber) -	{ -		namep += block_data->mBlockNumber; -		block_data->addData(varname, data, size, type, data_size); -	} -	else -	{ -		block_data->addData(varname, data, size, type, data_size); -	} -} - -// LLMessage* classes store the template of messages - - -class LLMessageVariable -{ -public: -	LLMessageVariable() : mName(NULL), mType(MVT_NULL), mSize(-1) -	{ -	} - -	LLMessageVariable(char *name) : mType(MVT_NULL), mSize(-1) -	{ -		mName = name; -	} - -	LLMessageVariable(char *name, const EMsgVariableType type, const S32 size) : mType(type), mSize(size)  -	{ -		mName = gMessageStringTable.getString(name);  -	} -	 -	~LLMessageVariable() {} - -	friend std::ostream&	 operator<<(std::ostream& s, LLMessageVariable &msg); - -	EMsgVariableType getType() const				{ return mType; } -	S32	getSize() const								{ return mSize; } -	char *getName() const							{ return mName; } -protected: -	char				*mName; -	EMsgVariableType	mType; -	S32					mSize; -}; - - -typedef enum e_message_block_type -{ -	MBT_NULL, -	MBT_SINGLE, -	MBT_MULTIPLE, -	MBT_VARIABLE, -	MBT_EOF -} EMsgBlockType; - -class LLMessageBlock -{ -public: -	LLMessageBlock(char *name, EMsgBlockType type, S32 number = 1) : mType(type), mNumber(number), mTotalSize(0)  -	{  -		mName = gMessageStringTable.getString(name); -	} - -	~LLMessageBlock() -	{ -		for_each(mMemberVariables.begin(), mMemberVariables.end(), DeletePairedPointer()); -	} - -	void addVariable(char *name, const EMsgVariableType type, const S32 size) -	{ -		LLMessageVariable** varp = &mMemberVariables[name]; -		if (*varp != NULL) -		{ -			llerrs << name << " has already been used as a variable name!" << llendl; -		} -		*varp = new LLMessageVariable(name, type, size); -		if (((*varp)->getType() != MVT_VARIABLE) -			&&(mTotalSize != -1)) -		{ -			mTotalSize += (*varp)->getSize(); -		} -		else -		{ -			mTotalSize = -1; -		} -	} - -	EMsgVariableType getVariableType(char *name) -	{ -		return (mMemberVariables[name])->getType(); -	} - -	S32 getVariableSize(char *name) -	{ -		return (mMemberVariables[name])->getSize(); -	} - -	friend std::ostream&	 operator<<(std::ostream& s, LLMessageBlock &msg); - -	typedef std::map<const char *, LLMessageVariable*> message_variable_map_t; -	message_variable_map_t 					mMemberVariables; -	char									*mName; -	EMsgBlockType							mType; -	S32										mNumber; -	S32										mTotalSize; -}; - - -enum EMsgFrequency -{ -	MFT_NULL	= 0,  // value is size of message number in bytes -	MFT_HIGH	= 1, -	MFT_MEDIUM	= 2, -	MFT_LOW		= 4 -}; - -typedef enum e_message_trust -{ -	MT_TRUST, -	MT_NOTRUST -} EMsgTrust; - -enum EMsgEncoding -{ -	ME_UNENCODED, -	ME_ZEROCODED -}; - -class LLMessageTemplate -{ -public: -	LLMessageTemplate(const char *name, U32 message_number, EMsgFrequency freq) -		:  -		//mMemberBlocks(), -		mName(NULL), -		mFrequency(freq), -		mTrust(MT_NOTRUST), -		mEncoding(ME_ZEROCODED), -		mMessageNumber(message_number),  -		mTotalSize(0),  -		mReceiveCount(0), -		mReceiveBytes(0), -		mReceiveInvalid(0), -		mDecodeTimeThisFrame(0.f), -		mTotalDecoded(0), -		mTotalDecodeTime(0.f), -		mMaxDecodeTimePerMsg(0.f), -		mBanFromTrusted(false), -		mBanFromUntrusted(false), -		mHandlerFunc(NULL),  -		mUserData(NULL) -	{  -		mName = gMessageStringTable.getString(name); -	} - -	~LLMessageTemplate() -	{ -		for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer()); -	} - -	void addBlock(LLMessageBlock *blockp) -	{ -		LLMessageBlock** member_blockp = &mMemberBlocks[blockp->mName]; -		if (*member_blockp != NULL) -		{ -			llerrs << "Block " << blockp->mName -				<< "has already been used as a block name!" << llendl; -		} -		*member_blockp = blockp; -		if (  (mTotalSize != -1) -			&&(blockp->mTotalSize != -1) -			&&(  (blockp->mType == MBT_SINGLE) -			   ||(blockp->mType == MBT_MULTIPLE))) -		{ -			mTotalSize += blockp->mNumber*blockp->mTotalSize; -		} -		else -		{ -			mTotalSize = -1; -		} -	} - -	LLMessageBlock *getBlock(char *name) -	{ -		return mMemberBlocks[name]; -	} - -	// Trusted messages can only be recieved on trusted circuits. -	void setTrust(EMsgTrust t) -	{ -		mTrust = t; -	} - -	EMsgTrust getTrust(void) -	{ -		return mTrust; -	} - -	// controls for how the message should be encoded -	void setEncoding(EMsgEncoding e) -	{ -		mEncoding = e; -	} -	EMsgEncoding getEncoding() -	{ -		return mEncoding; -	} - -	void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data) -	{ -		mHandlerFunc = handler_func; -		mUserData = user_data; -	} - -	BOOL callHandlerFunc(LLMessageSystem *msgsystem) -	{ -		if (mHandlerFunc) -		{ -			mHandlerFunc(msgsystem, mUserData); -			return TRUE; -		} -		return FALSE; -	} - -	bool isBanned(bool trustedSource) -	{ -		return trustedSource ? mBanFromTrusted : mBanFromUntrusted; -	} - -	friend std::ostream&	 operator<<(std::ostream& s, LLMessageTemplate &msg); - -public: -	typedef std::map<char*, LLMessageBlock*> message_block_map_t; -	message_block_map_t						mMemberBlocks; -	char									*mName; -	EMsgFrequency							mFrequency; -	EMsgTrust								mTrust; -	EMsgEncoding							mEncoding; -	U32										mMessageNumber; -	S32										mTotalSize; -	U32										mReceiveCount;		// how many of this template have been received since last reset -	U32										mReceiveBytes;		// How many bytes received -	U32										mReceiveInvalid;	// How many "invalid" packets -	F32										mDecodeTimeThisFrame;	// Total seconds spent decoding this frame -	U32										mTotalDecoded;		// Total messages successfully decoded -	F32										mTotalDecodeTime;	// Total time successfully decoding messages -	F32										mMaxDecodeTimePerMsg; - -	bool									mBanFromTrusted; -	bool									mBanFromUntrusted; - -private: -	// message handler function (this is set by each application) -	void									(*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data); -	void									**mUserData; -}; - - -// static -BOOL LLMessageSystem::mTimeDecodes = FALSE; - -// static, 50ms per message decode -F32  LLMessageSystem::mTimeDecodesSpamThreshold = 0.05f; -  // *NOTE: This needs to be moved into a seperate file so that it never gets  // included in the viewer.  30 Sep 2002 mark  // *NOTE: I don't think it's important that the messgage system tracks @@ -468,113 +80,6 @@ public:  	apr_pollfd_t mPollFD;  }; - -// LLMessageVariable functions and friends - -std::ostream& operator<<(std::ostream& s, LLMessageVariable &msg) -{ -	s << "\t\t" << msg.mName << " ("; -	switch (msg.mType) -	{ -	case MVT_FIXED: -		s << "Fixed, " << msg.mSize << " bytes total)\n"; -		break; -	case MVT_VARIABLE: -		s << "Variable, " << msg.mSize << " bytes of size info)\n"; -		break; -	default: -		s << "Unknown\n"; -		break; -	} -	return s; -} - -// LLMessageBlock functions and friends - -std::ostream& operator<<(std::ostream& s, LLMessageBlock &msg) -{ -	s << "\t" << msg.mName << " ("; -	switch (msg.mType) -	{ -	case MBT_SINGLE: -		s << "Fixed"; -		break; -	case MBT_MULTIPLE: -		s << "Multiple - " << msg.mNumber << " copies"; -		break; -	case MBT_VARIABLE: -		s << "Variable"; -		break; -	default: -		s << "Unknown"; -		break; -	} -	if (msg.mTotalSize != -1) -	{ -		s << ", " << msg.mTotalSize << " bytes each, " << msg.mNumber*msg.mTotalSize << " bytes total)\n"; -	} -	else -	{ -		s << ")\n"; -	} - - -	for (LLMessageBlock::message_variable_map_t::iterator iter = msg.mMemberVariables.begin(); -		 iter != msg.mMemberVariables.end(); iter++) -	{ -		LLMessageVariable& ci = *(iter->second); -		s << ci; -	} - -	return s; -} - -// LLMessageTemplate functions and friends - -std::ostream& operator<<(std::ostream& s, LLMessageTemplate &msg) -{ -	switch (msg.mFrequency) -	{ -	case MFT_HIGH: -		s << "========================================\n" << "Message #" << msg.mMessageNumber << "\n" << msg.mName << " ("; -		s << "High"; -		break; -	case MFT_MEDIUM: -		s << "========================================\n" << "Message #"; -		s << (msg.mMessageNumber & 0xFF) << "\n" << msg.mName << " ("; -		s << "Medium"; -		break; -	case MFT_LOW: -		s << "========================================\n" << "Message #"; -		s << (msg.mMessageNumber & 0xFFFF) << "\n" << msg.mName << " ("; -		s << "Low"; -		break; -	default: -		s << "Unknown"; -		break; -	} - -	if (msg.mTotalSize != -1) -	{ -		s << ", " << msg.mTotalSize << " bytes total)\n"; -	} -	else -	{ -		s << ")\n"; -	} -	 -	for (LLMessageTemplate::message_block_map_t::iterator iter = msg.mMemberBlocks.begin(); -		 iter != msg.mMemberBlocks.end(); iter++) -	{ -		LLMessageBlock* ci = iter->second; -		s << *ci; -	} - -	return s; -} - -// LLMessageList functions and friends -  // Lets support a small subset of regular expressions here  // Syntax is a string made up of:  //	a	- checks against alphanumeric				([A-Za-z0-9]) @@ -776,6 +281,106 @@ BOOL	b_positive_integer_ok(char *token)  	return TRUE;  } +namespace +{ +	class LLFnPtrResponder : public LLHTTPClient::Responder +	{ +	public: +		LLFnPtrResponder(void (*callback)(void **,S32), void **callbackData) : +			mCallback(callback), +			mCallbackData(callbackData) +		{ +		} + +		virtual void error(U32 status, const std::string& reason) +		{ +			// TODO: Map status in to useful error code. +			if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_TCP_TIMEOUT); +		} +		 +		virtual void result(const LLSD& content) +		{ +			if(NULL != mCallback) mCallback(mCallbackData, LL_ERR_NOERR); +		} + +	private: + +		void (*mCallback)(void **,S32);     +		void **mCallbackData; +	}; +} + + +class LLTrustedMessageService : public LLHTTPNode +{ +	virtual bool validate(const std::string& name, LLSD& context) const +		{ return true; } + +	virtual void post(LLHTTPNode::ResponsePtr response, +					  const LLSD& context, +					  const LLSD& input) const; +}; + +//virtual +void LLTrustedMessageService::post(LLHTTPNode::ResponsePtr response, +								   const LLSD& context, +								   const LLSD& input) const +{ +	std::string name = context["request"]["wildcard"]["message-name"]; +	std::string senderIP = context["request"]["remote-host"]; +	std::string senderPort = context["request"]["headers"] +		["x-secondlife-udp-listen-port"]; + +	LLSD message_data; +	message_data["sender"] = senderIP + ":" + senderPort; +	message_data["body"] = input; +	 +	LLMessageSystem::dispatch(name, message_data, response); +} + +class LLMessageHandlerBridge : public LLHTTPNode +{ +	virtual bool validate(const std::string& name, LLSD& context) const +		{ return true; } + +	virtual void post(LLHTTPNode::ResponsePtr response, const LLSD& context,  +					  const LLSD& input) const; +}; + +//virtual  +void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,  +							const LLSD& context, const LLSD& input) const +{ +	std::string name = context["request"]["wildcard"]["message-name"]; + +	lldebugs << "Setting mLastSender " << input["sender"].asString() << llendl; +	gMessageSystem->mLastSender = LLHost(input["sender"].asString()); +	gMessageSystem->mPacketsIn += 1; +	gMessageSystem->mLLSDMessageReader->setMessage(name, input["body"]); +	gMessageSystem->mMessageReader = gMessageSystem->mLLSDMessageReader; +	 +	if(gMessageSystem->callHandler(name.c_str(), false, gMessageSystem)) +	{ +		response->result(LLSD()); +	} +	else +	{ +		response->notFound(); +	} +} + +LLHTTPRegistration<LLMessageHandlerBridge> +	gHTTPRegistrationMessageWildcard("/message/<message-name>"); + +LLHTTPRegistration<LLTrustedMessageService> +	gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>"); + +//virtual +LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder() +{ +	// even abstract base classes need a concrete destructor +} +  void LLMessageSystem::init()  {  	// initialize member variables @@ -783,25 +388,12 @@ void LLMessageSystem::init()  	mbError = FALSE;  	mErrorCode = 0; -	mIncomingCompressedSize = 0;  	mSendReliable = FALSE; -	mbSBuilt = FALSE; -	mbSClear = TRUE; -  	mUnackedListDepth = 0;  	mUnackedListSize = 0;  	mDSMaxListDepth = 0; -	mCurrentRMessageData = NULL; -	mCurrentRMessageTemplate = NULL; - -	mCurrentSMessageData = NULL; -	mCurrentSMessageTemplate = NULL; -	mCurrentSMessageName = NULL; - -	mCurrentRecvPacketID = 0; -  	mNumberHighFreqMessages = 0;  	mNumberMediumFreqMessages = 0;  	mNumberLowFreqMessages = 0; @@ -825,57 +417,26 @@ void LLMessageSystem::init()  	mOurCircuitCode = 0; +	mIncomingCompressedSize = 0; +	mCurrentRecvPacketID = 0; +  	mMessageFileChecksum = 0;  	mMessageFileVersionNumber = 0.f;  	mTimingCallback = NULL;  	mTimingCallbackData = NULL; -} - -LLMessageSystem::LLMessageSystem() -{ -	init(); -	mSystemVersionMajor = 0; -	mSystemVersionMinor = 0; -	mSystemVersionPatch = 0; -	mSystemVersionServer = 0; -	mVersionFlags = 0x0; - -	// default to not accepting packets from not alive circuits -	mbProtected = TRUE; - -	mSendPacketFailureCount = 0; -	mCircuitPrintFreq = 0.f;		// seconds - -	// initialize various bits of net info -	mSocket = 0; -	mPort = 0; - -	mPollInfop = NULL; - -	mResendDumpTime = 0; -	mMessageCountTime = 0; -	mCircuitPrintTime = 0; -	mCurrentMessageTimeSeconds = 0; - -	// Constants for dumping output based on message processing time/count -	mNumMessageCounts = 0; -	mMaxMessageCounts = 0; // >= 0 means dump warnings -	mMaxMessageTime   = 0.f; - -	mTrueReceiveSize = 0; - -	// Error if checking this state, subclass methods which aren't implemented are delegated -	// to properly constructed message system. -	mbError = TRUE; +	mMessageBuilder = NULL; +	mMessageReader = NULL;  }  // Read file and build message templates  LLMessageSystem::LLMessageSystem(const char *filename, U32 port,   								 S32 version_major,  								 S32 version_minor, -								 S32 version_patch) +								 S32 version_patch) : +	mTemplateConfirmed(FALSE), +	mTemplateMatches(FALSE)  {  	init(); @@ -894,6 +455,14 @@ LLMessageSystem::LLMessageSystem(const char *filename, U32 port,  	loadTemplateFile(filename); +	mTemplateMessageBuilder = new LLTemplateMessageBuilder(mMessageTemplates); +	mLLSDMessageBuilder = new LLSDMessageBuilder(); +	mMessageBuilder = NULL; + +	mTemplateMessageReader = new LLTemplateMessageReader(mMessageNumbers); +	mLLSDMessageReader = new LLSDMessageReader(); +	mMessageReader = NULL; +  	// initialize various bits of net info  	mSocket = 0;  	mPort = port; @@ -1712,25 +1281,25 @@ LLMessageSystem::~LLMessageSystem()  		end_net();  	} -	delete mCurrentRMessageData; -	mCurrentRMessageData = NULL; +	delete mMessageReader; +	mMessageReader = NULL; -	delete mCurrentSMessageData; -	mCurrentSMessageData = NULL; +	delete mMessageBuilder; +	mMessageBuilder = NULL;  	delete mPollInfop;  	mPollInfop = NULL; + +	mIncomingCompressedSize = 0; +	mCurrentRecvPacketID = 0;  }  void LLMessageSystem::clearReceiveState()  { -	mReceiveSize = -1;  	mCurrentRecvPacketID = 0; -	mCurrentRMessageTemplate = NULL; -	delete mCurrentRMessageData; -	mCurrentRMessageData = NULL;  	mIncomingCompressedSize = 0;  	mLastSender.invalidate(); +	mMessageReader->clearMessage();  } @@ -1757,20 +1326,23 @@ BOOL LLMessageSystem::poll(F32 seconds)  // Returns TRUE if a valid, on-circuit message has been received.  BOOL LLMessageSystem::checkMessages( S64 frame_count )  { +	// Pump   	BOOL	valid_packet = FALSE; +	mMessageReader = mTemplateMessageReader;  	LLTransferTargetVFile::updateQueue();  	if (!mNumMessageCounts)  	{ -		// This is the first message being handled after a resetReceiveCounts, we must be starting -		// the message processing loop.  Reset the timers. +		// This is the first message being handled after a resetReceiveCounts, +		// we must be starting the message processing loop.  Reset the timers.  		mCurrentMessageTimeSeconds = totalTime() * SEC_PER_USEC;  		mMessageCountTime = getMessageTimeSeconds();  	}  	// loop until either no packets or a valid packet  	// i.e., burn through packets from unregistered circuits +	S32 receive_size = 0;  	do  	{  		clearReceiveState(); @@ -1786,16 +1358,16 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  		// If you want to dump all received packets into SecondLife.log, uncomment this  		//dumpPacketToLog(); -		mReceiveSize = mTrueReceiveSize; +		receive_size = mTrueReceiveSize;  		mLastSender = mPacketRing.getLastSender(); -		if (mReceiveSize < (S32) LL_MINIMUM_VALID_PACKET_SIZE) +		if (receive_size < (S32) LL_MINIMUM_VALID_PACKET_SIZE)  		{  			// A receive size of zero is OK, that means that there are no more packets available.  			// Ones that are non-zero but below the minimum packet size are worrisome. -			if (mReceiveSize > 0) +			if (receive_size > 0)  			{ -				llwarns << "Invalid (too short) packet discarded " << mReceiveSize << llendl; +				llwarns << "Invalid (too short) packet discarded " << receive_size << llendl;  				callExceptionFunc(MX_PACKET_TOO_SHORT);  			}  			// no data in packet receive buffer @@ -1809,18 +1381,18 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			// note if packet acks are appended.  			if(buffer[0] & LL_ACK_FLAG)  			{ -				acks += buffer[--mReceiveSize]; -				true_rcv_size = mReceiveSize; -				if(mReceiveSize >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE))) +				acks += buffer[--receive_size]; +				true_rcv_size = receive_size; +				if(receive_size >= ((S32)(acks * sizeof(TPACKETID) + LL_MINIMUM_VALID_PACKET_SIZE)))  				{ -					mReceiveSize -= acks * sizeof(TPACKETID); +					receive_size -= acks * sizeof(TPACKETID);  				}  				else  				{  					// mal-formed packet. ignore it and continue with  					// the next one  					llwarns << "Malformed packet received. Packet size " -						<< mReceiveSize << " with invalid no. of acks " << acks +						<< receive_size << " with invalid no. of acks " << acks  						<< llendl;  					valid_packet = FALSE;  					continue; @@ -1829,7 +1401,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			// process the message as normal -			mIncomingCompressedSize = zeroCodeExpand(&buffer,&mReceiveSize); +			mIncomingCompressedSize = zeroCodeExpand(&buffer,&receive_size);  			mCurrentRecvPacketID = buffer[1] + ((buffer[0] & 0x0f ) * 256);  			if (sizeof(TPACKETID) == 4)  			{ @@ -1953,7 +1525,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  						std::ostringstream str;  						str << "MSG: <- " << host;  						char buffer[MAX_STRING]; /* Flawfinder: ignore*/ -						snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize : mReceiveSize), mCurrentRecvPacketID);	/* Flawfinder: ignore */ +						snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", receive_size, (mIncomingCompressedSize ? mIncomingCompressedSize : receive_size), mCurrentRecvPacketID);	/* Flawfinder: ignore */  						str << buffer << "(unknown)"  							<< (recv_reliable ? " reliable" : "")  							<< " resent " @@ -1971,23 +1543,22 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			// But we don't want to acknowledge UseCircuitCode until the circuit is  			// available, which is why the acknowledgement test is done above.  JC -			valid_packet = decodeTemplate( buffer, mReceiveSize, &mCurrentRMessageTemplate ); -			if( valid_packet ) -			{ -				mCurrentRMessageTemplate->mReceiveCount++; -				lldebugst(LLERR_MESSAGE) << "MessageRecvd:" << mCurrentRMessageTemplate->mName << " from " << host << llendl; -			} +			valid_packet = mTemplateMessageReader->validateMessage(buffer,  +														   receive_size, +														   host);  			// UseCircuitCode is allowed in even from an invalid circuit, so that  			// we can toss circuits around. -			if (valid_packet && !cdp && (mCurrentRMessageTemplate->mName != _PREHASH_UseCircuitCode) ) +			if(valid_packet && !cdp &&  +			   (mTemplateMessageReader->getMessageName() != _PREHASH_UseCircuitCode))  			{  				logMsgFromInvalidCircuit( host, recv_reliable );  				clearReceiveState();  				valid_packet = FALSE;  			} -			if (valid_packet && cdp && !cdp->getTrusted() && (mCurrentRMessageTemplate->getTrust() == MT_TRUST) ) +			if(valid_packet && cdp && !cdp->getTrusted() &&  +				mTemplateMessageReader->isTrusted())  			{  				logTrustedMsgFromUntrustedCircuit( host );  				clearReceiveState(); @@ -1997,11 +1568,11 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			}  			if (valid_packet -			&& mCurrentRMessageTemplate->isBanned(cdp && cdp->getTrusted())) +			&& mTemplateMessageReader->isBanned(cdp && cdp->getTrusted()))  			{  				llwarns << "LLMessageSystem::checkMessages "  					<< "received banned message " -					<< mCurrentRMessageTemplate->mName +					<< mTemplateMessageReader->getMessageName()  					<< " from "  					<< ((cdp && cdp->getTrusted()) ? "trusted " : "untrusted ")  					<< host << llendl; @@ -2013,7 +1584,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			{  				logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) ); -				valid_packet = decodeData( buffer, host ); +				valid_packet = mTemplateMessageReader->readMessage(buffer, host);  			}  			// It's possible that the circuit went away, because ANY message can disable the circuit @@ -2026,7 +1597,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  				if( 1 )  				{  					static char* object_update = gMessageStringTable.getString("ObjectUpdate"); -					if(object_update == mCurrentRMessageTemplate->mName ) +					if(object_update == mTemplateMessageReader->getMessageName() )  					{  						llinfos << "ObjectUpdate:" << llendl;  						U32 i; @@ -2037,8 +1608,8 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  						}  						llinfos << "" << llendl; -						llinfos << "    Zero Unencoded: " << mReceiveSize << llendl; -						for( i = 0; i<mReceiveSize; i++ ) +						llinfos << "    Zero Unencoded: " << receive_size << llendl; +						for( i = 0; i<receive_size; i++ )  						{  							llinfos << "     " << i << ": " << (U32) buffer[i] << llendl;  						} @@ -2127,7 +1698,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  				if (mbProtected  && (!cdp))  				{  					llwarns << "Packet " -							<< (mCurrentRMessageTemplate ? mCurrentRMessageTemplate->mName : "") +							<< mTemplateMessageReader->getMessageName()  							<< " from invalid circuit " << host << llendl;  					mOffCircuitPackets++;  				} @@ -2140,7 +1711,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			// Code for dumping the complete contents of a message   			// delete [] zero_unexpanded_buffer;  		} -	} while (!valid_packet && mReceiveSize > 0); +	} while (!valid_packet && receive_size > 0);  	F64 mt_sec = getMessageTimeSeconds();  	// Check to see if we need to print debug info @@ -2241,600 +1812,56 @@ void LLMessageSystem::processAcks()  	}  } - -void LLMessageSystem::newMessageFast(const char *name) -{ -	mbSBuilt = FALSE; -	mbSClear = FALSE; - -	mCurrentSendTotal = 0; -	mSendReliable = FALSE; - -	char *namep = (char *)name;  - -	if (mMessageTemplates.count(namep) > 0) -	{ -		mCurrentSMessageTemplate = mMessageTemplates[namep]; -		if (mCurrentSMessageData) -		{ -			delete mCurrentSMessageData; -		} -		mCurrentSMessageData = new LLMsgData(namep); -		mCurrentSMessageName = namep; -		mCurrentSDataBlock = NULL; -		mCurrentSBlockName = NULL; - -		// add at one of each block -		LLMessageTemplate* msg_template = mMessageTemplates[namep]; -		for (LLMessageTemplate::message_block_map_t::iterator iter = msg_template->mMemberBlocks.begin(); -			 iter != msg_template->mMemberBlocks.end(); iter++) -		{ -			LLMessageBlock* ci = iter->second; -			LLMsgBlkData	*tblockp; -			tblockp = new LLMsgBlkData(ci->mName, 0); -			mCurrentSMessageData->addBlock(tblockp); -		} -	} -	else -	{ -		llerrs << "newMessage - Message " << name << " not registered" << llendl; -	} -} -  void LLMessageSystem::copyMessageRtoS()  { -	if (!mCurrentRMessageTemplate) +	// NOTE: babbage: switch builder to match reader to avoid +	// converting message format +	if(mMessageReader == mTemplateMessageReader)  	{ -		return; +		mMessageBuilder = mTemplateMessageBuilder;  	} -	newMessageFast(mCurrentRMessageTemplate->mName); - -	// copy the blocks -	// counting variables used to encode multiple block info -	S32 block_count = 0; -    char *block_name = NULL; - -	// loop through msg blocks to loop through variables, totalling up size data and filling the new (send) message -	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.begin(); -	LLMsgData::msg_blk_data_map_t::iterator end = mCurrentRMessageData->mMemberBlocks.end(); -	for(; iter != end; ++iter) +	else  	{ -		LLMsgBlkData* mbci = iter->second; -		if(!mbci) continue; - -		// do we need to encode a block code? -		if (block_count == 0) -		{ -			block_count = mbci->mBlockNumber; -			block_name = (char *)mbci->mName; -		} - -		// counting down mutliple blocks -		block_count--; - -		nextBlockFast(block_name); - -		// now loop through the variables -		LLMsgBlkData::msg_var_data_map_t::iterator dit = mbci->mMemberVarData.begin(); -		LLMsgBlkData::msg_var_data_map_t::iterator dend = mbci->mMemberVarData.end(); -		 -		for(; dit != dend; ++dit) -		{ -			LLMsgVarData& mvci = *dit; -			addDataFast(mvci.getName(), mvci.getData(), mvci.getType(), mvci.getSize()); -		} +		mMessageBuilder = mLLSDMessageBuilder;  	} +	mSendReliable = FALSE; +	mMessageBuilder->newMessage(mMessageReader->getMessageName()); +	mMessageReader->copyToBuilder(*mMessageBuilder);  }  void LLMessageSystem::clearMessage()  { -	mbSBuilt = FALSE; -	mbSClear = TRUE; - -	mCurrentSendTotal = 0;  	mSendReliable = FALSE; - -	mCurrentSMessageTemplate = NULL; - -	delete mCurrentSMessageData; -	mCurrentSMessageData = NULL; - -	mCurrentSMessageName = NULL; -	mCurrentSDataBlock = NULL; -	mCurrentSBlockName = NULL; +	mMessageBuilder->clearMessage();  } -  // set block to add data to within current message  void LLMessageSystem::nextBlockFast(const char *blockname)  { -	char *bnamep = (char *)blockname;  - -	if (!mCurrentSMessageTemplate) -	{ -		llerrs << "newMessage not called prior to setBlock" << llendl; -		return; -	} - -	// now, does this block exist? -	LLMessageTemplate::message_block_map_t::iterator temp_iter = mCurrentSMessageTemplate->mMemberBlocks.find(bnamep); -	if (temp_iter == mCurrentSMessageTemplate->mMemberBlocks.end()) -	{ -		llerrs << "LLMessageSystem::nextBlockFast " << bnamep -			<< " not a block in " << mCurrentSMessageTemplate->mName << llendl; -		return; -	} -	 -	LLMessageBlock* template_data = temp_iter->second; -	 -	// ok, have we already set this block? -	LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[bnamep]; -	if (block_data->mBlockNumber == 0) -	{ -		// nope! set this as the current block -		block_data->mBlockNumber = 1; -		mCurrentSDataBlock = block_data; -		mCurrentSBlockName = bnamep; - -		// add placeholders for each of the variables -		for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin(); -			 iter != template_data->mMemberVariables.end(); iter++) -		{ -			LLMessageVariable& ci = *(iter->second); -			mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); -		} -		return; -	} -	else -	{ -		// already have this block. . .  -		// are we supposed to have a new one? - -		// if the block is type MBT_SINGLE this is bad! -		if (template_data->mType == MBT_SINGLE) -		{ -			llerrs << "LLMessageSystem::nextBlockFast called multiple times" -				<< " for " << bnamep << " but is type MBT_SINGLE" << llendl; -			return; -		} - - -		// if the block is type MBT_MULTIPLE then we need a known number, make sure that we're not exceeding it -		if (  (template_data->mType == MBT_MULTIPLE) -			&&(mCurrentSDataBlock->mBlockNumber == template_data->mNumber)) -		{ -			llerrs << "LLMessageSystem::nextBlockFast called " -				<< mCurrentSDataBlock->mBlockNumber << " times for " << bnamep -				<< " exceeding " << template_data->mNumber -				<< " specified in type MBT_MULTIPLE." << llendl; -			return; -		} - -		// ok, we can make a new one -		// modify the name to avoid name collision by adding number to end -		S32  count = block_data->mBlockNumber; - -		// incrememt base name's count -		block_data->mBlockNumber++; - -		if (block_data->mBlockNumber > MAX_BLOCKS) -		{ -			llerrs << "Trying to pack too many blocks into MBT_VARIABLE type (limited to " << MAX_BLOCKS << ")" << llendl; -		} - -		// create new name -		// Nota Bene: if things are working correctly, mCurrentMessageData->mMemberBlocks[blockname]->mBlockNumber == mCurrentDataBlock->mBlockNumber + 1 - -		char *nbnamep = bnamep + count; -	 -		mCurrentSDataBlock = new LLMsgBlkData(bnamep, count); -		mCurrentSDataBlock->mName = nbnamep; -		mCurrentSMessageData->mMemberBlocks[nbnamep] = mCurrentSDataBlock; - -		// add placeholders for each of the variables -		for (LLMessageBlock::message_variable_map_t::iterator -				 iter = template_data->mMemberVariables.begin(), -				 end = template_data->mMemberVariables.end(); -			 iter != end; iter++) -		{ -			LLMessageVariable& ci = *(iter->second); -			mCurrentSDataBlock->addVariable(ci.getName(), ci.getType()); -		} -		return; -	} -} - -// add data to variable in current block -void LLMessageSystem::addDataFast(const char *varname, const void *data, EMsgVariableType type, S32 size) -{ -	char *vnamep = (char *)varname;  - -	// do we have a current message? -	if (!mCurrentSMessageTemplate) -	{ -		llerrs << "newMessage not called prior to addData" << llendl; -		return; -	} - -	// do we have a current block? -	if (!mCurrentSDataBlock) -	{ -		llerrs << "setBlock not called prior to addData" << llendl; -		return; -	} - -	// kewl, add the data if it exists -	LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep]; -	if (!var_data || !var_data->getName()) -	{ -		llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl; -		return; -	} - -	// ok, it seems ok. . . are we the correct size? -	if (var_data->getType() == MVT_VARIABLE) -	{ -		// Variable 1 can only store 255 bytes, make sure our data is smaller -		if ((var_data->getSize() == 1) && -			(size > 255)) -		{ -			llwarns << "Field " << varname << " is a Variable 1 but program " -			       << "attempted to stuff more than 255 bytes in " -			       << "(" << size << ").  Clamping size and truncating data." << llendl; -			size = 255; -			char *truncate = (char *)data; -			truncate[255] = 0; -		} - -		// no correct size for MVT_VARIABLE, instead we need to tell how many bytes the size will be encoded as -		mCurrentSDataBlock->addData(vnamep, data, size, type, var_data->getSize()); -		mCurrentSendTotal += size; -	} -	else -	{ -		if (size != var_data->getSize()) -		{ -			llerrs << varname << " is type MVT_FIXED but request size " << size << " doesn't match template size " -				   << var_data->getSize() << llendl; -			return; -		} -		// alright, smash it in -		mCurrentSDataBlock->addData(vnamep, data, size, type); -		mCurrentSendTotal += size; -	} -} - -// add data to variable in current block - fails if variable isn't MVT_FIXED -void LLMessageSystem::addDataFast(const char *varname, const void *data, EMsgVariableType type) -{ -	char *vnamep = (char *)varname;  - -	// do we have a current message? -	if (!mCurrentSMessageTemplate) -	{ -		llerrs << "newMessage not called prior to addData" << llendl; -		return; -	} - -	// do we have a current block? -	if (!mCurrentSDataBlock) -	{ -		llerrs << "setBlock not called prior to addData" << llendl; -		return; -	} - -	// kewl, add the data if it exists -	LLMessageVariable* var_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]->mMemberVariables[vnamep]; -	if (!var_data->getName()) -	{ -		llerrs << vnamep << " not a variable in block " << mCurrentSBlockName << " of " << mCurrentSMessageTemplate->mName << llendl; -		return; -	} - -	// ok, it seems ok. . . are we MVT_VARIABLE? -	if (var_data->getType() == MVT_VARIABLE) -	{ -		// nope -		llerrs << vnamep << " is type MVT_VARIABLE. Call using addData(name, data, size)" << llendl; -		return; -	} -	else -	{ -		mCurrentSDataBlock->addData(vnamep, data, var_data->getSize(), type); -		mCurrentSendTotal += var_data->getSize(); -	} +	mMessageBuilder->nextBlock(blockname);  }  BOOL LLMessageSystem::isSendFull(const char* blockname)  { -	if(!blockname) +	char* stringTableName = NULL; +	if(NULL != blockname)  	{ -		return (mCurrentSendTotal > MTUBYTES); +		stringTableName = gMessageStringTable.getString(blockname);  	} -	return isSendFullFast(gMessageStringTable.getString(blockname)); +	return isSendFullFast(stringTableName);  }  BOOL LLMessageSystem::isSendFullFast(const char* blockname)  { -	if(mCurrentSendTotal > MTUBYTES) -	{ -		return TRUE; -	} -	if(!blockname) -	{ -		return FALSE; -	} -	char* bnamep = (char*)blockname; -	S32 max; - -	LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[bnamep]; -	 -	switch(template_data->mType) -	{ -	case MBT_SINGLE: -		max = 1; -		break; -	case MBT_MULTIPLE: -		max = template_data->mNumber; -		break; -	case MBT_VARIABLE: -	default: -		max = MAX_BLOCKS; -		break; -	} -	if(mCurrentSMessageData->mMemberBlocks[bnamep]->mBlockNumber >= max) -	{ -		return TRUE; -	} -	return FALSE; +	return mMessageBuilder->isMessageFull(blockname);  }  // blow away the last block of a message, return FALSE if that leaves no blocks or there wasn't a block to remove -BOOL  LLMessageSystem::removeLastBlock() -{ -	if (mCurrentSBlockName) -	{ -		if (  (mCurrentSMessageData) -			&&(mCurrentSMessageTemplate)) -		{ -			if (mCurrentSMessageData->mMemberBlocks[mCurrentSBlockName]->mBlockNumber >= 1) -			{ -				// At least one block for the current block name. - -				// Store the current block name for future reference. -				char *block_name = mCurrentSBlockName; - -				// Decrement the sent total by the size of the -				// data in the message block that we're currently building. - -				LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mCurrentSBlockName]; -				 -				for (LLMessageBlock::message_variable_map_t::iterator iter = template_data->mMemberVariables.begin(); -					 iter != template_data->mMemberVariables.end(); iter++) -				{ -					LLMessageVariable& ci = *(iter->second); -					mCurrentSendTotal -= ci.getSize(); -				} - - -				// Now we want to find the block that we're blowing away. - -				// Get the number of blocks. -				LLMsgBlkData* block_data = mCurrentSMessageData->mMemberBlocks[block_name]; -				S32 num_blocks = block_data->mBlockNumber; - -				// Use the same (suspect?) algorithm that's used to generate -				// the names in the nextBlock method to find it. -				char *block_getting_whacked = block_name + num_blocks - 1; -				LLMsgBlkData* whacked_data = mCurrentSMessageData->mMemberBlocks[block_getting_whacked]; -				delete whacked_data; -				mCurrentSMessageData->mMemberBlocks.erase(block_getting_whacked); - -				if (num_blocks <= 1) -				{ -					// we just blew away the last one, so return FALSE -					return FALSE; -				} -				else -				{ -					// Decrement the counter. -					block_data->mBlockNumber--; -					return TRUE; -				} -			} -		} -	} -	return FALSE; -} - -// make sure that all the desired data is in place and then copy the data into mSendBuffer -void LLMessageSystem::buildMessage() +// TODO: Babbage: Remove this horror. +BOOL LLMessageSystem::removeLastBlock()  { -	// basic algorithm is to loop through the various pieces, building -	// size and offset info if we encounter a -1 for mSize at any -	// point that variable wasn't given data - -	// do we have a current message? -	if (!mCurrentSMessageTemplate) -	{ -		llerrs << "newMessage not called prior to buildMessage" << llendl; -		return; -	} - -	// zero out some useful values - -	// leave room for circuit counter -	mSendSize = LL_PACKET_ID_SIZE; - -	// encode message number and adjust total_offset -	if (mCurrentSMessageTemplate->mFrequency == MFT_HIGH) -	{ -// old, endian-dependant way -//		memcpy(&mSendBuffer[mSendSize], &mCurrentMessageTemplate->mMessageNumber, sizeof(U8)); - -// new, independant way -		mSendBuffer[mSendSize] = (U8)mCurrentSMessageTemplate->mMessageNumber; -		mSendSize += sizeof(U8); -	} -	else if (mCurrentSMessageTemplate->mFrequency == MFT_MEDIUM) -	{ -		U8 temp = 255; -		memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8));  /*Flawfinder: ignore*/ -		mSendSize += sizeof(U8); - -		// mask off unsightly bits -		temp = mCurrentSMessageTemplate->mMessageNumber & 255; -		memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8));  /*Flawfinder: ignore*/ -		mSendSize += sizeof(U8); -	} -	else if (mCurrentSMessageTemplate->mFrequency == MFT_LOW) -	{ -		U8 temp = 255; -		U16  message_num; -		memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8));  /*Flawfinder: ignore*/ -		mSendSize += sizeof(U8); -		memcpy(&mSendBuffer[mSendSize], &temp, sizeof(U8));  /*Flawfinder: ignore*/ -		mSendSize += sizeof(U8); - -		// mask off unsightly bits -		message_num = mCurrentSMessageTemplate->mMessageNumber & 0xFFFF; - -	    // convert to network byte order -		message_num = htons(message_num); -		memcpy(&mSendBuffer[mSendSize], &message_num, sizeof(U16)); /*Flawfinder: ignore*/ -		mSendSize += sizeof(U16); -	} -	else -	{ -		llerrs << "unexpected message frequency in buildMessage" << llendl; -		return; -	} - -	// counting variables used to encode multiple block info -	S32 block_count = 0; -	U8  temp_block_number; - -	// loop through msg blocks to loop through variables, totalling up size data and copying into mSendBuffer -	for (LLMsgData::msg_blk_data_map_t::iterator -			 iter = mCurrentSMessageData->mMemberBlocks.begin(), -			 end = mCurrentSMessageData->mMemberBlocks.end(); -		 iter != end; iter++) -	{ -		LLMsgBlkData* mbci = iter->second; -		// do we need to encode a block code? -		if (block_count == 0) -		{ -			block_count = mbci->mBlockNumber; - -			LLMessageBlock* template_data = mCurrentSMessageTemplate->mMemberBlocks[mbci->mName]; -			 -			// ok, if this is the first block of a repeating pack, set block_count and, if it's type MBT_VARIABLE encode a byte for how many there are -			if (template_data->mType == MBT_VARIABLE) -			{ -				// remember that mBlockNumber is a S32 -				temp_block_number = (U8)mbci->mBlockNumber; -				if ((S32)(mSendSize + sizeof(U8)) < MAX_BUFFER_SIZE) -				{ -				    memcpy(&mSendBuffer[mSendSize], &temp_block_number, sizeof(U8));	/* Flawfinder: ignore */ -				    mSendSize += sizeof(U8); -				} -				else -				{ -				    // Just reporting error is likely not enough. Need -				    // to check how to abort or error out gracefully -				    // from this function. XXXTBD -				    llerrs << "buildMessage failed. Message excedding" -						" sendBuffersize." << llendl; -				} -			} -			else if (template_data->mType == MBT_MULTIPLE) -			{ -				if (block_count != template_data->mNumber) -				{ -					// nope!  need to fill it in all the way! -					llerrs << "Block " << mbci->mName -						<< " is type MBT_MULTIPLE but only has data for " -						<< block_count << " out of its " -						<< template_data->mNumber << " blocks" << llendl; -				} -			} -		} - -		// counting down multiple blocks -		block_count--; - -		// now loop through the variables -		for (LLMsgBlkData::msg_var_data_map_t::iterator iter = mbci->mMemberVarData.begin(); -			 iter != mbci->mMemberVarData.end(); iter++) -		{ -			LLMsgVarData& mvci = *iter; -			if (mvci.getSize() == -1) -			{ -				// oops, this variable wasn't ever set! -				llerrs << "The variable " << mvci.getName() << " in block " -					<< mbci->mName << " of message " -					<< mCurrentSMessageData->mName -					<< " wasn't set prior to buildMessage call" << llendl; -			} -			else -			{ -				S32 data_size = mvci.getDataSize(); -				if(data_size > 0) -				{ -					// The type is MVT_VARIABLE, which means that we -					// need to encode a size argument. Otherwise, -					// there is no need. -					S32 size = mvci.getSize(); -					U8 sizeb; -					U16 sizeh; -					switch(data_size) -					{ -					case 1: -						sizeb = size; -						htonmemcpy(&mSendBuffer[mSendSize], &sizeb, MVT_U8, 1); -						break; -					case 2: -						sizeh = size; -						htonmemcpy(&mSendBuffer[mSendSize], &sizeh, MVT_U16, 2); -						break; -					case 4: -						htonmemcpy(&mSendBuffer[mSendSize], &size, MVT_S32, 4); -						break; -					default: -						llerrs << "Attempting to build variable field with unknown size of " << size << llendl; -						break; -					} -					mSendSize += mvci.getDataSize(); -				} - -				// if there is any data to pack, pack it -				if((mvci.getData() != NULL) && mvci.getSize()) -				{ -					if(mSendSize + mvci.getSize() < (S32)sizeof(mSendBuffer)) -					{ -					    memcpy( /* Flawfinder: ignore */ -							&mSendBuffer[mSendSize], -							mvci.getData(), -							mvci.getSize()); -					    mSendSize += mvci.getSize(); -					} -					else -					{ -					    // Just reporting error is likely not -					    // enough. Need to check how to abort or error -					    // out gracefully from this function. XXXTBD -						llerrs << "LLMessageSystem::buildMessage failed. " -							<< "Attempted to pack " -							<< mSendSize + mvci.getSize() -							<< " bytes into a buffer with size " -							<< mSendBuffer << "." << llendl -					}						 -				} -			} -		} -	} -	mbSBuilt = TRUE; +	return mMessageBuilder->removeLastBlock();  }  S32 LLMessageSystem::sendReliable(const LLHost &host) @@ -2858,7 +1885,9 @@ S32 LLMessageSystem::sendSemiReliable(const LLHost &host, void (*callback)(void  		timeout = LL_SEMIRELIABLE_TIMEOUT_FACTOR * LL_AVERAGED_PING_MAX;  	} -	return sendReliable(host, 0, FALSE, timeout, callback, callback_data); +	const S32 retries = 0; +	const BOOL ping_based_timeout = FALSE; +	return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);  }  // send the message via a UDP packet @@ -2884,7 +1913,8 @@ S32 LLMessageSystem::sendReliable(	const LLHost &host,  	mSendReliable = TRUE;  	mReliablePacketParams.set(host, retries, ping_based_timeout, timeout,  -		callback, callback_data, mCurrentSMessageName); +		callback, callback_data,  +		const_cast<char*>(mMessageBuilder->getMessageName()));  	return sendMessage(host);  } @@ -2922,11 +1952,13 @@ S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void  	}  	S32 send_bytes = 0; -	if (mCurrentSendTotal) +	if (mMessageBuilder->getMessageSize())  	{  		mSendReliable = TRUE;  		// No need for ping-based retry as not going to retry -		mReliablePacketParams.set(host, 0, FALSE, timeout, callback, callback_data, mCurrentSMessageName); +		mReliablePacketParams.set(host, 0, FALSE, timeout, callback,  +								  callback_data,  +								  const_cast<char*>(mMessageBuilder->getMessageName()));  		send_bytes = sendMessage(host);  		clearMessage();  	} @@ -2940,7 +1972,7 @@ S32 LLMessageSystem::flushSemiReliable(const LLHost &host, void (*callback)(void  S32 LLMessageSystem::flushReliable(const LLHost &host)  {  	S32 send_bytes = 0; -	if (mCurrentSendTotal) +	if (mMessageBuilder->getMessageSize())  	{  		send_bytes = sendReliable(host);  	} @@ -2953,13 +1985,12 @@ S32 LLMessageSystem::flushReliable(const LLHost &host)  // so should should not use llinfos.  S32 LLMessageSystem::sendMessage(const LLHost &host)  { -	if (!mbSBuilt) +	if (! mMessageBuilder->isBuilt())  	{ -		buildMessage(); +		mSendSize = mMessageBuilder->buildMessage(mSendBuffer, +												  MAX_BUFFER_SIZE);  	} -	mCurrentSendTotal = 0; -  	if (!(host.isOk()))    // if port and ip are zero, don't bother trying to send the message  	{  		return 0; @@ -2976,10 +2007,10 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)  			if(mVerboseLog)  			{  				llinfos << "MSG: -> " << host << "\tUNKNOWN CIRCUIT:\t" -						<< mCurrentSMessageName << llendl; +						<< mMessageBuilder->getMessageName() << llendl;  			}  			llwarns << "sendMessage - Trying to send " -					<< mCurrentSMessageName << " on unknown circuit " +					<< mMessageBuilder->getMessageName() << " on unknown circuit "  					<< host << llendl;  			return 0;  		} @@ -2998,15 +2029,41 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)  			if(mVerboseLog)  			{  				llinfos << "MSG: -> " << host << "\tDEAD CIRCUIT\t\t" -						<< mCurrentSMessageName << llendl; +						<< mMessageBuilder->getMessageName() << llendl;  			}  			llwarns << "sendMessage - Trying to send message " -					<< mCurrentSMessageName << " to dead circuit " +					<< mMessageBuilder->getMessageName() << " to dead circuit "  					<< host << llendl;  			return 0;  		}  	} +	// NOTE: babbage: LLSD message -> HTTP, template message -> UDP +	if(mMessageBuilder == mLLSDMessageBuilder) +	{ +		LLSD message = mLLSDMessageBuilder->getMessage(); +		 +		const LLHTTPSender& sender = LLHTTPSender::getSender(host); +		LLHTTPClient::ResponderPtr responder = NULL; +		if(mSendReliable) +		{ +			responder = +				new LLFnPtrResponder(mReliablePacketParams.mCallback, +									 mReliablePacketParams.mCallbackData); +		} +		else +		{ +			llwarns << "LLMessageSystem::sendMessage: Sending unreliable " << mMessageBuilder->getMessageName() << " message via HTTP" << llendl; +			responder = new LLFnPtrResponder(NULL, NULL); +		} +		sender.send(host, mLLSDMessageBuilder->getMessageName(), +					message, responder); + +		mSendReliable = FALSE; +		mReliablePacketParams.clear(); +		return 1; +	} +  	memset(mSendBuffer,0,LL_PACKET_ID_SIZE); // zero out the packet ID field  	// add the send id to the front of the message @@ -3017,20 +2074,17 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)  	// Compress the message, which will usually reduce its size.  	U8 * buf_ptr = (U8 *)mSendBuffer; -	S32 buffer_length = mSendSize; -	if(ME_ZEROCODED == mCurrentSMessageTemplate->getEncoding()) -	{ -		zeroCode(&buf_ptr, &buffer_length); -	} +	U32 buffer_length = mSendSize; +	mMessageBuilder->compressMessage(buf_ptr, buffer_length);  	if (buffer_length > 1500)  	{ -		if((mCurrentSMessageName != _PREHASH_ChildAgentUpdate) -		   && (mCurrentSMessageName != _PREHASH_SendXferPacket)) +		if((mMessageBuilder->getMessageName() != _PREHASH_ChildAgentUpdate) +		   && (mMessageBuilder->getMessageName() != _PREHASH_SendXferPacket))  		{  			llwarns << "sendMessage - Trying to send "  					<< ((buffer_length > 4000) ? "EXTRA " : "") -					<< "BIG message " << mCurrentSMessageName << " - " +					<< "BIG message " << mMessageBuilder->getMessageName() << " - "  					<< buffer_length << llendl;  		}  	} @@ -3055,7 +2109,7 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)  	BOOL is_ack_appended = FALSE;  	std::vector<TPACKETID> acks;  	if((space_left > 0) && (ack_count > 0) &&  -	   (mCurrentSMessageName != _PREHASH_PacketAck)) +	   (mMessageBuilder->getMessageName() != _PREHASH_PacketAck))  	{  		buf_ptr[0] |= LL_ACK_FLAG;  		S32 append_ack_count = llmin(space_left, ack_count); @@ -3126,7 +2180,7 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)  		char buffer[MAX_STRING];			/* Flawfinder: ignore */  		snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mSendSize, buffer_length, cdp->getPacketOutID());		/* Flawfinder: ignore */  		str << buffer -			<< mCurrentSMessageTemplate->mName +			<< mMessageBuilder->getMessageName()  			<< (mSendReliable ? " reliable " : "");  		if(is_ack_appended)  		{ @@ -3137,89 +2191,19 @@ S32 LLMessageSystem::sendMessage(const LLHost &host)  		llinfos << str.str() << llendl;  	} -	lldebugst(LLERR_MESSAGE) << "MessageSent at: " << (S32)totalTime()  -		<< ", " << mCurrentSMessageTemplate->mName -		<< " to " << host  -		<< llendl; - -	// ok, clean up temp data -	delete mCurrentSMessageData; -	mCurrentSMessageData = NULL; +	/*lldebugst(LLERR_MESSAGE) << "MessageSent at: " << (S32)totalTime()  +							 << "," << mMessageBuilder->getMessageName() +							 << " to " << host  +							 << llendl;*/  	mPacketsOut++;  	mBytesOut += buffer_length; +	mSendReliable = FALSE; +	mReliablePacketParams.clear();  	return buffer_length;  } - -// Returns template for the message contained in buffer -BOOL LLMessageSystem::decodeTemplate(   -		const U8* buffer, S32 buffer_size,  // inputs -		LLMessageTemplate** msg_template ) // outputs -{ -	const U8* header = buffer + LL_PACKET_ID_SIZE; - -	// is there a message ready to go? -	if (buffer_size <= 0) -	{ -		llwarns << "No message waiting for decode!" << llendl; -		return(FALSE); -	} - -	U32 num = 0; - -	if (header[0] != 255) -	{ -		// high frequency message -		num = header[0]; -	} -	else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 1)) && (header[1] != 255)) -	{ -		// medium frequency message -		num = (255 << 8) | header[1]; -	} -	else if ((buffer_size >= ((S32) LL_MINIMUM_VALID_PACKET_SIZE + 3)) && (header[1] == 255)) -	{ -		// low frequency message -		U16	message_id_U16 = 0; -		// I think this check busts the message system. -		// it appears that if there is a NULL in the message #, it won't copy it.... -		// what was the goal? -		//if(header[2]) -		memcpy(&message_id_U16, &header[2], 2);	/* Flawfinder: ignore */ - -		// dependant on endian-ness: -		//		U32	temp = (255 << 24) | (255 << 16) | header[2]; - -		// independant of endian-ness: -		message_id_U16 = ntohs(message_id_U16); -		num = 0xFFFF0000 | message_id_U16; -	} -	else // bogus packet received (too short) -	{ -		llwarns << "Packet with unusable length received (too short): " -				<< buffer_size << llendl; -		return(FALSE); -	} - -	LLMessageTemplate* temp = get_ptr_in_map(mMessageNumbers,num); -	if (temp) -	{ -		*msg_template = temp; -	} -	else -	{ -		llwarns << "Message #" << std::hex << num << std::dec -			<< " received but not registered!" << llendl; -		callExceptionFunc(MX_UNREGISTERED_MESSAGE); -		return(FALSE); -	} - -	return(TRUE); -} - -  void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_reliable )  {  	if(mVerboseLog) @@ -3227,9 +2211,9 @@ void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_re  		std::ostringstream str;  		str << "MSG: <- " << host;  		char buffer[MAX_STRING];			/* Flawfinder: ignore */ -		snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize: mReceiveSize), mCurrentRecvPacketID);	/* Flawfinder: ignore */ +		snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize: mMessageReader->getMessageSize()), mCurrentRecvPacketID);		/* Flawfinder: ignore */  		str << buffer -			<< mCurrentRMessageTemplate->mName +			<< mMessageReader->getMessageName()  			<< (recv_reliable ? " reliable" : "")   			<< " REJECTED";  		llinfos << str.str() << llendl; @@ -3244,8 +2228,9 @@ void LLMessageSystem::logMsgFromInvalidCircuit( const LLHost& host, BOOL recv_re  	}  	else  	{ -		mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; -		mMessageCountList[mNumMessageCounts].mMessageBytes = mReceiveSize; +		// TODO: babbage: work out if we need these +		// mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; +		mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();  		mMessageCountList[mNumMessageCounts].mInvalid = TRUE;  		mNumMessageCounts++;  	} @@ -3255,11 +2240,11 @@ void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )  {  	// RequestTrustedCircuit is how we establish trust, so don't spam  	// if it's received on a trusted circuit. JC -	if (strcmp(mCurrentRMessageTemplate->mName, "RequestTrustedCircuit")) +	if (strcmp(mMessageReader->getMessageName(), "RequestTrustedCircuit"))  	{  		llwarns << "Received trusted message on untrusted circuit. "  	   		<< "Will reply with deny. " -			<< "Message: " << mCurrentRMessageTemplate->mName +			<< "Message: " << mMessageReader->getMessageName()  			<< " Host: " << host << llendl;  	} @@ -3271,10 +2256,11 @@ void LLMessageSystem::logTrustedMsgFromUntrustedCircuit( const LLHost& host )  	}  	else  	{ -		mMessageCountList[mNumMessageCounts].mMessageNum -			= mCurrentRMessageTemplate->mMessageNumber; +		// TODO: babbage: work out if we need these +		//mMessageCountList[mNumMessageCounts].mMessageNum +		//	= mCurrentRMessageTemplate->mMessageNumber;  		mMessageCountList[mNumMessageCounts].mMessageBytes -			= mReceiveSize; +			= mMessageReader->getMessageSize();  		mMessageCountList[mNumMessageCounts].mInvalid = TRUE;  		mNumMessageCounts++;  	} @@ -3288,8 +2274,9 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r  	}  	else  	{ -		mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; -		mMessageCountList[mNumMessageCounts].mMessageBytes = mReceiveSize; +		// TODO: babbage: work out if we need these +		//mMessageCountList[mNumMessageCounts].mMessageNum = mCurrentRMessageTemplate->mMessageNumber; +		mMessageCountList[mNumMessageCounts].mMessageBytes = mMessageReader->getMessageSize();  		mMessageCountList[mNumMessageCounts].mInvalid = FALSE;  		mNumMessageCounts++;  	} @@ -3306,9 +2293,9 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r  		std::ostringstream str;  		str << "MSG: <- " << host;  		char buffer[MAX_STRING];			/* Flawfinder: ignore */ -		snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mReceiveSize, (mIncomingCompressedSize ? mIncomingCompressedSize : mReceiveSize), mCurrentRecvPacketID);		/* Flawfinder: ignore */ +		snprintf(buffer, MAX_STRING, "\t%6d\t%6d\t%6d ", mMessageReader->getMessageSize(), (mIncomingCompressedSize ? mIncomingCompressedSize : mMessageReader->getMessageSize()), mCurrentRecvPacketID);		/* Flawfinder: ignore */  		str << buffer -			<< mCurrentRMessageTemplate->mName +			<< mMessageReader->getMessageName()  			<< (recv_reliable ? " reliable" : "")  			<< (recv_resent ? " resent" : "")  			<< (recv_acks ? " acks" : ""); @@ -3316,446 +2303,19 @@ void LLMessageSystem::logValidMsg(LLCircuitData *cdp, const LLHost& host, BOOL r  	}  } - -void LLMessageSystem::logRanOffEndOfPacket( const LLHost& host ) -{ -	// we've run off the end of the packet! -	llwarns << "Ran off end of packet " << mCurrentRMessageTemplate->mName -			<< " with id " << mCurrentRecvPacketID << " from " << host -			<< llendl; -	if(mVerboseLog) -	{ -		llinfos << "MSG: -> " << host << "\tREAD PAST END:\t" -				<< mCurrentRecvPacketID << " " -				<< mCurrentSMessageTemplate->mName << llendl; -	} -	callExceptionFunc(MX_RAN_OFF_END_OF_PACKET); -} - - -// decode a given message -BOOL LLMessageSystem::decodeData(const U8* buffer, const LLHost& sender ) -{ -	llassert( mReceiveSize >= 0 ); -	llassert( mCurrentRMessageTemplate); -	llassert( !mCurrentRMessageData ); -	delete mCurrentRMessageData; // just to make sure - -	S32 decode_pos = LL_PACKET_ID_SIZE + (S32)(mCurrentRMessageTemplate->mFrequency); - -	// create base working data set -	mCurrentRMessageData = new LLMsgData(mCurrentRMessageTemplate->mName); -	 -	// loop through the template building the data structure as we go -	for (LLMessageTemplate::message_block_map_t::iterator iter = mCurrentRMessageTemplate->mMemberBlocks.begin(); -		 iter != mCurrentRMessageTemplate->mMemberBlocks.end(); iter++) -	{ -		LLMessageBlock* mbci = iter->second; -		U8	repeat_number; -		S32	i; - -		// how many of this block? - -		if (mbci->mType == MBT_SINGLE) -		{ -			// just one -			repeat_number = 1; -		} -		else if (mbci->mType == MBT_MULTIPLE) -		{ -			// a known number -			repeat_number = mbci->mNumber; -		} -		else if (mbci->mType == MBT_VARIABLE) -		{ -			// need to read the number from the message -			// repeat number is a single byte -			if (decode_pos >= mReceiveSize) -			{ -				logRanOffEndOfPacket( sender ); -				return FALSE; -			} -			repeat_number = buffer[decode_pos]; -			decode_pos++; -		} -		else -		{ -			llerrs << "Unknown block type" << llendl; -			return FALSE; -		} - -		LLMsgBlkData* cur_data_block = NULL; - -		// now loop through the block -		for (i = 0; i < repeat_number; i++) -		{ -			if (i) -			{ -				// build new name to prevent collisions -				// TODO: This should really change to a vector -				cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number); -				cur_data_block->mName = mbci->mName + i; -			} -			else -			{ -				cur_data_block = new LLMsgBlkData(mbci->mName, repeat_number); -			} - -			// add the block to the message -			mCurrentRMessageData->addBlock(cur_data_block); - -			// now read the variables -			for (LLMessageBlock::message_variable_map_t::iterator iter = mbci->mMemberVariables.begin(); -				 iter != mbci->mMemberVariables.end(); iter++) -			{ -				LLMessageVariable& mvci = *(iter->second); -				// ok, build out the variables -				// add variable block -				cur_data_block->addVariable(mvci.getName(), mvci.getType()); - -				// what type of variable? -				if (mvci.getType() == MVT_VARIABLE) -				{ -					// variable, get the number of bytes to read from the template -					S32 data_size = mvci.getSize(); -					U8 tsizeb = 0; -					U16 tsizeh = 0; -					U32 tsize = 0; - -					if ((decode_pos + data_size) > mReceiveSize) -					{ -						logRanOffEndOfPacket( sender ); -						return FALSE; -					} -					switch(data_size) -					{ -					case 1: -						htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U8, 1); -						tsize = tsizeb; -						break; -					case 2: -						htonmemcpy(&tsizeh, &buffer[decode_pos], MVT_U16, 2); -						tsize = tsizeh; -						break; -					case 4: -						htonmemcpy(&tsizeb, &buffer[decode_pos], MVT_U32, 4); -						break; -					default: -						llerrs << "Attempting to read variable field with unknown size of " << data_size << llendl; -						break; -						 -					} -					decode_pos += data_size; - -					if ((decode_pos + (S32)tsize) > mReceiveSize) -					{ -						logRanOffEndOfPacket( sender ); -						return FALSE; -					} -					cur_data_block->addData(mvci.getName(), &buffer[decode_pos], tsize, mvci.getType()); -					decode_pos += tsize; -				} -				else -				{ -					// fixed! -					// so, copy data pointer and set data size to fixed size - -					if ((decode_pos + mvci.getSize()) > mReceiveSize) -					{ -						logRanOffEndOfPacket( sender ); -						return FALSE; -					} - -					cur_data_block->addData(mvci.getName(), &buffer[decode_pos], mvci.getSize(), mvci.getType()); -					decode_pos += mvci.getSize(); -				} -			} -		} -	} - -	if (mCurrentRMessageData->mMemberBlocks.empty() -		&& !mCurrentRMessageTemplate->mMemberBlocks.empty()) -	{ -		lldebugs << "Empty message '" << mCurrentRMessageTemplate->mName << "' (no blocks)" << llendl; -		return FALSE; -	} - -	{ -		static LLTimer decode_timer; - -		if( mTimeDecodes || mTimingCallback ) -		{ -			decode_timer.reset(); -		} - -		//	if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion ) -		//	{ -		//		VTResume();  // VTune -		//	} - -		{ -			LLFastTimer t(LLFastTimer::FTM_PROCESS_MESSAGES); -			if( !mCurrentRMessageTemplate->callHandlerFunc(this) ) -			{ -				llwarns << "Message from " << sender << " with no handler function received: " << mCurrentRMessageTemplate->mName << llendl; -			} -		} - -		//	if( mCurrentRMessageTemplate->mName == _PREHASH_AgentToNewRegion ) -		//	{ -		//		VTPause();	// VTune -		//	} - -		if( mTimeDecodes || mTimingCallback ) -		{ -			F32 decode_time = decode_timer.getElapsedTimeF32(); - -			if (mTimingCallback) -			{ -				mTimingCallback(mCurrentRMessageTemplate->mName, -								decode_time, -								mTimingCallbackData); -			} - -			if (mTimeDecodes) -			{ -				mCurrentRMessageTemplate->mDecodeTimeThisFrame += decode_time; - -				mCurrentRMessageTemplate->mTotalDecoded++; -				mCurrentRMessageTemplate->mTotalDecodeTime += decode_time; - -				if( mCurrentRMessageTemplate->mMaxDecodeTimePerMsg < decode_time ) -				{ -					mCurrentRMessageTemplate->mMaxDecodeTimePerMsg = decode_time; -				} - - -				if( decode_time > mTimeDecodesSpamThreshold ) -				{ -					lldebugs << "--------- Message " << mCurrentRMessageTemplate->mName << " decode took " << decode_time << " seconds. (" << -						mCurrentRMessageTemplate->mMaxDecodeTimePerMsg << " max, " << -						(mCurrentRMessageTemplate->mTotalDecodeTime / mCurrentRMessageTemplate->mTotalDecoded) << " avg)" << llendl; -				} -			} -		} -	} -	return TRUE; -} - -void LLMessageSystem::getDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum, S32 max_size) -{ -	// is there a message ready to go? -	if (mReceiveSize == -1) -	{ -		llerrs << "No message waiting for decode 2!" << llendl; -		return; -	} - -	if (!mCurrentRMessageData) -	{ -		llerrs << "Invalid mCurrentMessageData in getData!" << llendl; -		return; -	} - -	char *bnamep = (char *)blockname + blocknum; // this works because it's just a hash.  The bnamep is never derefference -	char *vnamep = (char *)varname;  - -	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); - -	if (iter == mCurrentRMessageData->mMemberBlocks.end()) -	{ -		llerrs << "Block " << blockname << " #" << blocknum -			<< " not in message " << mCurrentRMessageData->mName << llendl; -		return; -	} - -	LLMsgBlkData *msg_block_data = iter->second; -	LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; - -	if (!vardata.getName()) -	{ -		llerrs << "Variable "<< vnamep << " not in message " -			<< mCurrentRMessageData->mName<< " block " << bnamep << llendl; -		return; -	} - -	if (size && size != vardata.getSize()) -	{ -		llerrs << "Msg " << mCurrentRMessageData->mName  -			<< " variable " << vnamep -			<< " is size " << vardata.getSize() -			<< " but copying into buffer of size " << size -			<< llendl; -		return; -	} - - -	const S32 vardata_size = vardata.getSize(); -	if( max_size >= vardata_size ) -	{    -		switch( vardata_size ) -		{  -		case 1: -			*((U8*)datap) = *((U8*)vardata.getData()); -			break; -		case 2: -			*((U16*)datap) = *((U16*)vardata.getData()); -			break; -		case 4: -			*((U32*)datap) = *((U32*)vardata.getData()); -			break; -		case 8: -			((U32*)datap)[0] = ((U32*)vardata.getData())[0]; -			((U32*)datap)[1] = ((U32*)vardata.getData())[1]; -			break; -		default: -			memcpy(datap, vardata.getData(), vardata_size);	/* Flawfinder: ignore */ -			break; -		} -	} -	else -	{ -		llwarns << "Msg " << mCurrentRMessageData->mName  -			<< " variable " << vnamep -			<< " is size " << vardata.getSize() -			<< " but truncated to max size of " << max_size -			<< llendl; - -		memcpy(datap, vardata.getData(), max_size);	/* Flawfinder: ignore */ -	} -} - -S32 LLMessageSystem::getNumberOfBlocksFast(const char *blockname) -{ -	// is there a message ready to go? -	if (mReceiveSize == -1) -	{ -		llerrs << "No message waiting for decode 3!" << llendl; -		return -1; -	} - -	if (!mCurrentRMessageData) -	{ -		llerrs << "Invalid mCurrentRMessageData in getData!" << llendl; -		return -1; -	} - -	char *bnamep = (char *)blockname;  - -	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); -	 -	if (iter == mCurrentRMessageData->mMemberBlocks.end()) -	{ -//		sprintf(errmsg, "Block %s not in message %s", bnamep, mCurrentRMessageData->mName); -//		llerrs << errmsg << llendl; -//		return -1; -		return 0; -	} - -	return (iter->second)->mBlockNumber; -} - -S32 LLMessageSystem::getSizeFast(const char *blockname, const char *varname) -{ -	// is there a message ready to go? -	if (mReceiveSize == -1) -	{ -		llerrs << "No message waiting for decode 4!" << llendl; -		return -1; -	} - -	if (!mCurrentRMessageData) -	{ -		llerrs << "Invalid mCurrentRMessageData in getData!" << llendl; -		return -1; -	} - -	char *bnamep = (char *)blockname;  - -	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); -	 -	if (iter == mCurrentRMessageData->mMemberBlocks.end()) -	{ -		llerrs << "Block " << bnamep << " not in message " -			<< mCurrentRMessageData->mName << llendl; -		return -1; -	} - -	char *vnamep = (char *)varname;  - -	LLMsgBlkData* msg_data = iter->second; -	LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep]; -	 -	if (!vardata.getName()) -	{ -		llerrs << "Variable " << varname << " not in message " -			<< mCurrentRMessageData->mName << " block " << bnamep << llendl; -		return -1; -	} - -	if (mCurrentRMessageTemplate->mMemberBlocks[bnamep]->mType != MBT_SINGLE) -	{ -		llerrs << "Block " << bnamep << " isn't type MBT_SINGLE," -			" use getSize with blocknum argument!" << llendl; -		return -1; -	} - -	return vardata.getSize(); -} - - -S32 LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum, const char *varname) -{ -	// is there a message ready to go? -	if (mReceiveSize == -1) -	{ -		llerrs << "No message waiting for decode 5!" << llendl; -		return -1; -	} - -	if (!mCurrentRMessageData) -	{ -		llerrs << "Invalid mCurrentRMessageData in getData!" << llendl; -		return -1; -	} - -	char *bnamep = (char *)blockname + blocknum;  -	char *vnamep = (char *)varname;  - -	LLMsgData::msg_blk_data_map_t::iterator iter = mCurrentRMessageData->mMemberBlocks.find(bnamep); -	 -	if (iter == mCurrentRMessageData->mMemberBlocks.end()) -	{ -		llerrs << "Block " << bnamep << " not in message " -			<< mCurrentRMessageData->mName << llendl; -		return -1; -	} - -	LLMsgBlkData* msg_data = iter->second; -	LLMsgVarData& vardata = msg_data->mMemberVarData[vnamep]; -	 -	if (!vardata.getName()) -	{ -		llerrs << "Variable " << vnamep << " not in message " -			<<  mCurrentRMessageData->mName << " block " << bnamep << llendl; -		return -1; -	} - -	return vardata.getSize(); -} - -  void LLMessageSystem::sanityCheck()  { -	if (!mCurrentRMessageData) -	{ -		llerrs << "mCurrentRMessageData is NULL" << llendl; -	} +// TODO: babbage: reinstate -	if (!mCurrentRMessageTemplate) -	{ -		llerrs << "mCurrentRMessageTemplate is NULL" << llendl; -	} +//	if (!mCurrentRMessageData) +//	{ +//		llerrs << "mCurrentRMessageData is NULL" << llendl; +//	} + +//	if (!mCurrentRMessageTemplate) +//	{ +//		llerrs << "mCurrentRMessageTemplate is NULL" << llendl; +//	}  //	if (!mCurrentRTemplateBlock)  //	{ @@ -3767,25 +2327,25 @@ void LLMessageSystem::sanityCheck()  //		llerrs << "mCurrentRDataBlock is NULL" << llendl;  //	} -	if (!mCurrentSMessageData) -	{ -		llerrs << "mCurrentSMessageData is NULL" << llendl; -	} +//	if (!mCurrentSMessageData) +//	{ +//		llerrs << "mCurrentSMessageData is NULL" << llendl; +//	} -	if (!mCurrentSMessageTemplate) -	{ -		llerrs << "mCurrentSMessageTemplate is NULL" << llendl; -	} +//	if (!mCurrentSMessageTemplate) +//	{ +//		llerrs << "mCurrentSMessageTemplate is NULL" << llendl; +//	}  //	if (!mCurrentSTemplateBlock)  //	{  //		llerrs << "mCurrentSTemplateBlock is NULL" << llendl;  //	} -	if (!mCurrentSDataBlock) -	{ -		llerrs << "mCurrentSDataBlock is NULL" << llendl; -	} +//	if (!mCurrentSDataBlock) +//	{ +//		llerrs << "mCurrentSDataBlock is NULL" << llendl; +//	}  }  void LLMessageSystem::showCircuitInfo() @@ -4171,7 +2731,8 @@ bool LLMessageSystem::addCircuitCode(U32 code, const LLUUID& session_id)  //}  // static -void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**) +void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, +											void** user)  {  	U32 circuit_code_in;  	msg->getU32Fast(_PREHASH_CircuitCode, _PREHASH_Code, circuit_code_in); @@ -4291,6 +2852,13 @@ void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**)  		llinfos << "Circuit code " << circuit_code_in << " from "  				<< msg->getSender() << " for agent " << id << " in session "  				<< session_id << llendl; + +		const LLUseCircuitCodeResponder* responder = +			(const LLUseCircuitCodeResponder*) user; +		if(responder) +		{ +			responder->complete(msg->getSender(), id); +		}  	}  	else  	{ @@ -4298,7 +2866,50 @@ void LLMessageSystem::processUseCircuitCode(LLMessageSystem* msg, void**)  	}  } +static LLHTTPNode& messageRootNode() +{ +	static LLHTTPNode root_node; +	static bool initialized = false; +	if (!initialized) { +		initialized = true; +		LLHTTPRegistrar::buildAllServices(root_node); +	} + +	return root_node; +} + +//static +void LLMessageSystem::dispatch(const std::string& msg_name, +								const LLSD& message) +{ +	LLPointer<LLSimpleResponse>	responsep =	LLSimpleResponse::create(); +	dispatch(msg_name, message, responsep); +} +//static +void LLMessageSystem::dispatch(const std::string& msg_name, +								const LLSD& message, +							   LLHTTPNode::ResponsePtr responsep) +{ +	if (msg_name.empty()) +	{ +		llwarns	<< "LLMessageService::dispatch called with no message name" +				<< llendl; +		return; +	} +	 +	std::string	path = "/message/" + msg_name; +	LLSD context; +	const LLHTTPNode* handler =	messageRootNode().traverse(path, context); +	if (!handler) +	{ +		llwarns	<< "LLMessageService::dispatch > no handler for " +				<< path << llendl; +		return; +	} + +	handler->post(responsep, context, message); +}  static void check_for_unrecognized_messages(  		const char* type, @@ -4613,7 +3224,8 @@ BOOL start_messaging_system(  	S32 version_minor,  	S32 version_patch,  	BOOL b_dump_prehash_file, -	const std::string& secret) +	const std::string& secret, +	const LLUseCircuitCodeResponder* responder)  {  	gMessageSystem = new LLMessageSystem(  		template_name.c_str(), @@ -4662,7 +3274,7 @@ BOOL start_messaging_system(  	//gMessageSystem->setHandlerFuncFast(_PREHASH_AssignCircuitCode, LLMessageSystem::processAssignCircuitCode);	     	gMessageSystem->setHandlerFuncFast(_PREHASH_AddCircuitCode, LLMessageSystem::processAddCircuitCode);  	//gMessageSystem->setHandlerFuncFast(_PREHASH_AckAddCircuitCode,		ack_add_circuit_code,		NULL); -	gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode); +	gMessageSystem->setHandlerFuncFast(_PREHASH_UseCircuitCode, LLMessageSystem::processUseCircuitCode, (void**)responder);  	gMessageSystem->setHandlerFuncFast(_PREHASH_PacketAck,             process_packet_ack,	    NULL);  	gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumRequest,  process_template_checksum_request,	NULL);  	gMessageSystem->setHandlerFuncFast(_PREHASH_SecuredTemplateChecksumRequest,  process_secured_template_checksum_request,	NULL); @@ -4882,13 +3494,13 @@ void LLMessageSystem::dumpReceiveCounts()  BOOL LLMessageSystem::isClear() const  { -	return mbSClear; +	return mMessageBuilder->isClear();  }  S32 LLMessageSystem::flush(const LLHost &host)  { -	if (mCurrentSendTotal) +	if (mMessageBuilder->getMessageSize())  	{  		S32 sentbytes = sendMessage(host);  		clearMessage(); @@ -4905,91 +3517,22 @@ U32 LLMessageSystem::getListenPort( void ) const  	return mPort;  } - -S32 LLMessageSystem::zeroCode(U8 **data, S32 *data_size) +// TODO: babbage: remove this horror! +S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal()  { -	S32 count = *data_size; -	 -	S32 net_gain = 0; -	U8 num_zeroes = 0; -	 -	U8 *inptr = (U8 *)*data; -	U8 *outptr = (U8 *)mEncodedSendBuffer; - -// skip the packet id field - -	for (U32 i=0;i<LL_PACKET_ID_SIZE;i++) -	{ -		count--; -		*outptr++ = *inptr++; -	} - -// build encoded packet, keeping track of net size gain - -// sequential zero bytes are encoded as 0 [U8 count]  -// with 0 0 [count] representing wrap (>256 zeroes) - -	while (count--) -	{ -		if (!(*inptr))   // in a zero count -		{ -			if (num_zeroes) -			{ -				if (++num_zeroes > 254) -				{ -					*outptr++ = num_zeroes; -					num_zeroes = 0; -				} -				net_gain--;   // subseqent zeroes save one -			} -			else -			{ -				*outptr++ = 0; -				net_gain++;  // starting a zero count adds one -				num_zeroes = 1; -			} -			inptr++; -		} -		else -		{ -			if (num_zeroes) -			{ -				*outptr++ = num_zeroes; -				num_zeroes = 0; -			} -			*outptr++ = *inptr++; -		} -	} - -	if (num_zeroes) +	if(mMessageBuilder == mLLSDMessageBuilder)  	{ -		*outptr++ = num_zeroes; -	} - -	if (net_gain < 0) -	{ -		mCompressedPacketsOut++; -		mUncompressedBytesOut += *data_size; - -		*data = mEncodedSendBuffer; -		*data_size += net_gain; -		mEncodedSendBuffer[0] |= LL_ZERO_CODE_FLAG;          // set the head bit to indicate zero coding - -		mCompressedBytesOut += *data_size; - +		// babbage: don't compress LLSD messages, so delta is 0 +		return 0;  	} -	mTotalBytesOut += *data_size; - -	return(net_gain); -} - -S32 LLMessageSystem::zeroCodeAdjustCurrentSendTotal() -{ -	if (!mbSBuilt) +	 +	if (! mMessageBuilder->isBuilt())  	{ -		buildMessage(); +		mSendSize = mMessageBuilder->buildMessage(mSendBuffer, +												  MAX_BUFFER_SIZE);  	} -	mbSBuilt = FALSE; +	// TODO: babbage: remove this horror +	mMessageBuilder->setBuilt(FALSE);  	S32 count = mSendSize; @@ -5169,7 +3712,6 @@ void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)(  	}  } -  bool LLMessageSystem::callHandler(const char *name,  		bool trustedSource, LLMessageSystem* msg)  { @@ -5237,27 +3779,14 @@ BOOL LLMessageSystem::isCircuitCodeKnown(U32 code) const  BOOL LLMessageSystem::isMessageFast(const char *msg)  { -	if (mCurrentRMessageTemplate) -	{ -		return(msg == mCurrentRMessageTemplate->mName); -	} -	else -	{ -		return FALSE; -	} +	return(msg == mMessageReader->getMessageName());  }  char* LLMessageSystem::getMessageName()  { -	if (mCurrentRMessageTemplate) -	{ -		return mCurrentRMessageTemplate->mName; -	} -	else -	{ -		return NULL; -	} +	const char* name = mMessageReader->getMessageName(); +	return name[0] == '\0'? NULL : const_cast<char*>(name);  }  const LLUUID& LLMessageSystem::getSenderID() const @@ -5281,211 +3810,6 @@ const LLUUID& LLMessageSystem::getSenderSessionID() const  	return LLUUID::null;  } -void LLMessageSystem::addVector3Fast(const char *varname, const LLVector3& vec) -{ -	addDataFast(varname, vec.mV, MVT_LLVector3, sizeof(vec.mV)); -} - -void LLMessageSystem::addVector3(const char *varname, const LLVector3& vec) -{ -	addDataFast(gMessageStringTable.getString(varname), vec.mV, MVT_LLVector3, sizeof(vec.mV)); -} - -void LLMessageSystem::addVector4Fast(const char *varname, const LLVector4& vec) -{ -	addDataFast(varname, vec.mV, MVT_LLVector4, sizeof(vec.mV)); -} - -void LLMessageSystem::addVector4(const char *varname, const LLVector4& vec) -{ -	addDataFast(gMessageStringTable.getString(varname), vec.mV, MVT_LLVector4, sizeof(vec.mV)); -} - - -void LLMessageSystem::addVector3dFast(const char *varname, const LLVector3d& vec) -{ -	addDataFast(varname, vec.mdV, MVT_LLVector3d, sizeof(vec.mdV)); -} - -void LLMessageSystem::addVector3d(const char *varname, const LLVector3d& vec) -{ -	addDataFast(gMessageStringTable.getString(varname), vec.mdV, MVT_LLVector3d, sizeof(vec.mdV)); -} - - -void LLMessageSystem::addQuatFast(const char *varname, const LLQuaternion& quat) -{ -	addDataFast(varname, quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3)); -} - -void LLMessageSystem::addQuat(const char *varname, const LLQuaternion& quat) -{ -	addDataFast(gMessageStringTable.getString(varname), quat.packToVector3().mV, MVT_LLQuaternion, sizeof(LLVector3)); -} - - -void LLMessageSystem::addUUIDFast(const char *varname, const LLUUID& uuid) -{ -	addDataFast(varname, uuid.mData, MVT_LLUUID, sizeof(uuid.mData)); -} - -void LLMessageSystem::addUUID(const char *varname, const LLUUID& uuid) -{ -	addDataFast(gMessageStringTable.getString(varname), uuid.mData, MVT_LLUUID, sizeof(uuid.mData)); -} - -void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d, S32 blocknum) -{ -	getDataFast(block, var, &d, sizeof(F32), blocknum); - -	if( !llfinite( d ) ) -	{ -		llwarns << "non-finite in getF32Fast " << block << " " << var << llendl; -		d = 0; -	} -} - -void LLMessageSystem::getF32(const char *block, const char *var, F32 &d, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(F32), blocknum); - -	if( !llfinite( d ) ) -	{ -		llwarns << "non-finite in getF32 " << block << " " << var << llendl; -		d = 0; -	} -} - -void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d, S32 blocknum) -{ -	getDataFast(block, var, &d, sizeof(F64), blocknum); - -	if( !llfinite( d ) ) -	{ -		llwarns << "non-finite in getF64Fast " << block << " " << var << llendl; -		d = 0; -	} -} - -void LLMessageSystem::getF64(const char *block, const char *var, F64 &d, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(F64), blocknum); - -	if( !llfinite( d ) ) -	{ -		llwarns << "non-finite in getF64 " << block << " " << var << llendl; -		d = 0; -	} -} - - -void LLMessageSystem::getVector3Fast(const char *block, const char *var, LLVector3 &v, S32 blocknum ) -{ -	getDataFast(block, var, v.mV, sizeof(v.mV), blocknum); - -	if( !v.isFinite() ) -	{ -		llwarns << "non-finite in getVector3Fast " << block << " " << var << llendl; -		v.zeroVec(); -	} -} - -void LLMessageSystem::getVector3(const char *block, const char *var, LLVector3 &v, S32 blocknum ) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mV, sizeof(v.mV), blocknum); - -	if( !v.isFinite() ) -	{ -		llwarns << "non-finite in getVector4 " << block << " " << var << llendl; -		v.zeroVec(); -	} -} - -void LLMessageSystem::getVector4Fast(const char *block, const char *var, LLVector4 &v, S32 blocknum ) -{ -	getDataFast(block, var, v.mV, sizeof(v.mV), blocknum); - -	if( !v.isFinite() ) -	{ -		llwarns << "non-finite in getVector4Fast " << block << " " << var << llendl; -		v.zeroVec(); -	} -} - -void LLMessageSystem::getVector4(const char *block, const char *var, LLVector4 &v, S32 blocknum ) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mV, sizeof(v.mV), blocknum); - -	if( !v.isFinite() ) -	{ -		llwarns << "non-finite in getVector3 " << block << " " << var << llendl; -		v.zeroVec(); -	} -} - -void LLMessageSystem::getVector3dFast(const char *block, const char *var, LLVector3d &v, S32 blocknum ) -{ -	getDataFast(block, var, v.mdV, sizeof(v.mdV), blocknum); - -	if( !v.isFinite() ) -	{ -		llwarns << "non-finite in getVector3dFast " << block << " " << var << llendl; -		v.zeroVec(); -	} - -} - -void LLMessageSystem::getVector3d(const char *block, const char *var, LLVector3d &v, S32 blocknum ) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), v.mdV, sizeof(v.mdV), blocknum); - -	if( !v.isFinite() ) -	{ -		llwarns << "non-finite in getVector3d " << block << " " << var << llendl; -		v.zeroVec(); -	} -} - -void LLMessageSystem::getQuatFast(const char *block, const char *var, LLQuaternion &q, S32 blocknum ) -{ -	LLVector3 vec; -	getDataFast(block, var, vec.mV, sizeof(vec.mV), blocknum); -	if( vec.isFinite() ) -	{ -		q.unpackFromVector3( vec ); -	} -	else -	{ -		llwarns << "non-finite in getQuatFast " << block << " " << var << llendl; -		q.loadIdentity(); -	} -} - -void LLMessageSystem::getQuat(const char *block, const char *var, LLQuaternion &q, S32 blocknum ) -{ -	LLVector3 vec; -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), vec.mV, sizeof(vec.mV), blocknum); -	if( vec.isFinite() ) -	{ -		q.unpackFromVector3( vec ); -	} -	else -	{ -		llwarns << "non-finite in getQuat " << block << " " << var << llendl; -		q.loadIdentity(); -	} -} - -void LLMessageSystem::getUUIDFast(const char *block, const char *var, LLUUID &u, S32 blocknum ) -{ -	getDataFast(block, var, u.mData, sizeof(u.mData), blocknum); -} - -void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u, S32 blocknum ) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), u.mData, sizeof(u.mData), blocknum); -} -  bool LLMessageSystem::generateDigestForNumberAndUUIDs(  	char* digest,  	const U32 number, @@ -5790,6 +4114,121 @@ void LLMessageSystem::dumpPacketToLog()  }  //static +BOOL LLMessageSystem::isTemplateConfirmed() +{ +	return gMessageSystem->mTemplateConfirmed; +} + +//static +BOOL LLMessageSystem::doesTemplateMatch() +{ +	if (!isTemplateConfirmed()) +	{ +		return FALSE; +	} +	return gMessageSystem->mTemplateMatches; +} + +//static +void LLMessageSystem::sendMessageTemplateChecksum(const LLHost ¤tHost) +{ +	gMessageSystem->mTemplateConfirmed = FALSE; +	gMessageSystem->mTemplateMatches = FALSE; +	gMessageSystem->newMessageFast(_PREHASH_TemplateChecksumRequest); +	// Don't use ping-based retry +	gMessageSystem->sendReliable(currentHost, 40, FALSE, 3, NULL, NULL); +} + +//static +void LLMessageSystem::processMessageTemplateChecksumReply(LLMessageSystem *msg, +														  void** user_data) +{ +	U32 remote_template_checksum = 0; +	msg->getU32Fast(_PREHASH_DataBlock, _PREHASH_Checksum, remote_template_checksum);	 +	msg->mTemplateConfirmed = TRUE; +	if ((remote_template_checksum) != msg->mMessageFileChecksum) +	{ +		llwarns << "out of sync message template!" << llendl; +		 +		msg->mTemplateMatches = FALSE; +		msg->newMessageFast(_PREHASH_CloseCircuit); +		msg->sendMessage(msg->getSender()); +		return; +	} + +	msg->mTemplateMatches = TRUE; +	llinfos << "According to " << msg->getSender() +			<< " the message template is current!" +			<< llendl; +} + +//static +void LLMessageSystem::sendSecureMessageTemplateChecksum(const LLHost& host) +{ +	// generate an token for use during template checksum requests to +	// prevent DOS attacks from injected bad template checksum replies. +	LLUUID *template_tokenp = new LLUUID; +	template_tokenp->generate(); +	lldebugs << "random token: " << *template_tokenp << llendl; + +	// register the handler for the reply while saving off template_token +	gMessageSystem->setHandlerFuncFast(_PREHASH_TemplateChecksumReply, +							LLMessageSystem::processSecureTemplateChecksumReply, +							(void**)template_tokenp); + +	// send checksum request +	gMessageSystem->mTemplateConfirmed = FALSE; +	gMessageSystem->newMessageFast(_PREHASH_SecuredTemplateChecksumRequest); +	gMessageSystem->nextBlockFast(_PREHASH_TokenBlock); +	gMessageSystem->addUUIDFast(_PREHASH_Token, *template_tokenp); +	gMessageSystem->sendReliable(host); +} + +//static +void LLMessageSystem::processSecureTemplateChecksumReply(LLMessageSystem *msg, +														 void** user_data) +{ +	// copy the token out into the stack and delete allocated memory +	LLUUID template_token = *((LLUUID*)user_data); +	delete user_data; + +	LLUUID received_token; +	msg->getUUID("TokenBlock", "Token", received_token); + +	if(received_token != template_token) +	{ +		llwarns << "Incorrect token in template checksum reply: " +				<< received_token << llendl; +		//return do_normal_idle; +		return; +	} + +	U32 remote_template_checksum = 0; +	U8 major_version = 0; +	U8 minor_version = 0; +	U8 patch_version = 0; +	U8 server_version = 0; +	U32 flags = 0x0; +	msg->getU32("DataBlock", "Checksum", remote_template_checksum); +	msg->getU8 ("DataBlock", "MajorVersion", major_version); +	msg->getU8 ("DataBlock", "MinorVersion", minor_version); +	msg->getU8 ("DataBlock", "PatchVersion", patch_version); +	msg->getU8 ("DataBlock", "ServerVersion", server_version); +	msg->getU32("DataBlock", "Flags", flags); + +	msg->mTemplateConfirmed = TRUE; +	if (remote_template_checksum != gMessageSystem->mMessageFileChecksum) +	{ +		llinfos << "Message template out of sync" << llendl; +		msg->mTemplateMatches = FALSE; +	} +	else +	{ +		msg->mTemplateMatches = TRUE; +	} +} + +//static  U64 LLMessageSystem::getMessageTimeUsecs(const BOOL update)  {  	if (gMessageSystem) @@ -5834,3 +4273,558 @@ std::string get_shared_secret()  	return g_shared_secret;  } +typedef std::map<const char*, LLMessageBuilder*> BuilderMap; + +static void setBuilder(BuilderMap& map, const char* name, LLMessageBuilder* builder) +{ +	map[gMessageStringTable.getString(name)] = builder; +} + +void LLMessageSystem::newMessageFast(const char *name) +{ +	if(LLMessageConfig::isMessageBuiltTemplate(name)) +	{ +		mMessageBuilder = mTemplateMessageBuilder; +	} +	else +	{ +		mMessageBuilder = mLLSDMessageBuilder; +	} +	mSendReliable = FALSE; +	mMessageBuilder->newMessage(name); +} +	 +void LLMessageSystem::newMessage(const char *name) +{ +	newMessageFast(gMessageStringTable.getString(name)); +} + +void LLMessageSystem::addBinaryDataFast(const char *varname, const void *data, S32 size) +{ +	mMessageBuilder->addBinaryData(varname, data, size); +} + +void LLMessageSystem::addBinaryData(const char *varname, const void *data, S32 size) +{ +	mMessageBuilder->addBinaryData(gMessageStringTable.getString(varname),data, size); +} + +void LLMessageSystem::addS8Fast(const char *varname, S8 v) +{ +	mMessageBuilder->addS8(varname, v); +} + +void LLMessageSystem::addS8(const char *varname, S8 v) +{ +	mMessageBuilder->addS8(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addU8Fast(const char *varname, U8 v) +{ +	mMessageBuilder->addU8(varname, v); +} + +void LLMessageSystem::addU8(const char *varname, U8 v) +{ +	mMessageBuilder->addU8(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addS16Fast(const char *varname, S16 v) +{ +	mMessageBuilder->addS16(varname, v); +} + +void LLMessageSystem::addS16(const char *varname, S16 v) +{ +	mMessageBuilder->addS16(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addU16Fast(const char *varname, U16 v) +{ +	mMessageBuilder->addU16(varname, v); +} + +void LLMessageSystem::addU16(const char *varname, U16 v) +{ +	mMessageBuilder->addU16(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addF32Fast(const char *varname, F32 v) +{ +	mMessageBuilder->addF32(varname, v); +} + +void LLMessageSystem::addF32(const char *varname, F32 v) +{ +	mMessageBuilder->addF32(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addS32Fast(const char *varname, S32 v) +{ +	mMessageBuilder->addS32(varname, v); +} + +void LLMessageSystem::addS32(const char *varname, S32 v) +{ +	mMessageBuilder->addS32(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addU32Fast(const char *varname, U32 v) +{ +	mMessageBuilder->addU32(varname, v); +} + +void LLMessageSystem::addU32(const char *varname, U32 v) +{ +	mMessageBuilder->addU32(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addU64Fast(const char *varname, U64 v) +{ +	mMessageBuilder->addU64(varname, v); +} + +void LLMessageSystem::addU64(const char *varname, U64 v) +{ +	mMessageBuilder->addU64(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addF64Fast(const char *varname, F64 v) +{ +	mMessageBuilder->addF64(varname, v); +} + +void LLMessageSystem::addF64(const char *varname, F64 v) +{ +	mMessageBuilder->addF64(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addIPAddrFast(const char *varname, U32 v) +{ +	mMessageBuilder->addIPAddr(varname, v); +} + +void LLMessageSystem::addIPAddr(const char *varname, U32 v) +{ +	mMessageBuilder->addIPAddr(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addIPPortFast(const char *varname, U16 v) +{ +	mMessageBuilder->addIPPort(varname, v); +} + +void LLMessageSystem::addIPPort(const char *varname, U16 v) +{ +	mMessageBuilder->addIPPort(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addBOOLFast(const char* varname, BOOL v) +{ +	mMessageBuilder->addBOOL(varname, v); +} + +void LLMessageSystem::addBOOL(const char* varname, BOOL v) +{ +	mMessageBuilder->addBOOL(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addStringFast(const char* varname, const char* v) +{ +	mMessageBuilder->addString(varname, v); +} + +void LLMessageSystem::addString(const char* varname, const char* v) +{ +	mMessageBuilder->addString(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addStringFast(const char* varname, const std::string& v) +{ +	mMessageBuilder->addString(varname, v); +} + +void LLMessageSystem::addString(const char* varname, const std::string& v) +{ +	mMessageBuilder->addString(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addVector3Fast(const char *varname, const LLVector3& v) +{ +	mMessageBuilder->addVector3(varname, v); +} + +void LLMessageSystem::addVector3(const char *varname, const LLVector3& v) +{ +	mMessageBuilder->addVector3(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addVector4Fast(const char *varname, const LLVector4& v) +{ +	mMessageBuilder->addVector4(varname, v); +} + +void LLMessageSystem::addVector4(const char *varname, const LLVector4& v) +{ +	mMessageBuilder->addVector4(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addVector3dFast(const char *varname, const LLVector3d& v) +{ +	mMessageBuilder->addVector3d(varname, v); +} + +void LLMessageSystem::addVector3d(const char *varname, const LLVector3d& v) +{ +	mMessageBuilder->addVector3d(gMessageStringTable.getString(varname), v); +} + +void LLMessageSystem::addQuatFast(const char *varname, const LLQuaternion& v) +{ +	mMessageBuilder->addQuat(varname, v); +} + +void LLMessageSystem::addQuat(const char *varname, const LLQuaternion& v) +{ +	mMessageBuilder->addQuat(gMessageStringTable.getString(varname), v); +} + + +void LLMessageSystem::addUUIDFast(const char *varname, const LLUUID& v) +{ +	mMessageBuilder->addUUID(varname, v); +} + +void LLMessageSystem::addUUID(const char *varname, const LLUUID& v) +{ +	mMessageBuilder->addUUID(gMessageStringTable.getString(varname), v); +} + +S32 LLMessageSystem::getCurrentSendTotal() const +{ +	return mMessageBuilder->getMessageSize(); +} + +void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u,  +								S32 blocknum) +{ +	mMessageReader->getS8(block, var, u, blocknum); +} + +void LLMessageSystem::getS8(const char *block, const char *var, S8 &u,  +							S32 blocknum) +{ +	getS8Fast(gMessageStringTable.getString(block),  +			  gMessageStringTable.getString(var), u, blocknum); +} + +void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u,  +								S32 blocknum) +{ +	mMessageReader->getU8(block, var, u, blocknum); +} + +void LLMessageSystem::getU8(const char *block, const char *var, U8 &u,  +							S32 blocknum) +{ +	getU8Fast(gMessageStringTable.getString(block),  +				gMessageStringTable.getString(var), u, blocknum); +} + +void LLMessageSystem::getBOOLFast(const char *block, const char *var, BOOL &b, +								  S32 blocknum) +{ +	mMessageReader->getBOOL(block, var, b, blocknum); +} + +void LLMessageSystem::getBOOL(const char *block, const char *var, BOOL &b,  +							  S32 blocknum) +{ +	getBOOLFast(gMessageStringTable.getString(block),  +				gMessageStringTable.getString(var), b, blocknum); +} + +void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d,  +								 S32 blocknum) +{ +	mMessageReader->getS16(block, var, d, blocknum); +} + +void LLMessageSystem::getS16(const char *block, const char *var, S16 &d,  +							 S32 blocknum) +{ +	getS16Fast(gMessageStringTable.getString(block),  +			   gMessageStringTable.getString(var), d, blocknum); +} + +void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d,  +								 S32 blocknum) +{ +	mMessageReader->getU16(block, var, d, blocknum); +} + +void LLMessageSystem::getU16(const char *block, const char *var, U16 &d,  +							 S32 blocknum) +{ +	getU16Fast(gMessageStringTable.getString(block),  +			   gMessageStringTable.getString(var), d, blocknum); +} + +void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d,  +								 S32 blocknum) +{ +	mMessageReader->getS32(block, var, d, blocknum); +} + +void LLMessageSystem::getS32(const char *block, const char *var, S32 &d,  +							 S32 blocknum) +{ +	getS32Fast(gMessageStringTable.getString(block),  +			   gMessageStringTable.getString(var), d, blocknum); +} + +void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d,  +								 S32 blocknum) +{ +	mMessageReader->getU32(block, var, d, blocknum); +} + +void LLMessageSystem::getU32(const char *block, const char *var, U32 &d,  +							 S32 blocknum) +{ +	getU32Fast(gMessageStringTable.getString(block),  +				gMessageStringTable.getString(var), d, blocknum); +} + +void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d,  +								 S32 blocknum) +{ +	mMessageReader->getU64(block, var, d, blocknum); +} + +void LLMessageSystem::getU64(const char *block, const char *var, U64 &d,  +							 S32 blocknum) +{ +	 +	getU64Fast(gMessageStringTable.getString(block),  +			   gMessageStringTable.getString(var), d, blocknum); +} + +void LLMessageSystem::getBinaryDataFast(const char *blockname,  +										const char *varname,  +										void *datap, S32 size,  +										S32 blocknum, S32 max_size) +{ +	mMessageReader->getBinaryData(blockname, varname, datap, size, blocknum,  +								  max_size); +} + +void LLMessageSystem::getBinaryData(const char *blockname,  +									const char *varname,  +									void *datap, S32 size,  +									S32 blocknum, S32 max_size) +{ +	getBinaryDataFast(gMessageStringTable.getString(blockname),  +					  gMessageStringTable.getString(varname),  +					  datap, size, blocknum, max_size); +} + +void LLMessageSystem::getF32Fast(const char *block, const char *var, F32 &d,  +								 S32 blocknum) +{ +	mMessageReader->getF32(block, var, d, blocknum); +} + +void LLMessageSystem::getF32(const char *block, const char *var, F32 &d,  +							 S32 blocknum) +{ +	getF32Fast(gMessageStringTable.getString(block),  +			   gMessageStringTable.getString(var), d, blocknum); +} + +void LLMessageSystem::getF64Fast(const char *block, const char *var, F64 &d,  +								 S32 blocknum) +{ +	mMessageReader->getF64(block, var, d, blocknum); +} + +void LLMessageSystem::getF64(const char *block, const char *var, F64 &d,  +							 S32 blocknum) +{ +	getF64Fast(gMessageStringTable.getString(block),  +				gMessageStringTable.getString(var), d, blocknum); +} + + +void LLMessageSystem::getVector3Fast(const char *block, const char *var,  +									 LLVector3 &v, S32 blocknum ) +{ +	mMessageReader->getVector3(block, var, v, blocknum); +} + +void LLMessageSystem::getVector3(const char *block, const char *var,  +								 LLVector3 &v, S32 blocknum ) +{ +	getVector3Fast(gMessageStringTable.getString(block),  +				   gMessageStringTable.getString(var), v, blocknum); +} + +void LLMessageSystem::getVector4Fast(const char *block, const char *var,  +									 LLVector4 &v, S32 blocknum ) +{ +	mMessageReader->getVector4(block, var, v, blocknum); +} + +void LLMessageSystem::getVector4(const char *block, const char *var,  +								 LLVector4 &v, S32 blocknum ) +{ +	getVector4Fast(gMessageStringTable.getString(block),  +				   gMessageStringTable.getString(var), v, blocknum); +} + +void LLMessageSystem::getVector3dFast(const char *block, const char *var,  +									  LLVector3d &v, S32 blocknum ) +{ +	mMessageReader->getVector3d(block, var, v, blocknum); +} + +void LLMessageSystem::getVector3d(const char *block, const char *var,  +								  LLVector3d &v, S32 blocknum ) +{ +	getVector3dFast(gMessageStringTable.getString(block),  +				gMessageStringTable.getString(var), v, blocknum); +} + +void LLMessageSystem::getQuatFast(const char *block, const char *var,  +								  LLQuaternion &q, S32 blocknum ) +{ +	mMessageReader->getQuat(block, var, q, blocknum); +} + +void LLMessageSystem::getQuat(const char *block, const char *var,  +							  LLQuaternion &q, S32 blocknum) +{ +	getQuatFast(gMessageStringTable.getString(block),  +			gMessageStringTable.getString(var), q, blocknum); +} + +void LLMessageSystem::getUUIDFast(const char *block, const char *var,  +								  LLUUID &u, S32 blocknum ) +{ +	mMessageReader->getUUID(block, var, u, blocknum); +} + +void LLMessageSystem::getUUID(const char *block, const char *var, LLUUID &u,  +							  S32 blocknum ) +{ +	getUUIDFast(gMessageStringTable.getString(block),  +				gMessageStringTable.getString(var), u, blocknum); +} + +void LLMessageSystem::getIPAddrFast(const char *block, const char *var,  +									U32 &u, S32 blocknum) +{ +	mMessageReader->getIPAddr(block, var, u, blocknum); +} + +void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u,  +								S32 blocknum) +{ +	getIPAddrFast(gMessageStringTable.getString(block),  +				  gMessageStringTable.getString(var), u, blocknum); +} + +void LLMessageSystem::getIPPortFast(const char *block, const char *var,  +									U16 &u, S32 blocknum) +{ +	mMessageReader->getIPPort(block, var, u, blocknum); +} + +void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u,  +								S32 blocknum) +{ +	getIPPortFast(gMessageStringTable.getString(block),  +				  gMessageStringTable.getString(var), u,  +				  blocknum); +} + + +void LLMessageSystem::getStringFast(const char *block, const char *var,  +									S32 buffer_size, char *s, S32 blocknum) +{ +	mMessageReader->getString(block, var, buffer_size, s, blocknum); +} + +void LLMessageSystem::getString(const char *block, const char *var,  +								S32 buffer_size, char *s, S32 blocknum ) +{ +	getStringFast(gMessageStringTable.getString(block),  +				  gMessageStringTable.getString(var), buffer_size, s,  +				  blocknum); +} + +S32	LLMessageSystem::getNumberOfBlocksFast(const char *blockname) +{ +	return mMessageReader->getNumberOfBlocks(blockname); +} + +S32	LLMessageSystem::getNumberOfBlocks(const char *blockname) +{ +	return getNumberOfBlocksFast(gMessageStringTable.getString(blockname)); +} +	 +S32	LLMessageSystem::getSizeFast(const char *blockname, const char *varname) +{ +	return mMessageReader->getSize(blockname, varname); +} + +S32	LLMessageSystem::getSize(const char *blockname, const char *varname) +{ +	return getSizeFast(gMessageStringTable.getString(blockname),  +					   gMessageStringTable.getString(varname)); +} +	 +// size in bytes of variable length data +S32	LLMessageSystem::getSizeFast(const char *blockname, S32 blocknum,  +								 const char *varname) +{ +	return mMessageReader->getSize(blockname, blocknum, varname); +} +		 +S32	LLMessageSystem::getSize(const char *blockname, S32 blocknum,  +							 const char *varname) +{ +	return getSizeFast(gMessageStringTable.getString(blockname), blocknum,  +					   gMessageStringTable.getString(varname)); +} + +S32 LLMessageSystem::getReceiveSize() const +{ +	return mMessageReader->getMessageSize(); +} + +//static  +void LLMessageSystem::setTimeDecodes( BOOL b ) +{ +	LLMessageReader::setTimeDecodes(b); +} +		 +//static  +void LLMessageSystem::setTimeDecodesSpamThreshold( F32 seconds ) +{  +	LLMessageReader::setTimeDecodesSpamThreshold(seconds); +} + +// HACK! babbage: return true if message rxed via either UDP or HTTP +// TODO: babbage: move gServicePump in to LLMessageSystem? +bool LLMessageSystem::checkAllMessages(S64 frame_count, LLPumpIO* http_pump) +{ +	if(checkMessages(frame_count)) +	{ +		return true; +	} +	U32 packetsIn = mPacketsIn; +	http_pump->pump(); +	http_pump->callback(); +	return (mPacketsIn - packetsIn) > 0; +} diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 3ffafcc1b8..a4a8022631 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -1,5 +1,5 @@  /**  - * @file message.h + * @FILE message.h   * @brief LLMessageSystem class header file   *   * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. @@ -30,9 +30,11 @@  #include "lltimer.h"  #include "llpacketring.h"  #include "llhost.h" +#include "llhttpnode.h"  #include "llpacketack.h"  #include "message_prehash.h"  #include "llstl.h" +#include "llmsgvariabletype.h"  const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;  const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192; @@ -131,39 +133,10 @@ class LLQuaternion;  class LLSD;  class LLUUID;  class LLMessageSystem; +class LLPumpIO;  // message data pieces are used to collect the data called for by the message template -// iterator typedefs precede each class as needed -typedef enum e_message_variable_type -{ -	MVT_NULL, -	MVT_FIXED, -	MVT_VARIABLE, -	MVT_U8, -	MVT_U16, -	MVT_U32, -	MVT_U64, -	MVT_S8, -	MVT_S16, -	MVT_S32, -	MVT_S64, -	MVT_F32, -	MVT_F64, -	MVT_LLVector3, -	MVT_LLVector3d, -	MVT_LLVector4, -	MVT_LLQuaternion, -	MVT_LLUUID,	 -	MVT_BOOL, -	MVT_IP_ADDR, -	MVT_IP_PORT, -	MVT_U16Vec3, -	MVT_U16Quat, -	MVT_S16Array, -	MVT_EOL -} EMsgVariableType; -  // message system exceptional condition handlers.  enum EMessageException  { @@ -180,19 +153,29 @@ class LLMsgBlkData;  class LLMessageTemplate;  class LLMessagePollInfo; +class LLMessageBuilder; +class LLTemplateMessageBuilder; +class LLSDMessageBuilder; +class LLMessageReader; +class LLTemplateMessageReader; +class LLSDMessageReader; -class LLMessageSystem +class LLUseCircuitCodeResponder  {  	LOG_CLASS(LLMessageSystem);  public: +	virtual ~LLUseCircuitCodeResponder(); +	virtual void complete(const LLHost& host, const LLUUID& agent) const = 0; +}; + +class LLMessageSystem +{ + private:  	U8										mSendBuffer[MAX_BUFFER_SIZE]; -	// Encoded send buffer needs to be slightly larger since the zero -	// coding can potentially increase the size of the send data. -	U8										mEncodedSendBuffer[2 * MAX_BUFFER_SIZE];  	S32										mSendSize; -	S32										mCurrentSendTotal; + public:  	LLPacketRing							mPacketRing;  	LLReliablePacketParams					mReliablePacketParams; @@ -271,12 +254,7 @@ public:  	LLMessageSystem(const char *filename, U32 port, S32 version_major,  		S32 version_minor, S32 version_patch); -public: -	// Subclass use. -	LLMessageSystem(); - -public: -	virtual ~LLMessageSystem(); +	~LLMessageSystem();  	BOOL isOK() const { return !mbError; }  	S32 getErrorCode() const { return mErrorCode; } @@ -294,9 +272,6 @@ public:  		setHandlerFuncFast(gMessageStringTable.getString(name), handler_func, user_data);  	} -	bool callHandler(const char *name, bool trustedSource, -							LLMessageSystem* msg); -  	// Set a callback function for a message system exception.  	void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL);  	// Call the specified exception func, and return TRUE if a @@ -308,6 +283,14 @@ public:  	// measured in seconds.  JC  	typedef void (*msg_timing_callback)(const char* hashed_name, F32 time, void* data);  	void setTimingFunc(msg_timing_callback func, void* data = NULL); +	msg_timing_callback getTimingCallback()  +	{  +		return mTimingCallback;  +	} +	void* getTimingCallbackData()  +	{ +		return mTimingCallbackData; +	}  	// This method returns true if the code is in the circuit codes map.  	BOOL isCircuitCodeKnown(U32 code) const; @@ -347,42 +330,21 @@ public:  	void setMySessionID(const LLUUID& session_id) { mSessionID = session_id; }  	const LLUUID& getMySessionID() { return mSessionID; } -	virtual void newMessageFast(const char *name); -	void	newMessage(const char *name) -	{ -		newMessageFast(gMessageStringTable.getString(name)); -	} +	void newMessageFast(const char *name); +	void newMessage(const char *name);  	void	copyMessageRtoS();  	void	clearMessage(); -	virtual void nextBlockFast(const char *blockname); +	void nextBlockFast(const char *blockname);  	void	nextBlock(const char *blockname)  	{  		nextBlockFast(gMessageStringTable.getString(blockname));  	} -private: -	void	addDataFast(const char *varname, const void *data, EMsgVariableType type, S32 size);	// Use only for types not in system already -	void	addData(const char *varname, const void *data, EMsgVariableType type, S32 size) -	{ -		addDataFast(gMessageStringTable.getString(varname), data, type, size); -	} -	 -	void	addDataFast(const char *varname, const void *data, EMsgVariableType type);				// DEPRECATED - not typed, doesn't check storage space -	void	addData(const char *varname, const void *data, EMsgVariableType type) -	{ -		addDataFast(gMessageStringTable.getString(varname), data, type); -	}  public: -	void	addBinaryDataFast(const char *varname, const void *data, S32 size) -	{ -		addDataFast(varname, data, MVT_FIXED, size); -	} -	void	addBinaryData(const char *varname, const void *data, S32 size) -	{ -		addDataFast(gMessageStringTable.getString(varname), data, MVT_FIXED, size); -	} +	void addBinaryDataFast(const char *varname, const void *data, S32 size); +	void addBinaryData(const char *varname, const void *data, S32 size);  	void	addBOOLFast( const char* varname, BOOL b);						// typed, checks storage space  	void	addBOOL( const char* varname, BOOL b);						// typed, checks storage space @@ -398,7 +360,7 @@ public:  	void	addF32(	const char *varname, F32 f);						// typed, checks storage space  	void	addS32Fast(	const char *varname, S32 s);						// typed, checks storage space  	void	addS32(	const char *varname, S32 s);						// typed, checks storage space -	virtual void addU32Fast(	const char *varname, U32 u);						// typed, checks storage space +	void addU32Fast(	const char *varname, U32 u);						// typed, checks storage space  	void	addU32(	const char *varname, U32 u);						// typed, checks storage space  	void	addU64Fast(	const char *varname, U64 lu);						// typed, checks storage space  	void	addU64(	const char *varname, U64 lu);						// typed, checks storage space @@ -412,7 +374,7 @@ public:  	void	addVector3d( const char *varname, const LLVector3d& vec);	// typed, checks storage space  	void	addQuatFast( const char *varname, const LLQuaternion& quat);	// typed, checks storage space  	void	addQuat( const char *varname, const LLQuaternion& quat);	// typed, checks storage space -	virtual void addUUIDFast( const char *varname, const LLUUID& uuid);			// typed, checks storage space +	void addUUIDFast( const char *varname, const LLUUID& uuid);			// typed, checks storage space  	void	addUUID( const char *varname, const LLUUID& uuid);			// typed, checks storage space  	void	addIPAddrFast( const char *varname, const U32 ip);			// typed, checks storage space  	void	addIPAddr( const char *varname, const U32 ip);			// typed, checks storage space @@ -423,8 +385,8 @@ public:  	void	addStringFast( const char* varname, const std::string& s);				// typed, checks storage space  	void	addString( const char* varname, const std::string& s);				// typed, checks storage space +	S32 getCurrentSendTotal() const;  	TPACKETID getCurrentRecvPacketID() { return mCurrentRecvPacketID; } -	S32 getCurrentSendTotal() const { return mCurrentSendTotal; }  	// This method checks for current send total and returns true if  	// you need to go to the next block type or need to start a new @@ -433,16 +395,16 @@ public:  	BOOL isSendFull(const char* blockname = NULL);  	BOOL isSendFullFast(const char* blockname = NULL); -	BOOL	removeLastBlock(); +	BOOL removeLastBlock(); -	void	buildMessage(); +	//void	buildMessage();  	S32     zeroCode(U8 **data, S32 *data_size);  	S32		zeroCodeExpand(U8 **data, S32 *data_size);  	S32		zeroCodeAdjustCurrentSendTotal();  	// Uses ping-based retry -	virtual S32 sendReliable(const LLHost &host); +	S32 sendReliable(const LLHost &host);  	// Uses ping-based retry  	S32	sendReliable(const U32 circuit)			{ return sendReliable(findHost(circuit)); } @@ -471,28 +433,10 @@ public:  	S32		sendMessage(const LLHost &host);  	S32		sendMessage(const U32 circuit); -	BOOL	decodeData(const U8 *buffer, const LLHost &host); - -	// TODO: Consolide these functions -	// TODO: Make these private, force use of typed functions. -	// If size is not 0, an error is generated if size doesn't exactly match the size of the data. -	// At all times, the number if bytes written to *datap is <= max_size. -private: -	void	getDataFast(const char *blockname, const char *varname, void *datap, S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX); -	void	getData(const char *blockname, const char *varname, void *datap, S32 size = 0, S32 blocknum = 0, S32 max_size = S32_MAX) -	{ -		getDataFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname), datap, size, blocknum, max_size); -	} -public: -	void	getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX) -	{ -		getDataFast(blockname, varname, datap, size, blocknum, max_size); -	} -	void	getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX) -	{ -		getDataFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname), datap, size, blocknum, max_size); -	} +	// BOOL	decodeData(const U8 *buffer, const LLHost &host); +	void	getBinaryDataFast(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX); +	void	getBinaryData(const char *blockname, const char *varname, void *datap, S32 size, S32 blocknum = 0, S32 max_size = S32_MAX);  	void	getBOOLFast(	const char *block, const char *var, BOOL &data, S32 blocknum = 0);  	void	getBOOL(	const char *block, const char *var, BOOL &data, S32 blocknum = 0);  	void	getS8Fast(		const char *block, const char *var, S8 &data, S32 blocknum = 0); @@ -507,9 +451,9 @@ public:  	void	getS32(		const char *block, const char *var, S32 &data, S32 blocknum = 0);  	void	getF32Fast(		const char *block, const char *var, F32 &data, S32 blocknum = 0);  	void	getF32(		const char *block, const char *var, F32 &data, S32 blocknum = 0); -	virtual void getU32Fast(		const char *block, const char *var, U32 &data, S32 blocknum = 0); +	void getU32Fast(		const char *block, const char *var, U32 &data, S32 blocknum = 0);  	void	getU32(		const char *block, const char *var, U32 &data, S32 blocknum = 0); -	virtual void getU64Fast(		const char *block, const char *var, U64 &data, S32 blocknum = 0); +	void getU64Fast(		const char *block, const char *var, U64 &data, S32 blocknum = 0);  	void	getU64(		const char *block, const char *var, U64 &data, S32 blocknum = 0);  	void	getF64Fast(		const char *block, const char *var, F64 &data, S32 blocknum = 0);  	void	getF64(		const char *block, const char *var, F64 &data, S32 blocknum = 0); @@ -521,13 +465,13 @@ public:  	void	getVector3d(const char *block, const char *var, LLVector3d &vec, S32 blocknum = 0);  	void	getQuatFast(	const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0);  	void	getQuat(	const char *block, const char *var, LLQuaternion &q, S32 blocknum = 0); -	virtual void getUUIDFast(	const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0); +	void getUUIDFast(	const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0);  	void	getUUID(	const char *block, const char *var, LLUUID &uuid, S32 blocknum = 0); -	virtual void getIPAddrFast(	const char *block, const char *var, U32 &ip, S32 blocknum = 0); +	void getIPAddrFast(	const char *block, const char *var, U32 &ip, S32 blocknum = 0);  	void	getIPAddr(	const char *block, const char *var, U32 &ip, S32 blocknum = 0); -	virtual void getIPPortFast(	const char *block, const char *var, U16 &port, S32 blocknum = 0); +	void getIPPortFast(	const char *block, const char *var, U16 &port, S32 blocknum = 0);  	void	getIPPort(	const char *block, const char *var, U16 &port, S32 blocknum = 0); -	virtual void getStringFast(	const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0); +	void getStringFast(	const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0);  	void	getString(	const char *block, const char *var, S32 buffer_size, char *buffer, S32 blocknum = 0); @@ -549,7 +493,7 @@ public:  	void	showCircuitInfo();  	LLString getCircuitInfoString(); -	virtual U32 getOurCircuitCode(); +	U32 getOurCircuitCode();  	void	enableCircuit(const LLHost &host, BOOL trusted);  	void	disableCircuit(const LLHost &host); @@ -595,20 +539,12 @@ public:  	void	sanityCheck();  	S32		getNumberOfBlocksFast(const char *blockname); -	S32		getNumberOfBlocks(const char *blockname) -	{ -		return getNumberOfBlocksFast(gMessageStringTable.getString(blockname)); -	} +	S32		getNumberOfBlocks(const char *blockname);  	S32		getSizeFast(const char *blockname, const char *varname); -	S32		getSize(const char *blockname, const char *varname) -	{ -		return getSizeFast(gMessageStringTable.getString(blockname), gMessageStringTable.getString(varname)); -	} -	S32		getSizeFast(const char *blockname, S32 blocknum, const char *varname);		// size in bytes of variable length data -	S32		getSize(const char *blockname, S32 blocknum, const char *varname) -	{ -		return getSizeFast(gMessageStringTable.getString(blockname), blocknum, gMessageStringTable.getString(varname)); -	} +	S32		getSize(const char *blockname, const char *varname); +	S32		getSizeFast(const char *blockname, S32 blocknum,  +						const char *varname); // size in bytes of data +	S32		getSize(const char *blockname, S32 blocknum, const char *varname);  	void	resetReceiveCounts();				// resets receive counts for all message types to 0  	void	dumpReceiveCounts();				// dumps receive count for each message type to llinfos @@ -623,14 +559,14 @@ public:  	void stopLogging();						// flush and close file  	void summarizeLogs(std::ostream& str);	// log statistics -	S32		getReceiveSize() const				{ return mReceiveSize; } -	S32		getReceiveCompressedSize() const	{ return mIncomingCompressedSize; } +	S32		getReceiveSize() const; +	S32		getReceiveCompressedSize() const { return mIncomingCompressedSize; }  	S32		getReceiveBytes() const;  	S32		getUnackedListSize() const			{ return mUnackedListSize; } -	const char* getCurrentSMessageName() const { return mCurrentSMessageName; } -	const char* getCurrentSBlockName() const { return mCurrentSBlockName; } +	//const char* getCurrentSMessageName() const { return mCurrentSMessageName; } +	//const char* getCurrentSBlockName() const { return mCurrentSBlockName; }  	// friends  	friend std::ostream&	operator<<(std::ostream& s, LLMessageSystem &msg); @@ -639,25 +575,41 @@ public:  	void setMaxMessageCounts(const S32 num);	// Max number of messages before dumping (neg to disable)  	// statics -public: +	static BOOL isTemplateConfirmed(); +	static BOOL doesTemplateMatch(); +	static void sendMessageTemplateChecksum(const LLHost&); +	static void processMessageTemplateChecksumReply(LLMessageSystem *msg, +													void** user_data); +	static void sendSecureMessageTemplateChecksum(const LLHost&); +	static void processSecureTemplateChecksumReply(LLMessageSystem *msg, +													void** user_data);  	static U64 getMessageTimeUsecs(const BOOL update = FALSE);	// Get the current message system time in microseconds  	static F64 getMessageTimeSeconds(const BOOL update = FALSE); // Get the current message system time in seconds -	static void setTimeDecodes( BOOL b )		 -		{ LLMessageSystem::mTimeDecodes = b; } - -	static void setTimeDecodesSpamThreshold( F32 seconds )  -		{ LLMessageSystem::mTimeDecodesSpamThreshold = seconds; } +	static void setTimeDecodes(BOOL b); +	static void setTimeDecodesSpamThreshold(F32 seconds);   	// message handlers internal to the message systesm  	//static void processAssignCircuitCode(LLMessageSystem* msg, void**);  	static void processAddCircuitCode(LLMessageSystem* msg, void**);  	static void processUseCircuitCode(LLMessageSystem* msg, void**); +	// dispatch llsd message to http node tree +	static void dispatch(const std::string& msg_name, +						 const LLSD& message); +	static void dispatch(const std::string& msg_name, +						 const LLSD& message, +						 LLHTTPNode::ResponsePtr responsep); +  	void setMessageBans(const LLSD& trusted, const LLSD& untrusted); + +	// Check UDP messages and pump http_pump to receive HTTP messages. +	bool checkAllMessages(S64 frame_count, LLPumpIO* http_pump);  private:  	// data used in those internal handlers +	BOOL mTemplateConfirmed; +	BOOL mTemplateMatches;  	// The mCircuitCodes is a map from circuit codes to session  	// ids. This allows us to verify sessions on connect. @@ -668,7 +620,6 @@ private:  	// that no one gives them a bad circuit code.  	LLUUID mSessionID; -private:  	void	addTemplate(LLMessageTemplate *templatep);  	void		clearReceiveState();  	BOOL		decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template ); @@ -678,7 +629,6 @@ private:  	void		logValidMsg(LLCircuitData *cdp, const LLHost& sender, BOOL recv_reliable, BOOL recv_resent, BOOL recv_acks );  	void		logRanOffEndOfPacket( const LLHost& sender ); -private:  	class LLMessageCountInfo  	{  	public: @@ -694,26 +644,10 @@ private:  	S32										mTrueReceiveSize;  	// Must be valid during decode -	S32										mReceiveSize; -	TPACKETID                               mCurrentRecvPacketID;       // packet ID of current receive packet (for reporting) -	LLMessageTemplate						*mCurrentRMessageTemplate; -	LLMsgData								*mCurrentRMessageData; -	S32									    mIncomingCompressedSize;		// original size of compressed msg (0 if uncomp.) -	LLHost									mLastSender; - -	// send message storage -	LLMsgData								*mCurrentSMessageData; -	LLMessageTemplate						*mCurrentSMessageTemplate; -	LLMsgBlkData							*mCurrentSDataBlock; -	char									*mCurrentSMessageName; -	char									*mCurrentSBlockName; - +	  	BOOL									mbError;  	S32 mErrorCode; -	BOOL									mbSBuilt;	// is send message built? -	BOOL									mbSClear;	// is the send message clear? -  	F64										mResendDumpTime; // The last time we dumped resends  	LLMessageCountInfo mMessageCountList[MAX_MESSAGE_COUNT_NUM]; @@ -740,6 +674,22 @@ private:  	void* mTimingCallbackData;  	void init(); // ctor shared initialisation. + +	LLHost mLastSender; +	S32 mIncomingCompressedSize;		// original size of compressed msg (0 if uncomp.) +	TPACKETID mCurrentRecvPacketID;       // packet ID of current receive packet (for reporting) + +	LLMessageBuilder* mMessageBuilder; +	LLTemplateMessageBuilder* mTemplateMessageBuilder; +	LLSDMessageBuilder* mLLSDMessageBuilder; +	LLMessageReader* mMessageReader; +	LLTemplateMessageReader* mTemplateMessageReader; +	LLSDMessageReader* mLLSDMessageReader; + +	friend class LLMessageHandlerBridge; +	 +	bool callHandler(const char *name, bool trustedSource, +					 LLMessageSystem* msg);  }; @@ -756,7 +706,8 @@ BOOL start_messaging_system(  	S32 version_minor,  	S32 version_patch,  	BOOL b_dump_prehash_file, -	const std::string& secret); +	const std::string& secret, +	const LLUseCircuitCodeResponder* responder = NULL);  void end_messaging_system(); @@ -932,12 +883,9 @@ inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n  } -inline const LLHost& LLMessageSystem::getSender() const -{ -	return mLastSender; -} +inline const LLHost& LLMessageSystem::getSender() const {return mLastSender;} -inline U32 LLMessageSystem::getSenderIP() const +inline U32 LLMessageSystem::getSenderIP() const   {  	return mLastSender.getAddress();  } @@ -947,291 +895,9 @@ inline U32 LLMessageSystem::getSenderPort() const  	return mLastSender.getPort();  } -inline void LLMessageSystem::addS8Fast(const char *varname, S8 s) -{ -	addDataFast(varname, &s, MVT_S8, sizeof(s)); -} - -inline void LLMessageSystem::addS8(const char *varname, S8 s) -{ -	addDataFast(gMessageStringTable.getString(varname), &s, MVT_S8, sizeof(s)); -} - -inline void LLMessageSystem::addU8Fast(const char *varname, U8 u) -{ -	addDataFast(varname, &u, MVT_U8, sizeof(u)); -} - -inline void LLMessageSystem::addU8(const char *varname, U8 u) -{ -	addDataFast(gMessageStringTable.getString(varname), &u, MVT_U8, sizeof(u)); -} - -inline void LLMessageSystem::addS16Fast(const char *varname, S16 i) -{ -	addDataFast(varname, &i, MVT_S16, sizeof(i)); -} - -inline void LLMessageSystem::addS16(const char *varname, S16 i) -{ -	addDataFast(gMessageStringTable.getString(varname), &i, MVT_S16, sizeof(i)); -} - -inline void LLMessageSystem::addU16Fast(const char *varname, U16 i) -{ -	addDataFast(varname, &i, MVT_U16, sizeof(i)); -} - -inline void LLMessageSystem::addU16(const char *varname, U16 i) -{ -	addDataFast(gMessageStringTable.getString(varname), &i, MVT_U16, sizeof(i)); -} - -inline void LLMessageSystem::addF32Fast(const char *varname, F32 f) -{ -	addDataFast(varname, &f, MVT_F32, sizeof(f)); -} - -inline void LLMessageSystem::addF32(const char *varname, F32 f) -{ -	addDataFast(gMessageStringTable.getString(varname), &f, MVT_F32, sizeof(f)); -} - -inline void LLMessageSystem::addS32Fast(const char *varname, S32 s) -{ -	addDataFast(varname, &s, MVT_S32, sizeof(s)); -} - -inline void LLMessageSystem::addS32(const char *varname, S32 s) -{ -	addDataFast(gMessageStringTable.getString(varname), &s, MVT_S32, sizeof(s)); -} - -inline void LLMessageSystem::addU32Fast(const char *varname, U32 u) -{ -	addDataFast(varname, &u, MVT_U32, sizeof(u)); -} - -inline void LLMessageSystem::addU32(const char *varname, U32 u) -{ -	addDataFast(gMessageStringTable.getString(varname), &u, MVT_U32, sizeof(u)); -} - -inline void LLMessageSystem::addU64Fast(const char *varname, U64 lu) -{ -	addDataFast(varname, &lu, MVT_U64, sizeof(lu)); -} - -inline void LLMessageSystem::addU64(const char *varname, U64 lu) -{ -	addDataFast(gMessageStringTable.getString(varname), &lu, MVT_U64, sizeof(lu)); -} - -inline void LLMessageSystem::addF64Fast(const char *varname, F64 d) -{ -	addDataFast(varname, &d, MVT_F64, sizeof(d)); -} - -inline void LLMessageSystem::addF64(const char *varname, F64 d) -{ -	addDataFast(gMessageStringTable.getString(varname), &d, MVT_F64, sizeof(d)); -} - -inline void LLMessageSystem::addIPAddrFast(const char *varname, U32 u) -{ -	addDataFast(varname, &u, MVT_IP_ADDR, sizeof(u)); -} - -inline void LLMessageSystem::addIPAddr(const char *varname, U32 u) -{ -	addDataFast(gMessageStringTable.getString(varname), &u, MVT_IP_ADDR, sizeof(u)); -} - -inline void LLMessageSystem::addIPPortFast(const char *varname, U16 u) -{ -	u = htons(u); -	addDataFast(varname, &u, MVT_IP_PORT, sizeof(u)); -} - -inline void LLMessageSystem::addIPPort(const char *varname, U16 u) -{ -	u = htons(u); -	addDataFast(gMessageStringTable.getString(varname), &u, MVT_IP_PORT, sizeof(u)); -} - -inline void LLMessageSystem::addBOOLFast(const char* varname, BOOL b) -{ -	// Can't just cast a BOOL (actually a U32) to a U8. -	// In some cases the low order bits will be zero. -	U8 temp = (b != 0); -	addDataFast(varname, &temp, MVT_BOOL, sizeof(temp)); -} - -inline void LLMessageSystem::addBOOL(const char* varname, BOOL b) -{ -	// Can't just cast a BOOL (actually a U32) to a U8. -	// In some cases the low order bits will be zero. -	U8 temp = (b != 0); -	addDataFast(gMessageStringTable.getString(varname), &temp, MVT_BOOL, sizeof(temp)); -} - -inline void LLMessageSystem::addStringFast(const char* varname, const char* s) -{ -	if (s) -		addDataFast( varname, (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1);  /* Flawfinder: ignore */   -	else -		addDataFast( varname, NULL, MVT_VARIABLE, 0);  -} - -inline void LLMessageSystem::addString(const char* varname, const char* s) -{ -	if (s) -		addDataFast( gMessageStringTable.getString(varname), (void *)s, MVT_VARIABLE, (S32)strlen(s) + 1);  /* Flawfinder: ignore */  -	else -		addDataFast( gMessageStringTable.getString(varname), NULL, MVT_VARIABLE, 0);  -} - -inline void LLMessageSystem::addStringFast(const char* varname, const std::string& s) -{ -	if (s.size()) -		addDataFast( varname, (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);  -	else -		addDataFast( varname, NULL, MVT_VARIABLE, 0);  -} - -inline void LLMessageSystem::addString(const char* varname, const std::string& s) -{ -	if (s.size()) -		addDataFast( gMessageStringTable.getString(varname), (void *)s.c_str(), MVT_VARIABLE, (S32)(s.size()) + 1);  -	else -		addDataFast( gMessageStringTable.getString(varname), NULL, MVT_VARIABLE, 0);  -} - -  //----------------------------------------------------------------------------- -// Retrieval aliases +// Transmission aliases  //----------------------------------------------------------------------------- -inline void LLMessageSystem::getS8Fast(const char *block, const char *var, S8 &u, S32 blocknum) -{ -	getDataFast(block, var, &u, sizeof(S8), blocknum); -} - -inline void LLMessageSystem::getS8(const char *block, const char *var, S8 &u, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(S8), blocknum); -} - -inline void LLMessageSystem::getU8Fast(const char *block, const char *var, U8 &u, S32 blocknum) -{ -	getDataFast(block, var, &u, sizeof(U8), blocknum); -} - -inline void LLMessageSystem::getU8(const char *block, const char *var, U8 &u, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U8), blocknum); -} - -inline void LLMessageSystem::getBOOLFast(const char *block, const char *var, BOOL &b, S32 blocknum ) -{ -	U8 value; -	getDataFast(block, var, &value, sizeof(U8), blocknum); -	b = (BOOL) value; -} - -inline void LLMessageSystem::getBOOL(const char *block, const char *var, BOOL &b, S32 blocknum ) -{ -	U8 value; -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &value, sizeof(U8), blocknum); -	b = (BOOL) value; -} - -inline void LLMessageSystem::getS16Fast(const char *block, const char *var, S16 &d, S32 blocknum) -{ -	getDataFast(block, var, &d, sizeof(S16), blocknum); -} - -inline void LLMessageSystem::getS16(const char *block, const char *var, S16 &d, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(S16), blocknum); -} - -inline void LLMessageSystem::getU16Fast(const char *block, const char *var, U16 &d, S32 blocknum) -{ -	getDataFast(block, var, &d, sizeof(U16), blocknum); -} - -inline void LLMessageSystem::getU16(const char *block, const char *var, U16 &d, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U16), blocknum); -} - -inline void LLMessageSystem::getS32Fast(const char *block, const char *var, S32 &d, S32 blocknum) -{ -	getDataFast(block, var, &d, sizeof(S32), blocknum); -} - -inline void LLMessageSystem::getS32(const char *block, const char *var, S32 &d, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(S32), blocknum); -} - -inline void LLMessageSystem::getU32Fast(const char *block, const char *var, U32 &d, S32 blocknum) -{ -	getDataFast(block, var, &d, sizeof(U32), blocknum); -} - -inline void LLMessageSystem::getU32(const char *block, const char *var, U32 &d, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U32), blocknum); -} - -inline void LLMessageSystem::getU64Fast(const char *block, const char *var, U64 &d, S32 blocknum) -{ -	getDataFast(block, var, &d, sizeof(U64), blocknum); -} - -inline void LLMessageSystem::getU64(const char *block, const char *var, U64 &d, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &d, sizeof(U64), blocknum); -} - - -inline void LLMessageSystem::getIPAddrFast(const char *block, const char *var, U32 &u, S32 blocknum) -{ -	getDataFast(block, var, &u, sizeof(U32), blocknum); -} - -inline void LLMessageSystem::getIPAddr(const char *block, const char *var, U32 &u, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U32), blocknum); -} - -inline void LLMessageSystem::getIPPortFast(const char *block, const char *var, U16 &u, S32 blocknum) -{ -	getDataFast(block, var, &u, sizeof(U16), blocknum); -	u = ntohs(u); -} - -inline void LLMessageSystem::getIPPort(const char *block, const char *var, U16 &u, S32 blocknum) -{ -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), &u, sizeof(U16), blocknum); -	u = ntohs(u); -} - - -inline void LLMessageSystem::getStringFast(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum ) -{ -	s[0] = '\0'; -	getDataFast(block, var, s, 0, blocknum, buffer_size); -	s[buffer_size - 1] = '\0'; -} - -inline void LLMessageSystem::getString(const char *block, const char *var, S32 buffer_size, char *s, S32 blocknum ) -{ -	s[0] = '\0'; -	getDataFast(gMessageStringTable.getString(block), gMessageStringTable.getString(var), s, 0, blocknum, buffer_size); -	s[buffer_size - 1] = '\0'; -}  inline S32 LLMessageSystem::sendMessage(const U32 circuit)  { diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index c2d7c9c2a3..9d7e603690 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -20,7 +20,6 @@ char * _PREHASH_X;  char * _PREHASH_Y;  char * _PREHASH_Z;  char * _PREHASH_AddFlags; -char * _PREHASH_ReservedNewbie;  char * _PREHASH_FailureInfo;  char * _PREHASH_MapData;  char * _PREHASH_AddItem; @@ -89,7 +88,6 @@ char * _PREHASH_RelatedRights;  char * _PREHASH_RedirectGridX;  char * _PREHASH_RedirectGridY;  char * _PREHASH_TransferID; -char * _PREHASH_Transacted;  char * _PREHASH_TexturesChanged;  char * _PREHASH_UserLookAt;  char * _PREHASH_TestBlock1; @@ -116,7 +114,6 @@ char * _PREHASH_SetSimStatusInDatabase;  char * _PREHASH_SetSimPresenceInDatabase;  char * _PREHASH_CameraProperty;  char * _PREHASH_BrushSize; -char * _PREHASH_StartExpungeProcess;  char * _PREHASH_SimulatorSetMap;  char * _PREHASH_RegionPresenceRequestByRegionID;  char * _PREHASH_ParcelObjectOwnersReply; @@ -210,8 +207,8 @@ char * _PREHASH_SimName;  char * _PREHASH_UserReport;  char * _PREHASH_DownloadPriority;  char * _PREHASH_ToAgentId; -char * _PREHASH_Mag;  char * _PREHASH_DirPopularQuery; +char * _PREHASH_Mag;  char * _PREHASH_ParcelPropertiesRequestByID;  char * _PREHASH_ObjectLink;  char * _PREHASH_RpcScriptReplyInbound; @@ -420,7 +417,6 @@ char * _PREHASH_TerminateFriendship;  char * _PREHASH_TaskData;  char * _PREHASH_SimWideMaxPrims;  char * _PREHASH_TotalPrims; -char * _PREHASH_SourceFilename;  char * _PREHASH_ProfileBegin;  char * _PREHASH_MoneyDetailsRequest;  char * _PREHASH_Request; @@ -467,7 +463,6 @@ char * _PREHASH_ParamInUse;  char * _PREHASH_GodKickUser;  char * _PREHASH_PickName;  char * _PREHASH_TaskName; -char * _PREHASH_ParcelGodReserveForNewbie;  char * _PREHASH_SubType;  char * _PREHASH_ObjectCount;  char * _PREHASH_RegionPresenceRequestByHandle; @@ -486,10 +481,13 @@ char * _PREHASH_UpdateParcel;  char * _PREHASH_ClearAgentSessions;  char * _PREHASH_SetAlwaysRun;  char * _PREHASH_NVPair; +char * _PREHASH_SearchType;  char * _PREHASH_ObjectSpinStart;  char * _PREHASH_UseEstateSun;  char * _PREHASH_LogoutBlock; +char * _PREHASH_RelayLogControl;  char * _PREHASH_RegionID; +char * _PREHASH_AbuseRegionID;  char * _PREHASH_Creator;  char * _PREHASH_ProposalText;  char * _PREHASH_DirEventsReply; @@ -534,7 +532,6 @@ char * _PREHASH_MaxY;  char * _PREHASH_TextureAnim;  char * _PREHASH_ReturnIDs;  char * _PREHASH_Date; -char * _PREHASH_GestureUpdate;  char * _PREHASH_AgentWearablesUpdate;  char * _PREHASH_AgentDataUpdate;  char * _PREHASH_Hash; @@ -556,7 +553,6 @@ char * _PREHASH_HistoryItemData;  char * _PREHASH_AgentCachedTexture;  char * _PREHASH_Subject;  char * _PREHASH_East; -char * _PREHASH_GodExpungeUser;  char * _PREHASH_QueryReplies;  char * _PREHASH_ObjectCategory;  char * _PREHASH_Time; @@ -783,6 +779,7 @@ char * _PREHASH_UnsubscribeLoad;  char * _PREHASH_Packet;  char * _PREHASH_UndoLand;  char * _PREHASH_SimAccess; +char * _PREHASH_AbuserID;  char * _PREHASH_MembershipFee;  char * _PREHASH_InviteGroupResponse;  char * _PREHASH_CreateInventoryFolder; @@ -920,6 +917,7 @@ char * _PREHASH_ImageNotInDatabase;  char * _PREHASH_StartDate;  char * _PREHASH_AnimID;  char * _PREHASH_Serial; +char * _PREHASH_AbuseRegionName;  char * _PREHASH_ControlPort;  char * _PREHASH_ModifyLand;  char * _PREHASH_Digest; @@ -984,11 +982,11 @@ char * _PREHASH_EventFlags;  char * _PREHASH_TallyVotes;  char * _PREHASH_Result;  char * _PREHASH_LookAt; +char * _PREHASH_SearchOrder;  char * _PREHASH_PayButton;  char * _PREHASH_SelfCount;  char * _PREHASH_PacketCount;  char * _PREHASH_ParcelBuyPass; -char * _PREHASH_Identified;  char * _PREHASH_OldItemID;  char * _PREHASH_RegionPort;  char * _PREHASH_PriceEnergyUnit; @@ -1024,7 +1022,6 @@ char * _PREHASH_EconomyDataRequest;  char * _PREHASH_TeleportLureRequest;  char * _PREHASH_FolderID;  char * _PREHASH_RegionHandleRequest; -char * _PREHASH_GestureRequest;  char * _PREHASH_ScriptDataRequest;  char * _PREHASH_GroupRoleDataRequest;  char * _PREHASH_GroupTitlesRequest; @@ -1168,11 +1165,9 @@ char * _PREHASH_Ratio;  char * _PREHASH_JoinGroupReply;  char * _PREHASH_LiveHelpGroupReply;  char * _PREHASH_Score; -char * _PREHASH_ExpungeData;  char * _PREHASH_Image;  char * _PREHASH_ObjectClickAction;  char * _PREHASH_Delta; -char * _PREHASH_InitiateUpload;  char * _PREHASH_Parameter;  char * _PREHASH_Flags;  char * _PREHASH_Plane; @@ -1208,7 +1203,6 @@ char * _PREHASH_Disconnect;  char * _PREHASH_SimPosition;  char * _PREHASH_SimWideTotalPrims;  char * _PREHASH_Index; -char * _PREHASH_BaseFilename;  char * _PREHASH_SimFilename;  char * _PREHASH_LastOwnerID;  char * _PREHASH_GroupNoticeRequest; @@ -1293,6 +1287,7 @@ char * _PREHASH_AssetBlock;  char * _PREHASH_AcceptNotices;  char * _PREHASH_SetGroupAcceptNotices;  char * _PREHASH_CloseCircuit; +char * _PREHASH_LogControl;  char * _PREHASH_TeleportFinish;  char * _PREHASH_PathRevolutions;  char * _PREHASH_ClassifiedInfoReply; @@ -1472,7 +1467,6 @@ char * _PREHASH_DirLandReply;  char * _PREHASH_SpaceLocationTeleportReply;  char * _PREHASH_MuteType;  char * _PREHASH_IMViaEMail; -char * _PREHASH_StartExpungeProcessAck;  char * _PREHASH_RentPrice;  char * _PREHASH_GenericMessage;  char * _PREHASH_ChildAgentAlive; @@ -1492,7 +1486,6 @@ void init_prehash_data()  	_PREHASH_Y = gMessageStringTable.getString("Y");  	_PREHASH_Z = gMessageStringTable.getString("Z");  	_PREHASH_AddFlags = gMessageStringTable.getString("AddFlags"); -	_PREHASH_ReservedNewbie = gMessageStringTable.getString("ReservedNewbie");  	_PREHASH_FailureInfo = gMessageStringTable.getString("FailureInfo");  	_PREHASH_MapData = gMessageStringTable.getString("MapData");  	_PREHASH_AddItem = gMessageStringTable.getString("AddItem"); @@ -1561,7 +1554,6 @@ void init_prehash_data()  	_PREHASH_RedirectGridX = gMessageStringTable.getString("RedirectGridX");  	_PREHASH_RedirectGridY = gMessageStringTable.getString("RedirectGridY");  	_PREHASH_TransferID = gMessageStringTable.getString("TransferID"); -	_PREHASH_Transacted = gMessageStringTable.getString("Transacted");  	_PREHASH_TexturesChanged = gMessageStringTable.getString("TexturesChanged");  	_PREHASH_UserLookAt = gMessageStringTable.getString("UserLookAt");  	_PREHASH_TestBlock1 = gMessageStringTable.getString("TestBlock1"); @@ -1588,7 +1580,6 @@ void init_prehash_data()  	_PREHASH_SetSimPresenceInDatabase = gMessageStringTable.getString("SetSimPresenceInDatabase");  	_PREHASH_CameraProperty = gMessageStringTable.getString("CameraProperty");  	_PREHASH_BrushSize = gMessageStringTable.getString("BrushSize"); -	_PREHASH_StartExpungeProcess = gMessageStringTable.getString("StartExpungeProcess");  	_PREHASH_SimulatorSetMap = gMessageStringTable.getString("SimulatorSetMap");  	_PREHASH_RegionPresenceRequestByRegionID = gMessageStringTable.getString("RegionPresenceRequestByRegionID");  	_PREHASH_ParcelObjectOwnersReply = gMessageStringTable.getString("ParcelObjectOwnersReply"); @@ -1682,8 +1673,8 @@ void init_prehash_data()  	_PREHASH_UserReport = gMessageStringTable.getString("UserReport");  	_PREHASH_DownloadPriority = gMessageStringTable.getString("DownloadPriority");  	_PREHASH_ToAgentId = gMessageStringTable.getString("ToAgentId"); -	_PREHASH_Mag = gMessageStringTable.getString("Mag");  	_PREHASH_DirPopularQuery = gMessageStringTable.getString("DirPopularQuery"); +	_PREHASH_Mag = gMessageStringTable.getString("Mag");  	_PREHASH_ParcelPropertiesRequestByID = gMessageStringTable.getString("ParcelPropertiesRequestByID");  	_PREHASH_ObjectLink = gMessageStringTable.getString("ObjectLink");  	_PREHASH_RpcScriptReplyInbound = gMessageStringTable.getString("RpcScriptReplyInbound"); @@ -1892,7 +1883,6 @@ void init_prehash_data()  	_PREHASH_TaskData = gMessageStringTable.getString("TaskData");  	_PREHASH_SimWideMaxPrims = gMessageStringTable.getString("SimWideMaxPrims");  	_PREHASH_TotalPrims = gMessageStringTable.getString("TotalPrims"); -	_PREHASH_SourceFilename = gMessageStringTable.getString("SourceFilename");  	_PREHASH_ProfileBegin = gMessageStringTable.getString("ProfileBegin");  	_PREHASH_MoneyDetailsRequest = gMessageStringTable.getString("MoneyDetailsRequest");  	_PREHASH_Request = gMessageStringTable.getString("Request"); @@ -1939,7 +1929,6 @@ void init_prehash_data()  	_PREHASH_GodKickUser = gMessageStringTable.getString("GodKickUser");  	_PREHASH_PickName = gMessageStringTable.getString("PickName");  	_PREHASH_TaskName = gMessageStringTable.getString("TaskName"); -	_PREHASH_ParcelGodReserveForNewbie = gMessageStringTable.getString("ParcelGodReserveForNewbie");  	_PREHASH_SubType = gMessageStringTable.getString("SubType");  	_PREHASH_ObjectCount = gMessageStringTable.getString("ObjectCount");  	_PREHASH_RegionPresenceRequestByHandle = gMessageStringTable.getString("RegionPresenceRequestByHandle"); @@ -1958,10 +1947,13 @@ void init_prehash_data()  	_PREHASH_ClearAgentSessions = gMessageStringTable.getString("ClearAgentSessions");  	_PREHASH_SetAlwaysRun = gMessageStringTable.getString("SetAlwaysRun");  	_PREHASH_NVPair = gMessageStringTable.getString("NVPair"); +	_PREHASH_SearchType = gMessageStringTable.getString("SearchType");  	_PREHASH_ObjectSpinStart = gMessageStringTable.getString("ObjectSpinStart");  	_PREHASH_UseEstateSun = gMessageStringTable.getString("UseEstateSun");  	_PREHASH_LogoutBlock = gMessageStringTable.getString("LogoutBlock"); +	_PREHASH_RelayLogControl = gMessageStringTable.getString("RelayLogControl");  	_PREHASH_RegionID = gMessageStringTable.getString("RegionID"); +	_PREHASH_AbuseRegionID = gMessageStringTable.getString("AbuseRegionID");  	_PREHASH_Creator = gMessageStringTable.getString("Creator");  	_PREHASH_ProposalText = gMessageStringTable.getString("ProposalText");  	_PREHASH_DirEventsReply = gMessageStringTable.getString("DirEventsReply"); @@ -2006,7 +1998,6 @@ void init_prehash_data()  	_PREHASH_TextureAnim = gMessageStringTable.getString("TextureAnim");  	_PREHASH_ReturnIDs = gMessageStringTable.getString("ReturnIDs");  	_PREHASH_Date = gMessageStringTable.getString("Date"); -	_PREHASH_GestureUpdate = gMessageStringTable.getString("GestureUpdate");  	_PREHASH_AgentWearablesUpdate = gMessageStringTable.getString("AgentWearablesUpdate");  	_PREHASH_AgentDataUpdate = gMessageStringTable.getString("AgentDataUpdate");  	_PREHASH_Hash = gMessageStringTable.getString("Hash"); @@ -2028,7 +2019,6 @@ void init_prehash_data()  	_PREHASH_AgentCachedTexture = gMessageStringTable.getString("AgentCachedTexture");  	_PREHASH_Subject = gMessageStringTable.getString("Subject");  	_PREHASH_East = gMessageStringTable.getString("East"); -	_PREHASH_GodExpungeUser = gMessageStringTable.getString("GodExpungeUser");  	_PREHASH_QueryReplies = gMessageStringTable.getString("QueryReplies");  	_PREHASH_ObjectCategory = gMessageStringTable.getString("ObjectCategory");  	_PREHASH_Time = gMessageStringTable.getString("Time"); @@ -2255,6 +2245,7 @@ void init_prehash_data()  	_PREHASH_Packet = gMessageStringTable.getString("Packet");  	_PREHASH_UndoLand = gMessageStringTable.getString("UndoLand");  	_PREHASH_SimAccess = gMessageStringTable.getString("SimAccess"); +	_PREHASH_AbuserID = gMessageStringTable.getString("AbuserID");  	_PREHASH_MembershipFee = gMessageStringTable.getString("MembershipFee");  	_PREHASH_InviteGroupResponse = gMessageStringTable.getString("InviteGroupResponse");  	_PREHASH_CreateInventoryFolder = gMessageStringTable.getString("CreateInventoryFolder"); @@ -2392,6 +2383,7 @@ void init_prehash_data()  	_PREHASH_StartDate = gMessageStringTable.getString("StartDate");  	_PREHASH_AnimID = gMessageStringTable.getString("AnimID");  	_PREHASH_Serial = gMessageStringTable.getString("Serial"); +	_PREHASH_AbuseRegionName = gMessageStringTable.getString("AbuseRegionName");  	_PREHASH_ControlPort = gMessageStringTable.getString("ControlPort");  	_PREHASH_ModifyLand = gMessageStringTable.getString("ModifyLand");  	_PREHASH_Digest = gMessageStringTable.getString("Digest"); @@ -2456,11 +2448,11 @@ void init_prehash_data()  	_PREHASH_TallyVotes = gMessageStringTable.getString("TallyVotes");  	_PREHASH_Result = gMessageStringTable.getString("Result");  	_PREHASH_LookAt = gMessageStringTable.getString("LookAt"); +	_PREHASH_SearchOrder = gMessageStringTable.getString("SearchOrder");  	_PREHASH_PayButton = gMessageStringTable.getString("PayButton");  	_PREHASH_SelfCount = gMessageStringTable.getString("SelfCount");  	_PREHASH_PacketCount = gMessageStringTable.getString("PacketCount");  	_PREHASH_ParcelBuyPass = gMessageStringTable.getString("ParcelBuyPass"); -	_PREHASH_Identified = gMessageStringTable.getString("Identified");  	_PREHASH_OldItemID = gMessageStringTable.getString("OldItemID");  	_PREHASH_RegionPort = gMessageStringTable.getString("RegionPort");  	_PREHASH_PriceEnergyUnit = gMessageStringTable.getString("PriceEnergyUnit"); @@ -2496,7 +2488,6 @@ void init_prehash_data()  	_PREHASH_TeleportLureRequest = gMessageStringTable.getString("TeleportLureRequest");  	_PREHASH_FolderID = gMessageStringTable.getString("FolderID");  	_PREHASH_RegionHandleRequest = gMessageStringTable.getString("RegionHandleRequest"); -	_PREHASH_GestureRequest = gMessageStringTable.getString("GestureRequest");  	_PREHASH_ScriptDataRequest = gMessageStringTable.getString("ScriptDataRequest");  	_PREHASH_GroupRoleDataRequest = gMessageStringTable.getString("GroupRoleDataRequest");  	_PREHASH_GroupTitlesRequest = gMessageStringTable.getString("GroupTitlesRequest"); @@ -2640,11 +2631,9 @@ void init_prehash_data()  	_PREHASH_JoinGroupReply = gMessageStringTable.getString("JoinGroupReply");  	_PREHASH_LiveHelpGroupReply = gMessageStringTable.getString("LiveHelpGroupReply");  	_PREHASH_Score = gMessageStringTable.getString("Score"); -	_PREHASH_ExpungeData = gMessageStringTable.getString("ExpungeData");  	_PREHASH_Image = gMessageStringTable.getString("Image");  	_PREHASH_ObjectClickAction = gMessageStringTable.getString("ObjectClickAction");  	_PREHASH_Delta = gMessageStringTable.getString("Delta"); -	_PREHASH_InitiateUpload = gMessageStringTable.getString("InitiateUpload");  	_PREHASH_Parameter = gMessageStringTable.getString("Parameter");  	_PREHASH_Flags = gMessageStringTable.getString("Flags");  	_PREHASH_Plane = gMessageStringTable.getString("Plane"); @@ -2680,7 +2669,6 @@ void init_prehash_data()  	_PREHASH_SimPosition = gMessageStringTable.getString("SimPosition");  	_PREHASH_SimWideTotalPrims = gMessageStringTable.getString("SimWideTotalPrims");  	_PREHASH_Index = gMessageStringTable.getString("Index"); -	_PREHASH_BaseFilename = gMessageStringTable.getString("BaseFilename");  	_PREHASH_SimFilename = gMessageStringTable.getString("SimFilename");  	_PREHASH_LastOwnerID = gMessageStringTable.getString("LastOwnerID");  	_PREHASH_GroupNoticeRequest = gMessageStringTable.getString("GroupNoticeRequest"); @@ -2765,6 +2753,7 @@ void init_prehash_data()  	_PREHASH_AcceptNotices = gMessageStringTable.getString("AcceptNotices");  	_PREHASH_SetGroupAcceptNotices = gMessageStringTable.getString("SetGroupAcceptNotices");  	_PREHASH_CloseCircuit = gMessageStringTable.getString("CloseCircuit"); +	_PREHASH_LogControl = gMessageStringTable.getString("LogControl");  	_PREHASH_TeleportFinish = gMessageStringTable.getString("TeleportFinish");  	_PREHASH_PathRevolutions = gMessageStringTable.getString("PathRevolutions");  	_PREHASH_ClassifiedInfoReply = gMessageStringTable.getString("ClassifiedInfoReply"); @@ -2944,7 +2933,6 @@ void init_prehash_data()  	_PREHASH_SpaceLocationTeleportReply = gMessageStringTable.getString("SpaceLocationTeleportReply");  	_PREHASH_MuteType = gMessageStringTable.getString("MuteType");  	_PREHASH_IMViaEMail = gMessageStringTable.getString("IMViaEMail"); -	_PREHASH_StartExpungeProcessAck = gMessageStringTable.getString("StartExpungeProcessAck");  	_PREHASH_RentPrice = gMessageStringTable.getString("RentPrice");  	_PREHASH_GenericMessage = gMessageStringTable.getString("GenericMessage");  	_PREHASH_ChildAgentAlive = gMessageStringTable.getString("ChildAgentAlive"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 63e23237f5..19b9881dde 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -20,7 +20,6 @@ extern char * _PREHASH_X;  extern char * _PREHASH_Y;  extern char * _PREHASH_Z;  extern char * _PREHASH_AddFlags; -extern char * _PREHASH_ReservedNewbie;  extern char * _PREHASH_FailureInfo;  extern char * _PREHASH_MapData;  extern char * _PREHASH_AddItem; @@ -89,7 +88,6 @@ extern char * _PREHASH_RelatedRights;  extern char * _PREHASH_RedirectGridX;  extern char * _PREHASH_RedirectGridY;  extern char * _PREHASH_TransferID; -extern char * _PREHASH_Transacted;  extern char * _PREHASH_TexturesChanged;  extern char * _PREHASH_UserLookAt;  extern char * _PREHASH_TestBlock1; @@ -116,7 +114,6 @@ extern char * _PREHASH_SetSimStatusInDatabase;  extern char * _PREHASH_SetSimPresenceInDatabase;  extern char * _PREHASH_CameraProperty;  extern char * _PREHASH_BrushSize; -extern char * _PREHASH_StartExpungeProcess;  extern char * _PREHASH_SimulatorSetMap;  extern char * _PREHASH_RegionPresenceRequestByRegionID;  extern char * _PREHASH_ParcelObjectOwnersReply; @@ -210,8 +207,8 @@ extern char * _PREHASH_SimName;  extern char * _PREHASH_UserReport;  extern char * _PREHASH_DownloadPriority;  extern char * _PREHASH_ToAgentId; -extern char * _PREHASH_Mag;  extern char * _PREHASH_DirPopularQuery; +extern char * _PREHASH_Mag;  extern char * _PREHASH_ParcelPropertiesRequestByID;  extern char * _PREHASH_ObjectLink;  extern char * _PREHASH_RpcScriptReplyInbound; @@ -420,7 +417,6 @@ extern char * _PREHASH_TerminateFriendship;  extern char * _PREHASH_TaskData;  extern char * _PREHASH_SimWideMaxPrims;  extern char * _PREHASH_TotalPrims; -extern char * _PREHASH_SourceFilename;  extern char * _PREHASH_ProfileBegin;  extern char * _PREHASH_MoneyDetailsRequest;  extern char * _PREHASH_Request; @@ -467,7 +463,6 @@ extern char * _PREHASH_ParamInUse;  extern char * _PREHASH_GodKickUser;  extern char * _PREHASH_PickName;  extern char * _PREHASH_TaskName; -extern char * _PREHASH_ParcelGodReserveForNewbie;  extern char * _PREHASH_SubType;  extern char * _PREHASH_ObjectCount;  extern char * _PREHASH_RegionPresenceRequestByHandle; @@ -486,10 +481,13 @@ extern char * _PREHASH_UpdateParcel;  extern char * _PREHASH_ClearAgentSessions;  extern char * _PREHASH_SetAlwaysRun;  extern char * _PREHASH_NVPair; +extern char * _PREHASH_SearchType;  extern char * _PREHASH_ObjectSpinStart;  extern char * _PREHASH_UseEstateSun;  extern char * _PREHASH_LogoutBlock; +extern char * _PREHASH_RelayLogControl;  extern char * _PREHASH_RegionID; +extern char * _PREHASH_AbuseRegionID;  extern char * _PREHASH_Creator;  extern char * _PREHASH_ProposalText;  extern char * _PREHASH_DirEventsReply; @@ -534,7 +532,6 @@ extern char * _PREHASH_MaxY;  extern char * _PREHASH_TextureAnim;  extern char * _PREHASH_ReturnIDs;  extern char * _PREHASH_Date; -extern char * _PREHASH_GestureUpdate;  extern char * _PREHASH_AgentWearablesUpdate;  extern char * _PREHASH_AgentDataUpdate;  extern char * _PREHASH_Hash; @@ -556,7 +553,6 @@ extern char * _PREHASH_HistoryItemData;  extern char * _PREHASH_AgentCachedTexture;  extern char * _PREHASH_Subject;  extern char * _PREHASH_East; -extern char * _PREHASH_GodExpungeUser;  extern char * _PREHASH_QueryReplies;  extern char * _PREHASH_ObjectCategory;  extern char * _PREHASH_Time; @@ -783,6 +779,7 @@ extern char * _PREHASH_UnsubscribeLoad;  extern char * _PREHASH_Packet;  extern char * _PREHASH_UndoLand;  extern char * _PREHASH_SimAccess; +extern char * _PREHASH_AbuserID;  extern char * _PREHASH_MembershipFee;  extern char * _PREHASH_InviteGroupResponse;  extern char * _PREHASH_CreateInventoryFolder; @@ -920,6 +917,7 @@ extern char * _PREHASH_ImageNotInDatabase;  extern char * _PREHASH_StartDate;  extern char * _PREHASH_AnimID;  extern char * _PREHASH_Serial; +extern char * _PREHASH_AbuseRegionName;  extern char * _PREHASH_ControlPort;  extern char * _PREHASH_ModifyLand;  extern char * _PREHASH_Digest; @@ -984,11 +982,11 @@ extern char * _PREHASH_EventFlags;  extern char * _PREHASH_TallyVotes;  extern char * _PREHASH_Result;  extern char * _PREHASH_LookAt; +extern char * _PREHASH_SearchOrder;  extern char * _PREHASH_PayButton;  extern char * _PREHASH_SelfCount;  extern char * _PREHASH_PacketCount;  extern char * _PREHASH_ParcelBuyPass; -extern char * _PREHASH_Identified;  extern char * _PREHASH_OldItemID;  extern char * _PREHASH_RegionPort;  extern char * _PREHASH_PriceEnergyUnit; @@ -1024,7 +1022,6 @@ extern char * _PREHASH_EconomyDataRequest;  extern char * _PREHASH_TeleportLureRequest;  extern char * _PREHASH_FolderID;  extern char * _PREHASH_RegionHandleRequest; -extern char * _PREHASH_GestureRequest;  extern char * _PREHASH_ScriptDataRequest;  extern char * _PREHASH_GroupRoleDataRequest;  extern char * _PREHASH_GroupTitlesRequest; @@ -1168,11 +1165,9 @@ extern char * _PREHASH_Ratio;  extern char * _PREHASH_JoinGroupReply;  extern char * _PREHASH_LiveHelpGroupReply;  extern char * _PREHASH_Score; -extern char * _PREHASH_ExpungeData;  extern char * _PREHASH_Image;  extern char * _PREHASH_ObjectClickAction;  extern char * _PREHASH_Delta; -extern char * _PREHASH_InitiateUpload;  extern char * _PREHASH_Parameter;  extern char * _PREHASH_Flags;  extern char * _PREHASH_Plane; @@ -1208,7 +1203,6 @@ extern char * _PREHASH_Disconnect;  extern char * _PREHASH_SimPosition;  extern char * _PREHASH_SimWideTotalPrims;  extern char * _PREHASH_Index; -extern char * _PREHASH_BaseFilename;  extern char * _PREHASH_SimFilename;  extern char * _PREHASH_LastOwnerID;  extern char * _PREHASH_GroupNoticeRequest; @@ -1293,6 +1287,7 @@ extern char * _PREHASH_AssetBlock;  extern char * _PREHASH_AcceptNotices;  extern char * _PREHASH_SetGroupAcceptNotices;  extern char * _PREHASH_CloseCircuit; +extern char * _PREHASH_LogControl;  extern char * _PREHASH_TeleportFinish;  extern char * _PREHASH_PathRevolutions;  extern char * _PREHASH_ClassifiedInfoReply; @@ -1472,7 +1467,6 @@ extern char * _PREHASH_DirLandReply;  extern char * _PREHASH_SpaceLocationTeleportReply;  extern char * _PREHASH_MuteType;  extern char * _PREHASH_IMViaEMail; -extern char * _PREHASH_StartExpungeProcessAck;  extern char * _PREHASH_RentPrice;  extern char * _PREHASH_GenericMessage;  extern char * _PREHASH_ChildAgentAlive; diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index a78b216ccb..9e83ce1434 100644 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -222,6 +222,12 @@ S32 start_net(S32& socket_out, int& nPort)  			return 4;  		}  	} + +	sockaddr_in socket_address; +	S32 socket_address_size = sizeof(socket_address); +	getsockname(hSocket, (SOCKADDR*) &socket_address, &socket_address_size); +	attempt_port = ntohs(socket_address.sin_port); +  	llinfos << "connected on port " << attempt_port << llendl;  	nPort = attempt_port; | 
