summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
authorDon Kjer <don@lindenlab.com>2007-05-01 21:39:25 +0000
committerDon Kjer <don@lindenlab.com>2007-05-01 21:39:25 +0000
commit4ecb9cb63e4993b3b4bc65d73ed255139b5c3f75 (patch)
tree48d9bb9a1ae468ecdbd53cf21a598d66ee8eced3 /indra/llmessage
parentf5e9ce7e47694e349a4eb28b052016b11e1bdf81 (diff)
svn merge -r 59163:61099 svn+ssh://svn/svn/linden/branches/release-candidate into release
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/llblowfishcipher.cpp48
-rw-r--r--indra/llmessage/llcachename.cpp95
-rw-r--r--indra/llmessage/llcachename.h3
-rw-r--r--indra/llmessage/llhost.cpp2
-rw-r--r--indra/llmessage/llhttpclient.cpp30
-rw-r--r--indra/llmessage/llhttpsender.cpp70
-rw-r--r--indra/llmessage/llhttpsender.h38
-rw-r--r--indra/llmessage/llinstantmessage.cpp30
-rw-r--r--indra/llmessage/llinstantmessage.h17
-rw-r--r--indra/llmessage/lliohttpserver.cpp26
-rw-r--r--indra/llmessage/lliohttpserver.h3
-rw-r--r--indra/llmessage/lliopipe.h2
-rw-r--r--indra/llmessage/lliosocket.cpp13
-rw-r--r--indra/llmessage/llmessagebuilder.cpp18
-rw-r--r--indra/llmessage/llmessagebuilder.h70
-rw-r--r--indra/llmessage/llmessageconfig.cpp210
-rw-r--r--indra/llmessage/llmessageconfig.h31
-rw-r--r--indra/llmessage/llmessagereader.cpp35
-rw-r--r--indra/llmessage/llmessagereader.h59
-rw-r--r--indra/llmessage/llmessagetemplate.cpp146
-rw-r--r--indra/llmessage/llmessagetemplate.h356
-rw-r--r--indra/llmessage/llmsgvariabletype.h33
-rw-r--r--indra/llmessage/llpacketack.h18
-rw-r--r--indra/llmessage/llpumpio.cpp8
-rw-r--r--indra/llmessage/llpumpio.h1
-rwxr-xr-xindra/llmessage/llsdmessagebuilder.cpp281
-rwxr-xr-xindra/llmessage/llsdmessagebuilder.h98
-rwxr-xr-xindra/llmessage/llsdmessagereader.cpp264
-rwxr-xr-xindra/llmessage/llsdmessagereader.h79
-rw-r--r--indra/llmessage/llservice.h2
-rw-r--r--indra/llmessage/llservicebuilder.cpp115
-rw-r--r--indra/llmessage/llservicebuilder.h73
-rw-r--r--indra/llmessage/lltemplatemessagebuilder.cpp856
-rw-r--r--indra/llmessage/lltemplatemessagebuilder.h88
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp750
-rw-r--r--indra/llmessage/lltemplatemessagereader.h98
-rw-r--r--indra/llmessage/message.cpp3046
-rw-r--r--indra/llmessage/message.h538
-rw-r--r--indra/llmessage/message_prehash.cpp44
-rw-r--r--indra/llmessage/message_prehash.h22
-rw-r--r--indra/llmessage/net.cpp6
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 &currentHost)
+{
+ 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;