diff options
Diffstat (limited to 'indra/llmessage')
34 files changed, 1953 insertions, 278 deletions
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index fd22de9399..4fb0187412 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -7,6 +7,7 @@ include(LLCommon)  include(LLMath)  include(LLMessage)  include(LLVFS) +include(LLAddBuildTest)  include_directories (${CMAKE_CURRENT_SOURCE_DIR}) @@ -34,6 +35,7 @@ set(llmessage_SOURCE_FILES      llhost.cpp      llhttpassetstorage.cpp      llhttpclient.cpp +    llhttpclientadapter.cpp      llhttpnode.cpp      llhttpsender.cpp      llinstantmessage.cpp @@ -57,6 +59,7 @@ set(llmessage_SOURCE_FILES      llpacketring.cpp      llpartdata.cpp      llpumpio.cpp +    llregionpresenceverifier.cpp      llsdappservices.cpp      llsdhttpserver.cpp      llsdmessagebuilder.cpp @@ -65,7 +68,9 @@ set(llmessage_SOURCE_FILES      llsdrpcserver.cpp      llservicebuilder.cpp      llservice.cpp +    llstoredmessage.cpp      lltemplatemessagebuilder.cpp +    lltemplatemessagedispatcher.cpp      lltemplatemessagereader.cpp      llthrottle.cpp      lltransfermanager.cpp @@ -73,6 +78,7 @@ set(llmessage_SOURCE_FILES      lltransfersourcefile.cpp      lltransfertargetfile.cpp      lltransfertargetvfile.cpp +    lltrustedmessageservice.cpp      llurlrequest.cpp      lluseroperation.cpp      llxfer.cpp @@ -85,7 +91,6 @@ set(llmessage_SOURCE_FILES      message_prehash.cpp      message_string_table.cpp      net.cpp -    network.cpp      partsyspacket.cpp      patch_code.cpp      patch_dct.cpp @@ -115,7 +120,10 @@ set(llmessage_HEADER_FILES      llhost.h      llhttpassetstorage.h      llhttpclient.h +    llhttpclientinterface.h +    llhttpclientadapter.h      llhttpnode.h +    llhttpnodeadapter.h      llhttpsender.h      llinstantmessage.h      llinvite.h @@ -144,6 +152,7 @@ set(llmessage_HEADER_FILES      llqueryflags.h      llregionflags.h      llregionhandle.h +    llregionpresenceverifier.h      llsdappservices.h      llsdhttpserver.h      llsdmessagebuilder.h @@ -152,9 +161,11 @@ set(llmessage_HEADER_FILES      llsdrpcserver.h      llservice.h      llservicebuilder.h +    llstoredmessage.h      lltaskname.h      llteleportflags.h      lltemplatemessagebuilder.h +    lltemplatemessagedispatcher.h      lltemplatemessagereader.h      llthrottle.h      lltransfermanager.h @@ -162,6 +173,7 @@ set(llmessage_HEADER_FILES      lltransfersourcefile.h      lltransfertargetfile.h      lltransfertargetvfile.h +    lltrustedmessageservice.h      llurlrequest.h      lluseroperation.h      llvehicleparams.h @@ -176,7 +188,6 @@ set(llmessage_HEADER_FILES      message.h      message_prehash.h      net.h -    network.h      partsyspacket.h      patch_code.h      patch_dct.h @@ -197,3 +208,13 @@ target_link_libraries(      ${CRYPTO_LIBRARIES}      ${XMLRPCEPI_LIBRARIES}      ) + +IF (NOT LINUX AND VIEWER) +    # When building the viewer the tests links against the shared objects.  +    # These can not be found when we try to run the tests, so we had to disable them, for the viewer build. +    # TODO: Can someone with viewer knowledge figure out how to make these find the correct so. +    #ADD_BUILD_TEST(llhttpclientadapter llmessage) +    ADD_BUILD_TEST(lltrustedmessageservice llmessage) +    ADD_BUILD_TEST(lltemplatemessagedispatcher llmessage) +ENDIF (NOT LINUX AND VIEWER) + diff --git a/indra/llmessage/lldispatcher.cpp b/indra/llmessage/lldispatcher.cpp index bb7c833b49..7ce3d11be4 100644 --- a/indra/llmessage/lldispatcher.cpp +++ b/indra/llmessage/lldispatcher.cpp @@ -111,40 +111,14 @@ bool LLDispatcher::unpackMessage(  		LLUUID& invoice,  		LLDispatcher::sparam_t& parameters)  { -	char buf[MAX_STRING];	/*Flawfinder: ignore*/  	msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);  	msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice); -	S32 size;  	S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);  	for (S32 i = 0; i < count; ++i)  	{ -		// we treat the SParam as binary data (since it might be an  -		// LLUUID in compressed form which may have embedded \0's,) -		size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter); -		msg->getBinaryDataFast( -			_PREHASH_ParamList, _PREHASH_Parameter, -			buf, size, i, MAX_STRING-1); - -		// If the last byte of the data is 0x0, this is either a normally -		// packed string, or a binary packed UUID (which for these messages -		// are packed with a 17th byte 0x0).  Unpack into a std::string -		// without the trailing \0, so "abc\0" becomes std::string("abc", 3) -		// which matches const char* "abc". -		if (size > 0 -			&& buf[size-1] == 0x0) -		{ -			// special char*/size constructor because UUIDs may have embedded -			// 0x0 bytes. -			std::string binary_data(buf, size-1); -			parameters.push_back(binary_data); -		} -		else -		{ -			// This is either a NULL string, or a string that was packed  -			// incorrectly as binary data, without the usual trailing '\0'. -			std::string string_data(buf, size); -			parameters.push_back(string_data); -		} +		std::string parameter; +		msg->getStringFast(_PREHASH_ParamList,_PREHASH_Parameter, parameter, i); +		parameters.push_back(parameter);  	}  	return true;  } diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp index 2438539049..dfdad59e2a 100644 --- a/indra/llmessage/llhttpassetstorage.cpp +++ b/indra/llmessage/llhttpassetstorage.cpp @@ -235,6 +235,7 @@ LLSD LLHTTPAssetRequest::getFullDetails() const  void LLHTTPAssetRequest::setupCurlHandle()  { +	// *NOTE: Similar code exists in mapserver/llcurlutil.cpp  JC  	mCurlHandle = curl_easy_init();  	curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);  	curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1); diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp new file mode 100644 index 0000000000..f0e7654646 --- /dev/null +++ b/indra/llmessage/llhttpclientadapter.cpp @@ -0,0 +1,53 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2001-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llhttpclientadapter.h" +#include "llhttpclient.h" + +LLHTTPClientAdapter::~LLHTTPClientAdapter()  +{ +} + +void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder)  +{ +	LLHTTPClient::get(url, responder); +} + +void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers)  +{ +	LLHTTPClient::get(url, responder, headers); +} + +void LLHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder)  +{ +	LLHTTPClient::put(url, body, responder); +} + diff --git a/indra/llmessage/llhttpclientadapter.h b/indra/llmessage/llhttpclientadapter.h new file mode 100644 index 0000000000..d5f3aeaf2c --- /dev/null +++ b/indra/llmessage/llhttpclientadapter.h @@ -0,0 +1,48 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_HTTPCLIENTADAPTER_H +#define LL_HTTPCLIENTADAPTER_H + +#include "llhttpclientinterface.h" +#include "llmemory.h"	// LLSingleton<> + +class LLHTTPClientAdapter : public LLHTTPClientInterface, public LLSingleton<LLHTTPClientAdapter> +{ +public: +	virtual ~LLHTTPClientAdapter(); +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder); +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers); +	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder); +}; + +#endif + diff --git a/indra/llmessage/llhttpclientinterface.h b/indra/llmessage/llhttpclientinterface.h new file mode 100644 index 0000000000..1f13d46447 --- /dev/null +++ b/indra/llmessage/llhttpclientinterface.h @@ -0,0 +1,50 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLHTTPCLIENTINTERFACE_H +#define LL_LLHTTPCLIENTINTERFACE_H + +#include "linden_common.h" +#include "llcurl.h" + +#include <string> + +class LLHTTPClientInterface +{ +public: +	virtual ~LLHTTPClientInterface() {} +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder) = 0; +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) = 0; +	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) = 0; +}; + +#endif // LL_LLHTTPCLIENTINTERFACE_H + diff --git a/indra/llmessage/llhttpnode.h b/indra/llmessage/llhttpnode.h index 4f80db47f1..17ffd66e8f 100644 --- a/indra/llmessage/llhttpnode.h +++ b/indra/llmessage/llhttpnode.h @@ -88,6 +88,9 @@ public:  	virtual LLSD post(const LLSD& input) const;  	virtual LLSD del(const LLSD& context) const; +	/** +	* @brief Abstract Base Class declaring Response interface. +	*/  	class Response : public LLRefCount  	{  	protected: @@ -95,8 +98,8 @@ public:  	public:  		/** -		 * @brief Return the LLSD content and a 200 OK. -		 */ +		* @brief Return the LLSD content and a 200 OK. +		*/  		virtual void result(const LLSD&) = 0;  		/** @@ -111,42 +114,41 @@ public:  		virtual void status(S32 code, const std::string& message) = 0;  		/** -		 * @brief Return no body, just status code and 'UNKNOWN ERROR'. -		 */ -		void status(S32 code); +		* @brief Return no body, just status code and 'UNKNOWN ERROR'. +		*/ +		virtual void status(S32 code); -		void notFound(const std::string& message); -		void notFound(); -		void methodNotAllowed(); +		virtual void notFound(const std::string& message); +		virtual void notFound(); +		virtual void methodNotAllowed();  		/** -		 * @breif Add a name: value http header. -		 * -		 * No effort is made to ensure the response is a valid http -		 * header. -		 * The headers are stored as a map of header name : value. -		 * Though HTTP allows the same header name to be transmitted -		 * more than once, this implementation only stores a header -		 * name once. -		 * @param name The name of the header, eg, "Content-Encoding" -		 * @param value The value of the header, eg, "gzip" -		 */ -		void addHeader(const std::string& name, const std::string& value); +		* @breif Add a name: value http header. +		* +		* No effort is made to ensure the response is a valid http +		* header. +		* The headers are stored as a map of header name : value. +		* Though HTTP allows the same header name to be transmitted +		* more than once, this implementation only stores a header +		* name once. +		* @param name The name of the header, eg, "Content-Encoding" +		* @param value The value of the header, eg, "gzip" +		*/ +		virtual void addHeader(const std::string& name, const std::string& value);  	protected:  		/** -		 * @brief Headers to be sent back with the HTTP response. -		 * -		 * Protected class membership since derived classes are -		 * expected to use it and there is no use case yet for other -		 * uses. If such a use case arises, I suggest making a -		 * headers() public method, and moving this member data into -		 * private. -		 */ +		* @brief Headers to be sent back with the HTTP response. +		* +		* Protected class membership since derived classes are +		* expected to use it and there is no use case yet for other +		* uses. If such a use case arises, I suggest making a +		* headers() public method, and moving this member data into +		* private. +		*/  		LLSD mHeaders;  	}; -  	typedef LLPointer<Response> ResponsePtr;  	virtual void get(ResponsePtr, const LLSD& context) const; diff --git a/indra/llmessage/llhttpnodeadapter.h b/indra/llmessage/llhttpnodeadapter.h new file mode 100644 index 0000000000..08b5664162 --- /dev/null +++ b/indra/llmessage/llhttpnodeadapter.h @@ -0,0 +1,57 @@ +/** + * @file llhttpnodeadapter.h + * @brief Declaration of llhttpnode adapter classes + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_HTTP_NODE_ADAPTER_H +#define LL_HTTP_NODE_ADAPTER_H + +#include "llhttpnode.h" + +template<typename T> +class LLHTTPNodeAdapter : public LLHTTPNode +{ +public: + +	virtual bool validate(const std::string& name, LLSD& context) const +	{ +		T node; +		return node.validate(name, context); +	} +	 +	virtual void post(LLHTTPNode::ResponsePtr response, +					  const LLSD& context, +					  const LLSD& input) const +	{ +		T node; +		return node.post(response, context, input); +	} +}; + +#endif // LL_HTTP_NODE_ADAPTER_H diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp index 0895af091b..83dfa94f00 100644 --- a/indra/llmessage/lliohttpserver.cpp +++ b/indra/llmessage/lliohttpserver.cpp @@ -844,6 +844,7 @@ LLIOPipe::EStatus LLHTTPResponder::process_impl(  				= node->getProtocolHandler();  			if (protocolHandler)  			{ +				lldebugs << "HTTP context: " << context << llendl;  				protocolHandler->build(chain, context);  			}  			else diff --git a/indra/llmessage/llmessagesenderinterface.h b/indra/llmessage/llmessagesenderinterface.h new file mode 100644 index 0000000000..4082666339 --- /dev/null +++ b/indra/llmessage/llmessagesenderinterface.h @@ -0,0 +1,49 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLMESSAGESENDERINTERFACE_H +#define LL_LLMESSAGESENDERINTERFACE_H + +#include "linden_common.h" +#include "llstoredmessage.h" +class LLHost; +class LLSD; + +class LLMessageSenderInterface +{ +public: +	virtual ~LLMessageSenderInterface() {} +	virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message) = 0; + +}; + +#endif // LL_LLMESSAGESENDERINTERFACE_H + diff --git a/indra/llmessage/llregionpresenceverifier.cpp b/indra/llmessage/llregionpresenceverifier.cpp new file mode 100644 index 0000000000..b3fabddd3e --- /dev/null +++ b/indra/llmessage/llregionpresenceverifier.cpp @@ -0,0 +1,87 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=internal$ + *  + * Copyright (c) 2008, Linden Research, Inc. + *  + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llregionpresenceverifier.h" +#include "llhttpclientinterface.h" +#include <sstream> +#include "net.h" +#include "message.h" + + +LLRegionPresenceVerifier::RegionResponder::RegionResponder(ResponsePtr data) : mSharedData(data) +{ +} + + +void LLRegionPresenceVerifier::RegionResponder::result(const LLSD& content) +{ +	std::string host = content["private_host"].asString(); +	U32 port = content["private_port"].asInteger(); +	LLHost destination(host, port); +	LLUUID id = content["region_id"]; + +	llinfos << "Verifying " << destination.getString() << " is region " << id << llendl; + +	std::stringstream uri; +	uri << "http://" << destination.getString() << "/state/basic"; +	mSharedData->getHttpClient().get(uri.str(), new VerifiedDestinationResponder(mSharedData, content)); +} + +void LLRegionPresenceVerifier::RegionResponder::completed( +	U32 status, +	const std::string& reason, +	const LLSD& content) +{ +	LLHTTPClient::Responder::completed(status, reason, content); +	 +	mSharedData->onCompletedRegionRequest(); +} + + +LLRegionPresenceVerifier::VerifiedDestinationResponder::VerifiedDestinationResponder(ResponsePtr data, const LLSD& content) : mSharedData(data), mContent(content) +{ +} + + + + +void LLRegionPresenceVerifier::VerifiedDestinationResponder::result(const LLSD& content) +{ +	LLUUID actual_region_id = content["region_id"]; +	LLUUID expected_region_id = mContent["region_id"]; + +	if (mSharedData->checkValidity(content)) +	{ +		mSharedData->onRegionVerified(mContent); +	} +	else if ((mSharedData->shouldRetry()) && (actual_region_id != expected_region_id)) // If the region is correct, then it means we've deliberately changed the data +	{ +		LLSD headers; +		headers["Cache-Control"] = "no-cache, max-age=0"; +		llinfos << "Requesting region information, get uncached for region " << mSharedData->getRegionUri() << llendl; +		mSharedData->decrementRetries(); +		mSharedData->getHttpClient().get(mSharedData->getRegionUri(), new RegionResponder(mSharedData), headers); +	} +	else +	{ +		llwarns << "Could not correctly look up region from region presence service. Region: " << mSharedData->getRegionUri() << llendl; +	} +} diff --git a/indra/llmessage/llregionpresenceverifier.h b/indra/llmessage/llregionpresenceverifier.h new file mode 100644 index 0000000000..a0f08f12fe --- /dev/null +++ b/indra/llmessage/llregionpresenceverifier.h @@ -0,0 +1,81 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=internal$ + *  + * Copyright (c) 2008, Linden Research, Inc. + *  + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* Macro Definitions */ +#ifndef LL_LLREGIONPRESENCEVERIFIER_H +#define LL_LLREGIONPRESENCEVERIFIER_H + +#include "llhttpclient.h" +#include <string> +#include "llsd.h" +#include <boost/shared_ptr.hpp> + +class LLHTTPClientInterface; + +class LLRegionPresenceVerifier +{ +public: +	class Response +	{ +	public: +		virtual ~Response() {} + +		virtual bool checkValidity(const LLSD& content) const = 0; +		virtual void onRegionVerified(const LLSD& region_details) = 0; + +		virtual void decrementRetries() = 0; + +		virtual LLHTTPClientInterface& getHttpClient() = 0; +		virtual std::string getRegionUri() const = 0; +		virtual bool shouldRetry() const = 0; + +		virtual void onCompletedRegionRequest() {} +	}; + +	typedef boost::shared_ptr<Response> ResponsePtr; + +	class RegionResponder : public LLHTTPClient::Responder +	{ +	public: +		RegionResponder(ResponsePtr data); +		virtual void result(const LLSD& content); +		virtual void completed( +			U32 status, +			const std::string& reason, +			const LLSD& content); + +	private: +		ResponsePtr mSharedData; +	}; + +	class VerifiedDestinationResponder : public LLHTTPClient::Responder +	{ +	public: +		VerifiedDestinationResponder(ResponsePtr data, const LLSD& content); +		virtual void result(const LLSD& content); +	private: +		ResponsePtr mSharedData; +		LLSD mContent; +	}; +}; + + +#endif //LL_LLREGIONPRESENCEVERIFIER_H diff --git a/indra/llmessage/llsdmessagebuilder.cpp b/indra/llmessage/llsdmessagebuilder.cpp index a62dd04560..21937f022f 100755 --- a/indra/llmessage/llsdmessagebuilder.cpp +++ b/indra/llmessage/llsdmessagebuilder.cpp @@ -268,10 +268,125 @@ void LLSDMessageBuilder::copyFromMessageData(const LLMsgData& data)  		for(; dit != dend; ++dit)  		{ -			//const LLMsgVarData& mvci = *dit; - -			// TODO: Copy mvci data in to block: -			// (*mCurrentBlock)[varname] = v; +			const LLMsgVarData& mvci = *dit; +			const char* varname = mvci.getName(); + +			switch(mvci.getType()) +			{ +			case MVT_FIXED: +				addBinaryData(varname, mvci.getData(), mvci.getSize()); +				break; + +			case MVT_VARIABLE: +				{ +					const char end = ((const char*)mvci.getData())[mvci.getSize()-1]; // Ensure null terminated +					if (mvci.getDataSize() == 1 && end == 0)  +					{ +						addString(varname, (const char*)mvci.getData()); +					} +					else +					{ +						addBinaryData(varname, mvci.getData(), mvci.getSize()); +					} +					break; +				} + +			case MVT_U8: +				addU8(varname, *(U8*)mvci.getData()); +				break; + +			case MVT_U16: +				addU16(varname, *(U16*)mvci.getData()); +				break; + +			case MVT_U32: +				addU32(varname, *(U32*)mvci.getData()); +				break; + +			case MVT_U64: +				addU64(varname, *(U64*)mvci.getData()); +				break; + +			case MVT_S8: +				addS8(varname, *(S8*)mvci.getData()); +				break; + +			case MVT_S16: +				addS16(varname, *(S16*)mvci.getData()); +				break; + +			case MVT_S32: +				addS32(varname, *(S32*)mvci.getData()); +				break; + +			// S64 not supported in LLSD so we just truncate it +			case MVT_S64: +				addS32(varname, *(S64*)mvci.getData()); +				break; + +			case MVT_F32: +				addF32(varname, *(F32*)mvci.getData()); +				break; + +			case MVT_F64: +				addF64(varname, *(F64*)mvci.getData()); +				break; + +			case MVT_LLVector3: +				addVector3(varname, *(LLVector3*)mvci.getData()); +				break; + +			case MVT_LLVector3d: +				addVector3d(varname, *(LLVector3d*)mvci.getData()); +				break; + +			case MVT_LLVector4: +				addVector4(varname, *(LLVector4*)mvci.getData()); +				break; + +			case MVT_LLQuaternion: +				{ +					LLVector3 v = *(LLVector3*)mvci.getData(); +					LLQuaternion q; +					q.unpackFromVector3(v); +					addQuat(varname, q); +					break; +				} + +			case MVT_LLUUID: +				addUUID(varname, *(LLUUID*)mvci.getData()); +				break;	 + +			case MVT_BOOL: +				addBOOL(varname, *(BOOL*)mvci.getData()); +				break; + +			case MVT_IP_ADDR: +				addIPAddr(varname, *(U32*)mvci.getData()); +				break; + +			case MVT_IP_PORT: +				addIPPort(varname, *(U16*)mvci.getData()); +				break; + +			case MVT_U16Vec3: +				//treated as an array of 6 bytes +				addBinaryData(varname, mvci.getData(), 6); +				break; + +			case MVT_U16Quat: +				//treated as an array of 8 bytes +				addBinaryData(varname, mvci.getData(), 8); +				break; + +			case MVT_S16Array: +				addBinaryData(varname, mvci.getData(), mvci.getSize()); +				break; + +			default: +				llwarns << "Unknown type in conversion of message to LLSD" << llendl; +				break; +			}  		}  	}  } diff --git a/indra/llmessage/llstoredmessage.cpp b/indra/llmessage/llstoredmessage.cpp new file mode 100644 index 0000000000..615eff405d --- /dev/null +++ b/indra/llmessage/llstoredmessage.cpp @@ -0,0 +1,38 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2001-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llstoredmessage.h" + +LLStoredMessage::LLStoredMessage(const std::string& name, const LLSD& message) : mMessage(message), mName(name) +{ +} + diff --git a/indra/llmessage/llstoredmessage.h b/indra/llmessage/llstoredmessage.h new file mode 100644 index 0000000000..e817f19bd2 --- /dev/null +++ b/indra/llmessage/llstoredmessage.h @@ -0,0 +1,58 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + *  + * Copyright (c) 2001-2009, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_STOREDMESSAGE_H +#define LL_STOREDMESSAGE_H + +#include "linden_common.h" +#include "llsd.h" +#include <boost/shared_ptr.hpp> +#include <string> + + +class LLMessageSystem; + +class LLStoredMessage +{ +public: +	LLStoredMessage(const std::string& name, const LLSD& message); +private: +	friend class LLMessageSystem; + +	LLSD mMessage; +	std::string mName; +}; + +typedef boost::shared_ptr<LLStoredMessage> LLStoredMessagePtr; + + +#endif // LL_STOREDMESSAGE_H diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp index c153c81372..e6419807ff 100644 --- a/indra/llmessage/lltemplatemessagebuilder.cpp +++ b/indra/llmessage/lltemplatemessagebuilder.cpp @@ -41,7 +41,7 @@  #include "v3math.h"  #include "v4math.h" -LLTemplateMessageBuilder::LLTemplateMessageBuilder(message_template_name_map_t& name_template_map) : +LLTemplateMessageBuilder::LLTemplateMessageBuilder(const message_template_name_map_t& name_template_map) :  	mCurrentSMessageData(NULL),  	mCurrentSMessageTemplate(NULL),  	mCurrentSDataBlock(NULL), @@ -75,14 +75,14 @@ void LLTemplateMessageBuilder::newMessage(const char *name)  	char* namep = (char*)name;   	if (mMessageTemplates.count(namep) > 0)  	{ -		mCurrentSMessageTemplate = mMessageTemplates[namep]; +		mCurrentSMessageTemplate = mMessageTemplates.find(name)->second;  		mCurrentSMessageData = new LLMsgData(namep);  		mCurrentSMessageName = namep;  		mCurrentSDataBlock = NULL;  		mCurrentSBlockName = NULL;  		// add at one of each block -		const LLMessageTemplate* msg_template = mMessageTemplates[namep]; +		const LLMessageTemplate* msg_template = mMessageTemplates.find(name)->second;  		if (msg_template->getDeprecation() != MD_NOTDEPRECATED)  		{ diff --git a/indra/llmessage/lltemplatemessagebuilder.h b/indra/llmessage/lltemplatemessagebuilder.h index bcdf722b1b..96e7ae1a86 100644 --- a/indra/llmessage/lltemplatemessagebuilder.h +++ b/indra/llmessage/lltemplatemessagebuilder.h @@ -49,7 +49,7 @@ public:  	typedef std::map<const char* , LLMessageTemplate*> message_template_name_map_t; -	LLTemplateMessageBuilder(message_template_name_map_t&); +	LLTemplateMessageBuilder(const message_template_name_map_t&);  	virtual ~LLTemplateMessageBuilder();  	virtual void newMessage(const char* name); @@ -99,6 +99,7 @@ public:  	virtual void copyFromMessageData(const LLMsgData& data);  	virtual void copyFromLLSD(const LLSD&); +	LLMsgData* getCurrentMessage() const { return mCurrentSMessageData; }  private:  	void addData(const char* varname, const void* data,   					 EMsgVariableType type, S32 size); @@ -114,7 +115,7 @@ private:  	BOOL mbSBuilt;  	BOOL mbSClear;  	S32	 mCurrentSendTotal; -	message_template_name_map_t& mMessageTemplates; +	const message_template_name_map_t& mMessageTemplates;  };  #endif // LL_LLTEMPLATEMESSAGEBUILDER_H diff --git a/indra/llmessage/lltemplatemessagedispatcher.cpp b/indra/llmessage/lltemplatemessagedispatcher.cpp new file mode 100644 index 0000000000..3bbf3a058d --- /dev/null +++ b/indra/llmessage/lltemplatemessagedispatcher.cpp @@ -0,0 +1,72 @@ +/** + * @file lltemplatemessagedispatcher.h + * @brief LLTemplateMessageDispatcher class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "lltemplatemessagedispatcher.h" + +#include "llhttpnode.h" +#include "llhost.h" +#include "message.h" +#include "llsd.h" +#include "lltemplatemessagereader.h" + + +LLTemplateMessageDispatcher::LLTemplateMessageDispatcher(LLTemplateMessageReader &template_message_reader) : +	mTemplateMessageReader(template_message_reader) +{ +} + +void LLTemplateMessageDispatcher::dispatch(const std::string& msg_name, +										   const LLSD& message, +										   LLHTTPNode::ResponsePtr responsep) +{ +	std::vector<U8> data = message["body"]["binary-template-data"].asBinary(); +	U32 size = data.size(); +	if(size == 0) +	{ +		return; +	} + +	LLHost host; +	host = gMessageSystem->getSender(); + +	bool validate_message = mTemplateMessageReader.validateMessage(&(data[0]), data.size(), host, true); + +	if (validate_message) +	{ +		mTemplateMessageReader.readMessage(&(data[0]),host); +	}  +	else  +	{ +		gMessageSystem->clearReceiveState(); +	} +} + diff --git a/indra/llmessage/lltemplatemessagedispatcher.h b/indra/llmessage/lltemplatemessagedispatcher.h new file mode 100644 index 0000000000..b1e74f47bb --- /dev/null +++ b/indra/llmessage/lltemplatemessagedispatcher.h @@ -0,0 +1,53 @@ +/** + * @file lltemplatemessagedispatcher.h + * @brief LLTemplateMessageDispatcher class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLTEMPLATEMESSAGEDISPATCHER_H +#define LLTEMPLATEMESSAGEDISPATCHER_H + +#include "linden_common.h" +#include "llsd.h" +#include "llhttpnode.h" +#include "lltemplatemessagereader.h" + + +class LLTemplateMessageDispatcher +{ +public: +	LLTemplateMessageDispatcher(LLTemplateMessageReader& template_message_reader); +	void dispatch(const std::string& msg_name, +				  const LLSD& message, +				  LLHTTPNode::ResponsePtr responsep); + +private: +	LLTemplateMessageReader &mTemplateMessageReader; +}; + +#endif // LLTEMPLATEMESSAGEDISPATCHER_H diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index f64a096b3e..d635844ee5 100644 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -755,18 +755,38 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender  BOOL LLTemplateMessageReader::validateMessage(const U8* buffer,   											  S32 buffer_size,  -											  const LLHost& sender) +											  const LLHost& sender, +											  bool trusted)  {  	mReceiveSize = buffer_size; -	BOOL result = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); -	if(result) +	BOOL valid = decodeTemplate(buffer, buffer_size, &mCurrentRMessageTemplate ); +	if(valid)  	{  		mCurrentRMessageTemplate->mReceiveCount++; -		//lldebugs << "MessageRecvd:"  +		//lldebugs << "MessageRecvd:"  		//						 << mCurrentRMessageTemplate->mName   		//						 << " from " << sender << llendl;  	} -	return result; + +	if (valid && isBanned(trusted)) +	{ +		LL_WARNS("Messaging") << "LLMessageSystem::checkMessages " +			<< "received banned message " +			<< getMessageName() +			<< " from " +			<< ((trusted) ? "trusted " : "untrusted ") +			<< sender << llendl; +		valid = FALSE; +	} + +	if(valid && isUdpBanned()) +	{ +		llwarns << "Received UDP black listed message " +				<<  getMessageName() +				<< " from " << sender << llendl; +		valid = FALSE; +	} +	return valid;  }  BOOL LLTemplateMessageReader::readMessage(const U8* buffer,  diff --git a/indra/llmessage/lltemplatemessagereader.h b/indra/llmessage/lltemplatemessagereader.h index e1062de88f..ab06ab433d 100644 --- a/indra/llmessage/lltemplatemessagereader.h +++ b/indra/llmessage/lltemplatemessagereader.h @@ -105,7 +105,7 @@ public:  	virtual void copyToBuilder(LLMessageBuilder&) const;  	BOOL validateMessage(const U8* buffer, S32 buffer_size,  -						 const LLHost& sender); +						 const LLHost& sender, bool trusted = false);  	BOOL readMessage(const U8* buffer, const LLHost& sender);  	bool isTrusted() const; diff --git a/indra/llmessage/lltrustedmessageservice.cpp b/indra/llmessage/lltrustedmessageservice.cpp new file mode 100644 index 0000000000..c1a6c437a7 --- /dev/null +++ b/indra/llmessage/lltrustedmessageservice.cpp @@ -0,0 +1,89 @@ +/** + * @file lltrustedmessageservice.cpp + * @brief LLTrustedMessageService implementation + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "lltrustedmessageservice.h" +#include "llhost.h" +#include "llmessageconfig.h" +#include "message.h" + + +bool LLTrustedMessageService::validate(const std::string& name, LLSD& context) +const +{ +	return true; +} + +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; +	std::string sender = senderIP + ":" + senderPort; +	message_data["sender"] = sender; +	message_data["body"] = input; +	 +	// untrusted senders should not have access to the trusted message +	// service, but this can happen in development, so check and warn +	LLMessageConfig::SenderTrust trust = +		LLMessageConfig::getSenderTrustedness(name); +	if ((trust == LLMessageConfig::TRUSTED || +		 (trust == LLMessageConfig::NOT_SET && +		  gMessageSystem->isTrustedMessage(name))) +		 && !gMessageSystem->isTrustedSender(LLHost(sender))) +	{ +		LL_WARNS("Messaging") << "trusted message POST to /trusted-message/"  +				<< name << " from unknown or untrusted sender " +				<< sender << llendl; +		response->status(403, "Unknown or untrusted sender"); +	} +	else +	{ +		gMessageSystem->receivedMessageFromTrustedSender(); +		if (input.has("binary-template-data")) +		{ +			llinfos << "Dispatching template: " << input << llendl; +			// try and send this message using udp dispatch +			LLMessageSystem::dispatchTemplate(name, message_data, response); +		} +		else +		{ +			llinfos << "Dispatching without template: " << input << llendl; +			LLMessageSystem::dispatch(name, message_data, response); +		} +	} +} diff --git a/indra/llmessage/lltrustedmessageservice.h b/indra/llmessage/lltrustedmessageservice.h new file mode 100644 index 0000000000..bc824565f1 --- /dev/null +++ b/indra/llmessage/lltrustedmessageservice.h @@ -0,0 +1,51 @@ +/** + * @file lltrustedmessageservice.h + * @brief LLTrustedMessageService class + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LLTRUSTEDMESSAGESERVICE_H +#define LLTRUSTEDMESSAGESERVICE_H + +#include "linden_common.h" +#include "llhttpnode.h" + +class LLSD; + +class LLTrustedMessageService +{ +public: + +	bool validate(const std::string& name, LLSD& context) const; +	 +	void post(LLHTTPNode::ResponsePtr response, +			  const LLSD& context, +			  const LLSD& input) const; +}; + +#endif // LLTRUSTEDMESSAGESERVICE_H diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index 4e6cda2880..8ab12ce991 100644 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -59,13 +59,16 @@  #include "llerrorlegacy.h"  #include "llfasttimer.h"  #include "llhttpclient.h" +#include "llhttpnodeadapter.h"  #include "llhttpsender.h"  #include "llmd5.h"  #include "llmessagebuilder.h"  #include "llmessageconfig.h" +#include "lltemplatemessagedispatcher.h"  #include "llpumpio.h"  #include "lltemplatemessagebuilder.h"  #include "lltemplatemessagereader.h" +#include "lltrustedmessageservice.h"  #include "llmessagetemplate.h"  #include "llmessagetemplateparser.h"  #include "llsd.h" @@ -142,52 +145,6 @@ namespace  	};  } - -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; -	std::string sender = senderIP + ":" + senderPort; -	message_data["sender"] = sender; -	message_data["body"] = input; -	 -	// untrusted senders should not have access to the trusted message -	// service, but this can happen in development, so check and warn -	LLMessageConfig::SenderTrust trust = -		LLMessageConfig::getSenderTrustedness(name); -	if ((trust == LLMessageConfig::TRUSTED || -		 (trust == LLMessageConfig::NOT_SET && -		  gMessageSystem->isTrustedMessage(name))) -		 && !gMessageSystem->isTrustedSender(LLHost(sender))) -	{ -		LL_WARNS("Messaging") << "trusted message POST to /trusted-message/"  -				<< name << " from unknown or untrusted sender " -				<< sender << llendl; -		response->status(403, "Unknown or untrusted sender"); -	} -	else -	{ -		LLMessageSystem::dispatch(name, message_data, response); -	} -} -  class LLMessageHandlerBridge : public LLHTTPNode  {  	virtual bool validate(const std::string& name, LLSD& context) const @@ -223,9 +180,6 @@ void LLMessageHandlerBridge::post(LLHTTPNode::ResponsePtr response,  LLHTTPRegistration<LLMessageHandlerBridge>  	gHTTPRegistrationMessageWildcard("/message/<message-name>"); -LLHTTPRegistration<LLTrustedMessageService> -	gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>"); -  //virtual  LLUseCircuitCodeResponder::~LLUseCircuitCodeResponder()  { @@ -293,7 +247,8 @@ LLMessageSystem::LLMessageSystem(const std::string& filename, U32 port,  								 S32 version_patch,  								 bool failure_is_fatal,  								 const F32 circuit_heartbeat_interval, const F32 circuit_timeout) : -	mCircuitInfo(circuit_heartbeat_interval, circuit_timeout) +	mCircuitInfo(circuit_heartbeat_interval, circuit_timeout), +	mLastMessageFromTrustedMessageService(false)  {  	init(); @@ -445,6 +400,7 @@ void LLMessageSystem::clearReceiveState()  	mLastSender.invalidate();  	mLastReceivingIF.invalidate();  	mMessageReader->clearMessage(); +	mLastMessageFromTrustedMessageService = false;  } @@ -477,6 +433,17 @@ bool LLMessageSystem::isTrustedSender(const LLHost& host) const  	return cdp->getTrusted();  } +void LLMessageSystem::receivedMessageFromTrustedSender() +{ +	mLastMessageFromTrustedMessageService = true; +} + +bool LLMessageSystem::isTrustedSender() const +{	 +	return mLastMessageFromTrustedMessageService || +		isTrustedSender(getSender()); +} +  static LLMessageSystem::message_template_name_map_t::const_iterator   findTemplate(const LLMessageSystem::message_template_name_map_t& templates,   			 std::string name) @@ -717,11 +684,16 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			// UseCircuitCode can be a valid, off-circuit packet.  			// But we don't want to acknowledge UseCircuitCode until the circuit is  			// available, which is why the acknowledgement test is done above.  JC - +			bool trusted = cdp && cdp->getTrusted();  			valid_packet = mTemplateMessageReader->validateMessage(  				buffer,  				receive_size, -				host); +				host, +				trusted); +			if (!valid_packet) +			{ +				clearReceiveState(); +			}  			// UseCircuitCode is allowed in even from an invalid circuit, so that  			// we can toss circuits around. @@ -749,29 +721,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  				valid_packet = FALSE;  			} -			if ( -				valid_packet && -				mTemplateMessageReader->isBanned(cdp && cdp->getTrusted())) -			{ -				LL_WARNS("Messaging") << "LLMessageSystem::checkMessages " -					<< "received banned message " -					<< mTemplateMessageReader->getMessageName() -					<< " from " -					<< ((cdp && cdp->getTrusted()) ? "trusted " : "untrusted ") -					<< host << llendl; -				clearReceiveState(); -				valid_packet = FALSE; -			} - -			if( valid_packet && mTemplateMessageReader->isUdpBanned()) -			{ -				llwarns << "Received UDP black listed message " -						<<  mTemplateMessageReader->getMessageName() -						<< " from " << host << llendl; -				clearReceiveState(); -				valid_packet = FALSE; -			} -  			if( valid_packet )  			{  				logValidMsg(cdp, host, recv_reliable, recv_resent, (BOOL)(acks>0) ); @@ -784,94 +733,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  			if (valid_packet)  			{ -				// enable this for output of message names -				//LL_INFOS("Messaging") << "< \"" << mTemplateMessageReader->getMessageName() -						//<< "\"" << llendl; - -				/* Code for dumping the complete contents of a message.  Keep for future use in optimizing messages. -				if( 1 ) -				{ -					static char* object_update = LLMessageStringTable::getInstance()->getString("ObjectUpdate"); -					if(object_update == mTemplateMessageReader->getMessageName() ) -					{ -						LL_INFOS("Messaging") << "ObjectUpdate:" << llendl; -						U32 i; -						LL_INFOS("Messaging") << "    Zero Encoded: " << zero_unexpanded_size << llendl; -						for( i = 0; i<zero_unexpanded_size; i++ ) -						{ -							LL_INFOS("Messaging") << "     " << i << ": " << (U32) zero_unexpanded_buffer[i] << llendl; -						} -						LL_INFOS("Messaging") << "" << llendl; - -						LL_INFOS("Messaging") << "    Zero Unencoded: " << receive_size << llendl; -						for( i = 0; i<receive_size; i++ ) -						{ -							LL_INFOS("Messaging") << "     " << i << ": " << (U32) buffer[i] << llendl; -						} -						LL_INFOS("Messaging") << "" << llendl; - -						LL_INFOS("Messaging") << "    Blocks and variables: " << llendl; -						S32 byte_count = 0; -						for (LLMessageTemplate::message_block_map_t::iterator -								 iter = mCurrentRMessageTemplate->mMemberBlocks.begin(), -								 end = mCurrentRMessageTemplate->mMemberBlocks.end(); -							 iter != end; iter++) -						{ -							LLMessageBlock* block = iter->second; -							const char* block_name = block->mName; -							for (LLMsgBlkData::msg_var_data_map_t::iterator -									 iter = block->mMemberVariables.begin(), -									 end = block->mMemberVariables.end(); -								 iter != end; iter++) -							{ -								const char* var_name = iter->first; -								 -								if( getNumberOfBlocksFast( block_name ) < 1 ) -								{ -									LL_INFOS("Messaging") << var_name << " has no blocks" << llendl; -								} -								for( S32 blocknum = 0; blocknum < getNumberOfBlocksFast( block_name ); blocknum++ ) -								{ -									char *bnamep = (char *)block_name + blocknum; // this works because it's just a hash.  The bnamep is never derefference -									char *vnamep = (char *)var_name;  - -									LLMsgBlkData *msg_block_data = mCurrentRMessageData->mMemberBlocks[bnamep]; - -									if (!msg_block_data) -									{ -										std::string errmsg = llformat("Block %s #%d not in message %s", block_name, blocknum, mCurrentRMessageData->mName); -										LL_ERRS("Messaging") << errmsg << llendl; -									} - -									LLMsgVarData vardata = msg_block_data->mMemberVarData[vnamep]; - -									if (!vardata.getName()) -									{ -										std::string errmsg = llformat("Variable %s not in message %s block %s", vnamep, mCurrentRMessageData->mName, bnamep); -										LL_ERRS("Messaging") << errmsg << llendl; -									} - -									const S32 vardata_size = vardata.getSize(); -									if( vardata_size ) -									{ -										for( i = 0; i < vardata_size; i++ ) -										{ -											byte_count++; -											LL_INFOS("Messaging") << block_name << " " << var_name << " [" << blocknum << "][" << i << "]= " << (U32)(((U8*)vardata.getData())[i]) << llendl; -										} -									} -									else -									{ -										LL_INFOS("Messaging") << block_name << " " << var_name << " [" << blocknum << "] 0 bytes" << llendl; -									} -								} -							} -						} -						LL_INFOS("Messaging") << "Byte count =" << byte_count << llendl; -					} -				} -				*/ -  				mPacketsIn++;  				mBytesIn += mTrueReceiveSize; @@ -899,9 +760,6 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count )  					mInvalidOnCircuitPackets++;  				}  			} - -			// Code for dumping the complete contents of a message  -			// delete [] zero_unexpanded_buffer;  		}  	} while (!valid_packet && receive_size > 0); @@ -1004,7 +862,7 @@ void LLMessageSystem::processAcks()  	}  } -void LLMessageSystem::copyMessageRtoS() +void LLMessageSystem::copyMessageReceivedToSend()  {  	// NOTE: babbage: switch builder to match reader to avoid  	// converting message format @@ -1021,6 +879,72 @@ void LLMessageSystem::copyMessageRtoS()  	mMessageReader->copyToBuilder(*mMessageBuilder);  } +LLSD LLMessageSystem::getReceivedMessageLLSD() const +{ +	LLSDMessageBuilder builder; +	mMessageReader->copyToBuilder(builder); +	return builder.getMessage(); +} + +LLSD LLMessageSystem::getBuiltMessageLLSD() const  +{ +	LLSD result; +	if (mLLSDMessageBuilder == mMessageBuilder) +	{ +		 result = mLLSDMessageBuilder->getMessage(); +	} +	else +	{ +		// TODO: implement as below? +		llerrs << "Message not built as LLSD." << llendl;  +	} +	return result; +} + +LLSD LLMessageSystem::wrapReceivedTemplateData() const +{ +	if(mMessageReader == mTemplateMessageReader) +	{ +		LLTemplateMessageBuilder builder(mMessageTemplates); +		builder.newMessage(mMessageReader->getMessageName()); +		mMessageReader->copyToBuilder(builder); +		U8 buffer[MAX_BUFFER_SIZE]; +		const U8 offset_to_data = 0; +		U32 size = builder.buildMessage(buffer, MAX_BUFFER_SIZE, +										offset_to_data); +		std::vector<U8> binary_data(buffer, buffer+size); +		LLSD wrapped_data = LLSD::emptyMap(); +		wrapped_data["binary-template-data"] = binary_data; +		return wrapped_data; +	} +	else +	{ +		return getReceivedMessageLLSD(); +	} +} + +LLStoredMessagePtr LLMessageSystem::getReceivedMessage() const +{ +	const std::string& name = mMessageReader->getMessageName(); +	LLSD message = wrapReceivedTemplateData(); + +	return LLStoredMessagePtr(new LLStoredMessage(name, message)); +} + +LLStoredMessagePtr LLMessageSystem::getBuiltMessage() const +{ +	const std::string& name = mMessageBuilder->getMessageName(); +	LLSD message = getBuiltMessageLLSD(); + +	return LLStoredMessagePtr(new LLStoredMessage(name, message)); +} + +S32 LLMessageSystem::sendMessage(const LLHost &host, LLStoredMessagePtr message) +{ +	return sendMessage(host, message->mName.c_str(), message->mMessage); +} + +  void LLMessageSystem::clearMessage()  {  	mSendReliable = FALSE; @@ -1033,6 +957,11 @@ void LLMessageSystem::nextBlockFast(const char *blockname)  	mMessageBuilder->nextBlock(blockname);  } +void LLMessageSystem::nextBlock(const char *blockname) +{ +	nextBlockFast(LLMessageStringTable::getInstance()->getString(blockname)); +} +  BOOL LLMessageSystem::isSendFull(const char* blockname)  {  	char* stringTableName = NULL; @@ -1112,19 +1041,19 @@ S32 LLMessageSystem::sendReliable(	const LLHost &host,  void LLMessageSystem::forwardMessage(const LLHost &host)  { -	copyMessageRtoS(); +	copyMessageReceivedToSend();  	sendMessage(host);  }  void LLMessageSystem::forwardReliable(const LLHost &host)  { -	copyMessageRtoS(); +	copyMessageReceivedToSend();  	sendReliable(host);  }  void LLMessageSystem::forwardReliable(const U32 circuit_code)  { -	copyMessageRtoS(); +	copyMessageReceivedToSend();  	sendReliable(findHost(circuit_code));  } @@ -1135,7 +1064,7 @@ S32 LLMessageSystem::forwardReliable(	const LLHost &host,  										void (*callback)(void **,S32),   										void ** callback_data)  { -	copyMessageRtoS(); +	copyMessageReceivedToSend();  	return sendReliable(host, retries, ping_based_timeout, timeout, callback, callback_data);  } @@ -1463,13 +1392,6 @@ S32 LLMessageSystem::sendMessage(  		LL_WARNS("Messaging") << "trying to send message to invalid host"	<< llendl;  		return 0;  	} -	newMessage(name);	 -	if (mMessageBuilder != mLLSDMessageBuilder) -	{ -		LL_WARNS("Messaging") << "trying to send llsd message when builder is not LLSD!" -				<< llendl; -		return 0; -	}  	const LLHTTPSender& sender = LLHTTPSender::getSender(host);  	sender.send(host, name, message, createResponder(name)); @@ -2178,6 +2100,15 @@ void LLMessageSystem::dispatch(  	handler->post(responsep, context, message);  } +//static  +void LLMessageSystem::dispatchTemplate(const std::string& msg_name, +										const LLSD& message, +										LLHTTPNode::ResponsePtr responsep) +{ +	LLTemplateMessageDispatcher dispatcher(*(gMessageSystem->mTemplateMessageReader)); +	dispatcher.dispatch(msg_name, message, responsep); +} +  static void check_for_unrecognized_messages(  		const char* type,  		const LLSD& map, @@ -2730,7 +2661,7 @@ void LLMessageSystem::summarizeLogs(std::ostream& str)  	str << "END MESSAGE LOG SUMMARY" << std::endl;  } -void end_messaging_system() +void end_messaging_system(bool print_summary)  {  	gTransferManager.cleanup();  	LLTransferTargetVFile::updateQueue(true); // shutdown LLTransferTargetVFile @@ -2738,9 +2669,12 @@ void end_messaging_system()  	{  		gMessageSystem->stopLogging(); -		std::ostringstream str; -		gMessageSystem->summarizeLogs(str); -		LL_INFOS("Messaging") << str.str().c_str() << llendl; +		if (print_summary) +		{ +			std::ostringstream str; +			gMessageSystem->summarizeLogs(str); +			LL_INFOS("Messaging") << str.str().c_str() << llendl; +		}  		delete gMessageSystem;  		gMessageSystem = NULL; @@ -4088,3 +4022,11 @@ void LLMessageSystem::banUdpMessage(const std::string& name)  		llwarns << "Attempted to ban an unknown message: " << name << "." << llendl;  	}  } +const LLHost& LLMessageSystem::getSender() const +{ +	return mLastSender; +} + +LLHTTPRegistration<LLHTTPNodeAdapter<LLTrustedMessageService> > +	gHTTPRegistrationTrustedMessageWildcard("/trusted-message/<message-name>"); + diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h index 25eeb85323..4fda8f01d7 100644 --- a/indra/llmessage/message.h +++ b/indra/llmessage/message.h @@ -63,6 +63,9 @@  #include "llstl.h"  #include "llmsgvariabletype.h"  #include "llmsgvariabletype.h" +#include "llmessagesenderinterface.h" + +#include "llstoredmessage.h"  const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;  const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192; @@ -206,7 +209,7 @@ public:  	virtual void complete(const LLHost& host, const LLUUID& agent) const = 0;  }; -class LLMessageSystem +class LLMessageSystem : public LLMessageSenderInterface  {   private:  	U8					mSendBuffer[MAX_BUFFER_SIZE]; @@ -373,14 +376,33 @@ public:  	void newMessageFast(const char *name);  	void newMessage(const char *name); -	void	copyMessageRtoS(); -	void	clearMessage(); + +public: +	LLStoredMessagePtr getReceivedMessage() const;  +	LLStoredMessagePtr getBuiltMessage() const; +	S32 sendMessage(const LLHost &host, LLStoredMessagePtr message); + +private: +	LLSD getReceivedMessageLLSD() const; +	LLSD getBuiltMessageLLSD() const; + +	// NOTE: babbage: Only use to support legacy misuse of the +	// LLMessageSystem API where values are dangerously written +	// as one type and read as another. LLSD does not support +	// dangerous conversions and so converting the message to an +	// LLSD would result in the reads failing. All code which +	// misuses the message system in this way should be made safe +	// but while the unsafe code is run in old processes, this +	// method should be used to forward unsafe messages. +	LLSD wrapReceivedTemplateData() const; + +public: + +	void copyMessageReceivedToSend(); +	void clearMessage();  	void nextBlockFast(const char *blockname); -	void	nextBlock(const char *blockname) -	{ -		nextBlockFast(LLMessageStringTable::getInstance()->getString(blockname)); -	} +	void nextBlock(const char *blockname);  public:  	void addBinaryDataFast(const char *varname, const void *data, S32 size); @@ -461,14 +483,14 @@ public:  							void (*callback)(void **,S32), void ** callback_data);  	// flush sends a message only if data's been pushed on it. -	S32		flushSemiReliable(	const LLHost &host,  +	S32	 flushSemiReliable(	const LLHost &host,   								void (*callback)(void **,S32), void ** callback_data); -	S32		flushReliable(	const LLHost &host ); +	S32	flushReliable(	const LLHost &host ); -	void    forwardMessage(const LLHost &host); -	void    forwardReliable(const LLHost &host); -	void    forwardReliable(const U32 circuit_code); +	void forwardMessage(const LLHost &host); +	void forwardReliable(const LLHost &host); +	void forwardReliable(const U32 circuit_code);  	S32 forwardReliable(  		const LLHost &host,   		S32 retries,  @@ -480,9 +502,10 @@ public:  	LLHTTPClient::ResponderPtr createResponder(const std::string& name);  	S32		sendMessage(const LLHost &host);  	S32		sendMessage(const U32 circuit); +private:  	S32		sendMessage(const LLHost &host, const char* name,  						const LLSD& message); - +public:  	// 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); @@ -561,8 +584,12 @@ public:  	void	sendDenyTrustedCircuit(const LLHost &host);  	/** Return false if host is unknown or untrusted */ +	// Note:DaveH/Babbage some trusted messages can be received without a circuit  	bool isTrustedSender(const LLHost& host) const; +	/** Return true if current message is from trusted source */ +	bool isTrustedSender() const; +  	/** Return false true if name is unknown or untrusted */  	bool isTrustedMessage(const std::string& name) const; @@ -578,6 +605,7 @@ public:  	// Change this message to be UDP black listed.  	void banUdpMessage(const std::string& name); +  private:  	// A list of the circuits that need to be sent DenyTrustedCircuit messages.  	typedef std::set<LLHost> host_set_t; @@ -594,6 +622,7 @@ public:  	void	establishBidirectionalTrust(const LLHost &host, S64 frame_count = 0);  	// returns whether the given host is on a trusted circuit +	// Note:DaveH/Babbage some trusted messages can be received without a circuit  	BOOL    getCircuitTrust(const LLHost &host);  	void	setCircuitAllowTimeout(const LLHost &host, BOOL allow); @@ -663,6 +692,12 @@ public:  						 const LLSD& message,  						 LLHTTPNode::ResponsePtr responsep); +	// this is added to support specific legacy messages and is +	// ***not intended for general use*** Si, Gabriel, 2009 +	static void dispatchTemplate(const std::string& msg_name, +						 const LLSD& message, +						 LLHTTPNode::ResponsePtr responsep); +  	void setMessageBans(const LLSD& trusted, const LLSD& untrusted);  	/** @@ -690,9 +725,18 @@ public:  	// Check UDP messages and pump http_pump to receive HTTP messages.  	bool checkAllMessages(S64 frame_count, LLPumpIO* http_pump); + +	// Moved to allow access from LLTemplateMessageDispatcher +	void clearReceiveState(); + +	// This will cause all trust queries to return true until the next message +	// is read: use with caution! +	void receivedMessageFromTrustedSender();  private: +	bool mLastMessageFromTrustedMessageService; +	  	// The mCircuitCodes is a map from circuit codes to session  	// ids. This allows us to verify sessions on connect.  	typedef std::map<U32, LLUUID> code_session_map_t; @@ -703,7 +747,6 @@ private:  	LLUUID mSessionID;  	void	addTemplate(LLMessageTemplate *templatep); -	void		clearReceiveState();  	BOOL		decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );  	void		logMsgFromInvalidCircuit( const LLHost& sender, BOOL recv_reliable ); @@ -799,7 +842,7 @@ bool start_messaging_system(  	const F32 circuit_heartbeat_interval,   	const F32 circuit_timeout); -void end_messaging_system(); +void end_messaging_system(bool print_summary = true);  void null_message_callback(LLMessageSystem *msg, void **data); @@ -976,8 +1019,6 @@ inline void *ntohmemcpy(void *s, const void *ct, EMsgVariableType type, size_t n  	return(htonmemcpy(s,ct,type, n));  } - -inline const LLHost& LLMessageSystem::getSender() const {return mLastSender;}  inline const LLHost& LLMessageSystem::getReceivingInterface() const {return mLastReceivingIF;}  inline U32 LLMessageSystem::getSenderIP() const  diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp index 8cbd9f63f1..f63faa511a 100644 --- a/indra/llmessage/net.cpp +++ b/indra/llmessage/net.cpp @@ -51,7 +51,6 @@  #endif  // linden library includes -#include "network.h"  #include "llerror.h"  #include "llhost.h"  #include "lltimer.h" @@ -395,11 +394,30 @@ S32 start_net(S32& socket_out, int& nPort)  		return 1;  	} -	// Don't bind() if we want the operating system to assign our ports for  -	// us.  	if (NET_USE_OS_ASSIGNED_PORT == nPort)  	{ -		// Do nothing; the operating system will do it for us. +		// Although bind is not required it will tell us which port we were +		// assigned to. +		stLclAddr.sin_family      = AF_INET; +		stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); +		stLclAddr.sin_port        = htons(0); +		llinfos << "attempting to connect on OS assigned port" << llendl; +		nRet = bind(hSocket, (struct sockaddr*) &stLclAddr, sizeof(stLclAddr)); +		if (nRet < 0) +		{ +			llwarns << "Failed to bind on an OS assigned port error: " +					<< nRet << llendl; +		} +		else +		{ +			sockaddr_in socket_info; +			socklen_t len = sizeof(sockaddr_in); +			int err = getsockname(hSocket, (sockaddr*)&socket_info, &len); +			llinfos << "Get socket returned: " << err << " length " << len << llendl; +			nPort = ntohs(socket_info.sin_port); +			llinfos << "Assigned port: " << nPort << llendl; +			 +		}  	}  	else  	{ diff --git a/indra/llmessage/tests/llcurl_stub.cpp b/indra/llmessage/tests/llcurl_stub.cpp new file mode 100644 index 0000000000..9d1d3fa221 --- /dev/null +++ b/indra/llmessage/tests/llcurl_stub.cpp @@ -0,0 +1,88 @@ +/** + * @file llcurl_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2008&license=internal$ + * + * Copyright (c) 2008, Linden Research, Inc. + * + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") { } + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +LLCurl::Responder::Responder() +{ +} + +void LLCurl::Responder::completed(U32 status, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const &reason, +								  LLSD const& mContent) +{ +	if (isGoodStatus(status)) +	{ +		result(mContent); +	} +	else +	{ +		error(status, reason, mContent); +	} +} + +void LLCurl::Responder::completedHeader(unsigned, +										std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, +										LLSD const&) +{ +} + +void LLCurl::Responder::completedRaw(unsigned, +									 std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, +									 LLChannelDescriptors const&, +									 boost::shared_ptr<LLBufferArray> const&) +{ +} + +void LLCurl::Responder::error(unsigned, +							  std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, +							  LLSD const&) +{ +} + +LLCurl::Responder::~Responder () +{ +} + +void LLCurl::Responder::error(unsigned, +							  std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) +{ +} + +void LLCurl::Responder::result(LLSD const&) +{ +} + +namespace boost +{ +	void intrusive_ptr_add_ref(LLCurl::Responder* p) +	{ +		++p->mReferenceCount; +	} + +	void intrusive_ptr_release(LLCurl::Responder* p) +	{ +		if(p && 0 == --p->mReferenceCount) +		{ +			delete p; +		} +	} +}; + diff --git a/indra/llmessage/tests/llhttpclientadapter_test.cpp b/indra/llmessage/tests/llhttpclientadapter_test.cpp new file mode 100644 index 0000000000..bde76db08b --- /dev/null +++ b/indra/llmessage/tests/llhttpclientadapter_test.cpp @@ -0,0 +1,169 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + *  + * Copyright (c) 2001-2008, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llhttpclientadapter.h" + +#include "../test/lltut.h" +#include "llhttpclient.h" +#include "llcurl_stub.cpp" + +float const HTTP_REQUEST_EXPIRY_SECS = 1.0F; + +std::vector<std::string> get_urls; +std::vector<boost::intrusive_ptr<LLCurl::Responder> > get_responders; +void LLHTTPClient::get(const std::string& url, boost::intrusive_ptr<LLCurl::Responder> responder, const LLSD& headers, const F32 timeout) +{ +	get_urls.push_back(url); +	get_responders.push_back(responder); +} + +std::vector<std::string> put_urls; +std::vector<LLSD> put_body; +std::vector<boost::intrusive_ptr<LLCurl::Responder> > put_responders; + +void LLHTTPClient::put(std::string const &url, LLSD const &body, boost::intrusive_ptr<LLCurl::Responder> responder,float)  +{ +	put_urls.push_back(url); +	put_responders.push_back(responder); +	put_body.push_back(body); + +} + + +namespace tut +{ +	struct LLHTTPClientAdapterData +	{ +		LLHTTPClientAdapterData() +		{ +			get_urls.clear(); +			get_responders.clear(); +			put_urls.clear(); +			put_responders.clear(); +			put_body.clear(); +		} +	}; + +	typedef test_group<LLHTTPClientAdapterData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory tf("LLHTTPClientAdapterData test"); +} + +namespace tut +{ +	// Ensure we can create the object +	template<> template<> +	void object::test<1>() +	{ +		LLHTTPClientAdapter adapter; +	} + +	// Does the get pass the appropriate arguments to the LLHTTPClient +	template<> template<> +	void object::test<2>() +	{ +		LLHTTPClientAdapter adapter; + +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		adapter.get("Made up URL", responder); +		ensure_equals(get_urls.size(), 1); +		ensure_equals(get_urls[0], "Made up URL"); +	} + +	// Ensure the responder matches the one passed to get +	template<> template<> +	void object::test<3>() +	{ +		LLHTTPClientAdapter adapter; +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		adapter.get("Made up URL", responder); + +		ensure_equals(get_responders.size(), 1); +		ensure_equals(get_responders[0].get(), responder.get()); +	} +	 +	// Ensure the correct url is used in the put +	template<> template<> +	void object::test<4>() +	{ +		LLHTTPClientAdapter adapter; + +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		LLSD body; +		body["TestBody"] = "Foobar"; + +		adapter.put("Made up URL", body, responder); +		ensure_equals(put_urls.size(), 1); +		ensure_equals(put_urls[0], "Made up URL"); +	} + +	// Ensure the correct responder is used by put +	template<> template<> +	void object::test<5>() +	{ +		LLHTTPClientAdapter adapter; + +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		LLSD body; +		body["TestBody"] = "Foobar"; + +		adapter.put("Made up URL", body, responder); + +		ensure_equals(put_responders.size(), 1); +		ensure_equals(put_responders[0].get(), responder.get()); +	} + +	// Ensure the message body is passed through the put properly +	template<> template<> +	void object::test<6>() +	{ +		LLHTTPClientAdapter adapter; + +		boost::intrusive_ptr<LLCurl::Responder> responder = new LLCurl::Responder(); + +		LLSD body; +		body["TestBody"] = "Foobar"; + +		adapter.put("Made up URL", body, responder); + +		ensure_equals(put_body.size(), 1); +		ensure_equals(put_body[0]["TestBody"].asString(), "Foobar"); +	} +} + diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp new file mode 100644 index 0000000000..a6f5659352 --- /dev/null +++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp @@ -0,0 +1,164 @@ +/** + * @file lltrustedmessageservice_test.cpp + * @brief LLTrustedMessageService unit tests + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "lltemplatemessagedispatcher.h" +#include "lltut.h" + +#include "llhttpnode.h" +#include "llhost.h" +#include "message.h" +#include "llsd.h" + +#include "llhost.cpp" // Needed for copy operator +#include "net.cpp" // Needed by LLHost. + +LLMessageSystem * gMessageSystem = NULL; + +// sensor test doubles +bool gClearRecvWasCalled = false; +void LLMessageSystem::clearReceiveState(void)  +{  +	gClearRecvWasCalled = true;  +} + +char gUdpDispatchedData[MAX_BUFFER_SIZE]; +bool gUdpDispatchWasCalled = false; +BOOL LLTemplateMessageReader::readMessage(const U8* data,class LLHost const &)  +{  +	gUdpDispatchWasCalled = true; +	strcpy(gUdpDispatchedData, reinterpret_cast<const char*>(data)); +	return  true; +} + +BOOL gValidateMessage = FALSE; +BOOL LLTemplateMessageReader::validateMessage(const U8*, S32 buffer_size, LLHost const &sender, bool trusted)  +{  +	return gValidateMessage; +} + +LLHost host; +const LLHost& LLMessageSystem::getSender() const  +{  +	return host;  +} + +const char* gBinaryTemplateData = "BINARYTEMPLATEDATA"; +void fillVector(std::vector<U8>& vector_data, const char* data) +{ +	vector_data.resize(strlen(data) + 1); +	strcpy(reinterpret_cast<char*>(&vector_data[0]), data); +} + +namespace tut +{ +		static LLTemplateMessageReader::message_template_number_map_t numberMap; + +		struct LLTemplateMessageDispatcherData +		{ +			LLTemplateMessageDispatcherData() +			{ +				mMessageName = "MessageName"; +				gUdpDispatchWasCalled = false; +				gClearRecvWasCalled = false; +				gValidateMessage = FALSE; +				mMessage["body"]["binary-template-data"] = std::vector<U8>(); +			} + +			LLSD mMessage; +			LLHTTPNode::ResponsePtr mResponsePtr; +			std::string mMessageName; +		}; + +	typedef test_group<LLTemplateMessageDispatcherData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory tf("LLTemplateMessageDispatcher test"); +} + +namespace tut +{ +	// does an empty message stop processing? +	template<> template<> +	void object::test<1>() +	{ +		LLTemplateMessageReader* pReader = NULL; +		LLTemplateMessageDispatcher t(*pReader); +		t.dispatch(mMessageName, mMessage, mResponsePtr); +		ensure(! gUdpDispatchWasCalled); +		ensure(! gClearRecvWasCalled); +	} + +	// does the disaptch invoke the udp send method? +	template<> template<> +	void object::test<2>() +	{ +		LLTemplateMessageReader* pReader = NULL; +		LLTemplateMessageDispatcher t(*pReader); +		gValidateMessage = TRUE; +		std::vector<U8> vector_data; +		fillVector(vector_data, gBinaryTemplateData);		 +		mMessage["body"]["binary-template-data"] = vector_data; +		t.dispatch(mMessageName, mMessage, mResponsePtr); +		ensure("udp dispatch was called", gUdpDispatchWasCalled); +	} + +	// what if the message wasn't valid? We would hope the message gets cleared! +	template<> template<> +	void object::test<3>() +	{ +		LLTemplateMessageReader* pReader = NULL; +		LLTemplateMessageDispatcher t(*pReader); +		std::vector<U8> vector_data; +		fillVector(vector_data, gBinaryTemplateData); +		mMessage["body"]["binary-template-data"] = vector_data; +		gValidateMessage = FALSE; +		t.dispatch(mMessageName, mMessage, mResponsePtr); +		ensure("clear received message was called", gClearRecvWasCalled); +	} + +	// is the binary data passed through correctly? +	template<> template<> +	void object::test<4>() +	{ +		LLTemplateMessageReader* pReader = NULL; +		LLTemplateMessageDispatcher t(*pReader); +		gValidateMessage = TRUE; +		std::vector<U8> vector_data; +		fillVector(vector_data, gBinaryTemplateData); +		mMessage["body"]["binary-template-data"] = vector_data; +		t.dispatch(mMessageName, mMessage, mResponsePtr); +		ensure("data couriered correctly", strcmp(gBinaryTemplateData, gUdpDispatchedData) == 0); +	} +} + diff --git a/indra/llmessage/tests/lltesthttpclientadapter.cpp b/indra/llmessage/tests/lltesthttpclientadapter.cpp new file mode 100644 index 0000000000..1140458918 --- /dev/null +++ b/indra/llmessage/tests/lltesthttpclientadapter.cpp @@ -0,0 +1,56 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=internal$ + *  + * Copyright (c) 2008, Linden Research, Inc. + *  + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "lltesthttpclientadapter.h" + +LLTestHTTPClientAdapter::LLTestHTTPClientAdapter() +{ +} + +LLTestHTTPClientAdapter::~LLTestHTTPClientAdapter() +{ +} + +void LLTestHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder) +{ +	mGetUrl.push_back(url); +	mGetResponder.push_back(responder); +} + +void LLTestHTTPClientAdapter::put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder) +{ +	mPutUrl.push_back(url); +	mPutBody.push_back(body); +	mPutResponder.push_back(responder); +} + +U32 LLTestHTTPClientAdapter::putCalls() const  +{  +	return mPutUrl.size();  +} + +void LLTestHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) +{ +	mGetUrl.push_back(url); +	mGetHeaders.push_back(headers); +	mGetResponder.push_back(responder); +} + + diff --git a/indra/llmessage/tests/lltesthttpclientadapter.h b/indra/llmessage/tests/lltesthttpclientadapter.h new file mode 100644 index 0000000000..d032503685 --- /dev/null +++ b/indra/llmessage/tests/lltesthttpclientadapter.h @@ -0,0 +1,52 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=internal$ + *  + * Copyright (c) 2008, Linden Research, Inc. + *  + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* Macro Definitions */ +#ifndef LL_LLTESTHTTPCLIENTADAPTER_H +#define LL_LLTESTHTTPCLIENTADAPTER_H + + +#include "linden_common.h" +#include "llhttpclientinterface.h" + +class LLTestHTTPClientAdapter : public LLHTTPClientInterface +{ +public: +	LLTestHTTPClientAdapter(); +	virtual ~LLTestHTTPClientAdapter(); +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder); +	virtual void get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers); + +	virtual void put(const std::string& url, const LLSD& body, LLCurl::ResponderPtr responder); +	U32 putCalls() const; + +	std::vector<LLSD> mPutBody; +	std::vector<LLSD> mGetHeaders; +	std::vector<std::string> mPutUrl; +	std::vector<std::string> mGetUrl; +	std::vector<LLCurl::ResponderPtr> mPutResponder; +	std::vector<LLCurl::ResponderPtr> mGetResponder; +}; + + + +#endif //LL_LLSIMULATORPRESENCESENDER_H + diff --git a/indra/llmessage/tests/lltestmessagesender.cpp b/indra/llmessage/tests/lltestmessagesender.cpp new file mode 100644 index 0000000000..a37aa4c566 --- /dev/null +++ b/indra/llmessage/tests/lltestmessagesender.cpp @@ -0,0 +1,33 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=internal$ + *  + * Copyright (c) 2008, Linden Research, Inc. + *  + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "lltestmessagesender.h" + +LLTestMessageSender::~LLTestMessageSender() +{ +} + + +S32 LLTestMessageSender::sendMessage(const LLHost& host, LLStoredMessagePtr message) +{ +	mSendHosts.push_back(host); +	mSendMessages.push_back(message); +	return 0; +} diff --git a/indra/llmessage/tests/lltestmessagesender.h b/indra/llmessage/tests/lltestmessagesender.h new file mode 100644 index 0000000000..83c0eff4d3 --- /dev/null +++ b/indra/llmessage/tests/lltestmessagesender.h @@ -0,0 +1,46 @@ +/**  + * @file  + * @brief  + * + * $LicenseInfo:firstyear=2008&license=internal$ + *  + * Copyright (c) 2008, Linden Research, Inc. + *  + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +/* Macro Definitions */ +#ifndef LL_LLTESTMESSAGESENDER_H +#define LL_LLTESTMESSAGESENDER_H + + +#include "linden_common.h" +#include "llmessagesenderinterface.h" +#include <vector> + + + +class LLTestMessageSender : public LLMessageSenderInterface +{ +public: +	virtual ~LLTestMessageSender(); +	virtual S32 sendMessage(const LLHost& host, LLStoredMessagePtr message); + +	std::vector<LLHost> mSendHosts; +	std::vector<LLStoredMessagePtr> mSendMessages; +}; + + + +#endif //LL_LLTESTMESSAGESENDER_H + diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp new file mode 100644 index 0000000000..44595391df --- /dev/null +++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp @@ -0,0 +1,145 @@ +/** + * @file lltrustedmessageservice_test.cpp + * @brief LLTrustedMessageService unit tests + * + * $LicenseInfo:firstyear=2009&license=viewergpl$ + * + * Copyright (c) 2001-2009, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "lltrustedmessageservice.h" +#include "../test/lltut.h" + +#include "llhost.cpp" // LLHost is a value type for test purposes. +#include "net.cpp" // Needed by LLHost. + +#include "message.h" +#include "llmessageconfig.h" + +LLMessageSystem* gMessageSystem = NULL; + +LLMessageConfig::SenderTrust +LLMessageConfig::getSenderTrustedness(const std::string& msg_name) +{ +	return LLMessageConfig::NOT_SET; +} + +void LLMessageSystem::receivedMessageFromTrustedSender() +{ +} + +bool LLMessageSystem::isTrustedSender(const LLHost& host) const +{ +	return false; +} + +bool LLMessageSystem::isTrustedMessage(const std::string& name) const +{ +	return false; +} + +bool messageDispatched = false; +bool messageDispatchedAsBinary = false; +LLSD lastLLSD; +std::string lastMessageName; + +void LLMessageSystem::dispatch(const std::string& msg_name, +							   const LLSD& message, +							   LLHTTPNode::ResponsePtr responsep) +{ +	messageDispatched = true; +	lastLLSD = message; +	lastMessageName = msg_name; +} + +void LLMessageSystem::dispatchTemplate(const std::string& msg_name, +						 const LLSD& message, +						 LLHTTPNode::ResponsePtr responsep) +{ +	lastLLSD = message; +	lastMessageName = msg_name; +	messageDispatchedAsBinary = true; +} + +namespace tut +{ +	    struct LLTrustedMessageServiceData +		{ +			LLTrustedMessageServiceData() +			{ +				LLSD emptyLLSD; +				lastLLSD = emptyLLSD; +				lastMessageName = "uninitialised message name"; +				messageDispatched = false; +				messageDispatchedAsBinary = false; +			} +		}; + +	typedef test_group<LLTrustedMessageServiceData> factory; +	typedef factory::object object; +} + +namespace +{ +	tut::factory tf("LLTrustedMessageServiceData test"); +} + +namespace tut +{ +	// characterisation tests + +	// 1) test that messages get forwarded with names etc. as current behaviour (something like LLMessageSystem::dispatch(name, data...) + +	// test llsd messages are sent as normal using LLMessageSystem::dispatch() (eventually) +	template<> template<> +	void object::test<1>() +	{ +		LLHTTPNode::ResponsePtr response; +		LLSD input; +		LLSD context; +		LLTrustedMessageService adapter; +		adapter.post(response, context, input); +		// test original ting got called wit nowt, ya get me blood? +		ensure_equals(messageDispatched, true); +		ensure(lastLLSD.has("body")); +	} + +	// test that llsd wrapped binary-template-data messages are  +	// sent via LLMessageSystem::binaryDispatch() or similar +	template<> template<> +	void object::test<2>() +	{ +		LLHTTPNode::ResponsePtr response; +		LLSD input; +		input["binary-template-data"] = "10001010110"; //make me a message here. +		LLSD context; +		LLTrustedMessageService adapter; + +		adapter.post(response, context, input); +		ensure("check template-binary-data message was dispatched as binary", messageDispatchedAsBinary); +		ensure_equals(lastLLSD["body"]["binary-template-data"].asString(),  "10001010110"); +		// test somit got called with "10001010110" (something like LLMessageSystem::dispatchTemplate(blah)) +	} +}  | 
