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