diff options
Diffstat (limited to 'indra')
54 files changed, 2792 insertions, 1062 deletions
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 610aa99dc9..0edacac7a9 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -181,7 +181,7 @@ endif (DARWIN) if (LINUX OR DARWIN) - set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs") + set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs -Wno-non-virtual-dtor") if (NOT GCC_DISABLE_FATAL_WARNINGS) set(GCC_WARNINGS "${GCC_WARNINGS} -Werror") diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 7cfdead32e..3557a99248 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -69,8 +69,13 @@ MACRO(ADD_SIMULATOR_BUILD_TEST name parent) ENDMACRO(ADD_SIMULATOR_BUILD_TEST name parent) MACRO(ADD_BUILD_TEST_INTERNAL name parent libraries source_files) - - ADD_EXECUTABLE(${name}_test ${source_files}) + SET(TEST_SOURCE_FILES ${source_files}) + SET(HEADER "${name}.h") + set_source_files_properties(${HEADER} + PROPERTIES HEADER_FILE_ONLY TRUE) + LIST(APPEND TEST_SOURCE_FILES ${HEADER}) + INCLUDE_DIRECTORIES("${LIBS_OPEN_DIR}/test") + ADD_EXECUTABLE(${name}_test ${TEST_SOURCE_FILES}) TARGET_LINK_LIBRARIES(${name}_test ${libraries} ) @@ -80,11 +85,11 @@ MACRO(ADD_BUILD_TEST_INTERNAL name parent libraries source_files) ADD_CUSTOM_COMMAND( OUTPUT ${TEST_OUTPUT} COMMAND ${TEST_EXE} - ARGS --touch=${TEST_OUTPUT} + ARGS --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${name}_test WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) ADD_CUSTOM_TARGET(${name}_test_ok ALL DEPENDS ${TEST_OUTPUT}) ADD_DEPENDENCIES(${parent} ${name}_test_ok) -ENDMACRO(ADD_BUILD_TEST_INTERNAL name parent libraries)
\ No newline at end of file +ENDMACRO(ADD_BUILD_TEST_INTERNAL name parent libraries) diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index f1094a8fd2..4109eade19 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -118,6 +118,7 @@ const char* const DEFAULT_AGNI_DATA_SERVER = "63.211.139.100"; const char* const DEFAULT_AGNI_ASSET_SERVER = "http://asset.agni.lindenlab.com:80"; // Information about what ports are for what services is in the wiki Name Space Ports page +// https://wiki.lindenlab.com/wiki/Name_Space_Ports const char* const DEFAULT_LOCAL_ASSET_SERVER = "http://localhost:12041/asset/tmp"; const char* const LOCAL_ASSET_URL_FORMAT = "http://%s:12041/asset"; @@ -138,6 +139,10 @@ const U32 DEFAULT_CAP_PROXY_PORT = 12043; const U32 DEFAULT_INV_DATA_SERVER_PORT = 12044; const U32 DEFAULT_CGI_SERVICES_PORT = 12045; +// Mapserver uses ports 12124 - 12139 to allow multiple mapservers to run +// on a single host for map tile generation. JC +const U32 DEFAULT_MAPSERVER_PORT = 12124; + // For automatic port discovery when running multiple viewers on one host const U32 PORT_DISCOVERY_RANGE_MIN = 13000; const U32 PORT_DISCOVERY_RANGE_MAX = PORT_DISCOVERY_RANGE_MIN + 50; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index 1a1dbd40b6..8915890e18 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -33,6 +33,8 @@ #ifndef LL_LLSTRING_H #define LL_LLSTRING_H +#include <string> + #if LL_LINUX || LL_SOLARIS #include <wctype.h> #include <wchar.h> diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index f68d86ff7c..2e93b2a3a7 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -300,19 +300,22 @@ U32 LLOSInfo::getProcessVirtualSizeKB() #endif #if LL_LINUX LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb"); - S32 numRead = 0; - char buff[STATUS_SIZE]; /* Flawfinder: ignore */ + if (status_filep) + { + S32 numRead = 0; + char buff[STATUS_SIZE]; /* Flawfinder: ignore */ - size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); - buff[nbytes] = '\0'; + size_t nbytes = fread(buff, 1, STATUS_SIZE-1, status_filep); + buff[nbytes] = '\0'; - // All these guys return numbers in KB - char *memp = strstr(buff, "VmSize:"); - if (memp) - { - numRead += sscanf(memp, "%*s %u", &virtual_size); + // All these guys return numbers in KB + char *memp = strstr(buff, "VmSize:"); + if (memp) + { + numRead += sscanf(memp, "%*s %u", &virtual_size); + } + fclose(status_filep); } - fclose(status_filep); #elif LL_SOLARIS char proc_ps[LL_MAX_PATH]; sprintf(proc_ps, "/proc/%d/psinfo", (int)getpid()); diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index 7593eeae37..f9b84dd6bd 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -36,7 +36,7 @@ const S32 LL_VERSION_MAJOR = 1; const S32 LL_VERSION_MINOR = 27; const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 109809; +const S32 LL_VERSION_BUILD = 112940; const char * const LL_CHANNEL = "Second Life Server"; diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 37c276096e..be6b6c817b 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -58,26 +58,42 @@ void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl) impl = NULL; } +// Return string from message, eliminating final \n if present +static std::string chomp(const char* msg) +{ + // stomp trailing \n + std::string message = msg; + if (!message.empty()) + { + size_t last = message.size() - 1; + if (message[last] == '\n') + { + message.resize( last ); + } + } + return message; +} + /** sample error callback expecting a LLFILE* client object */ void error_callback(const char* msg, void*) { - lldebugs << "LLImageJ2CImpl error_callback: " << msg << llendl; + lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl; } /** sample warning callback expecting a LLFILE* client object */ void warning_callback(const char* msg, void*) { - lldebugs << "LLImageJ2CImpl warning_callback: " << msg << llendl; + lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl; } /** sample debug callback expecting no client object */ void info_callback(const char* msg, void*) { - lldebugs << "LLImageJ2CImpl info_callback: " << msg << llendl; + lldebugs << "LLImageJ2COJ: " << chomp(msg) << llendl; } diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 6fa5c9076e..2689ada80c 100644 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -110,37 +110,11 @@ static const std::string PARCEL_ACTION_STRING[LLParcel::A_COUNT + 1] = "unknown" }; -// Timeouts for parcels -// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000 -const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000); -// ***** TESTING is 10 minutes -//const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000); -// group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000 -const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000); -// ***** TESTING is 10 minutes -//const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000); -// default sale timeout is 2 days -> 172800000000 -const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000); -// ***** TESTING is 10 minutes -//const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000); - -// more grace period extensions. -const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000); - -// if more than 100,000s before sale revert, and no extra extension -// has been given, go ahead and extend it more. That's about 1.2 days. -const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; - - -const std::string& ownership_status_to_string(LLParcel::EOwnershipStatus status); -LLParcel::EOwnershipStatus ownership_string_to_status(const std::string& s); //const char* revert_action_to_string(LLParcel::ESaleTimerExpireAction action); //LLParcel::ESaleTimerExpireAction revert_string_to_action(const char* s); -const std::string& category_to_string(LLParcel::ECategory category); const std::string& category_to_ui_string(LLParcel::ECategory category); -LLParcel::ECategory category_string_to_category(const std::string& s); LLParcel::ECategory category_ui_string_to_category(const std::string& s); LLParcel::LLParcel() @@ -548,500 +522,6 @@ void LLParcel::setDiscountRate(F32 rate) // File input and output //----------------------------------------------------------- - -// WARNING: Area will be wrong until you calculate it. -BOOL LLParcel::importStream(std::istream& input_stream) -{ - U32 setting; - S32 secs_until_revert = 0; - - skip_to_end_of_next_keyword("{", input_stream); - if (!input_stream.good()) - { - llwarns << "LLParcel::importStream() - bad input_stream" << llendl; - return FALSE; - } - - while (input_stream.good()) - { - skip_comments_and_emptyspace(input_stream); - std::string line, keyword, value; - get_line(line, input_stream, MAX_STRING); - get_keyword_and_value(keyword, value, line); - - if ("}" == keyword) - { - break; - } - else if ("parcel_id" == keyword) - { - mID.set(value); - } - else if ("status" == keyword) - { - mStatus = ownership_string_to_status(value); - } - else if ("category" == keyword) - { - mCategory = category_string_to_category(value); - } - else if ("local_id" == keyword) - { - LLStringUtil::convertToS32(value, mLocalID); - } - else if ("name" == keyword) - { - setName( value ); - } - else if ("desc" == keyword) - { - setDesc( value ); - } - else if ("music_url" == keyword) - { - setMusicURL( value ); - } - else if ("media_url" == keyword) - { - setMediaURL( value ); - } - else if ("media_desc" == keyword) - { - setMediaDesc( value ); - } - else if ("media_type" == keyword) - { - setMediaType( value ); - } - else if ("media_width" == keyword) - { - S32 width; - LLStringUtil::convertToS32(value, width); - setMediaWidth( width ); - } - else if ("media_height" == keyword) - { - S32 height; - LLStringUtil::convertToS32(value, height); - setMediaHeight( height ); - } - else if ("media_id" == keyword) - { - mMediaID.set( value ); - } - else if ("media_auto_scale" == keyword) - { - LLStringUtil::convertToU8(value, mMediaAutoScale); - } - else if ("media_loop" == keyword) - { - LLStringUtil::convertToU8(value, mMediaLoop); - } - else if ("obscure_media" == keyword) - { - LLStringUtil::convertToU8(value, mObscureMedia); - } - else if ("obscure_music" == keyword) - { - LLStringUtil::convertToU8(value, mObscureMusic); - } - else if ("owner_id" == keyword) - { - mOwnerID.set( value ); - } - else if ("group_owned" == keyword) - { - LLStringUtil::convertToBOOL(value, mGroupOwned); - } - else if ("clean_other_time" == keyword) - { - S32 time; - LLStringUtil::convertToS32(value, time); - setCleanOtherTime(time); - } - else if ("auth_buyer_id" == keyword) - { - mAuthBuyerID.set(value); - } - else if ("snapshot_id" == keyword) - { - mSnapshotID.set(value); - } - else if ("user_location" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mUserLocation.mV[VX], - &mUserLocation.mV[VY], - &mUserLocation.mV[VZ]); - } - else if ("user_look_at" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mUserLookAt.mV[VX], - &mUserLookAt.mV[VY], - &mUserLookAt.mV[VZ]); - } - else if ("landing_type" == keyword) - { - S32 landing_type = 0; - LLStringUtil::convertToS32(value, landing_type); - mLandingType = (ELandingType) landing_type; - } - else if ("join_neighbors" == keyword) - { - llinfos << "found deprecated keyword join_neighbors" << llendl; - } - else if ("revert_sale" == keyword) - { - LLStringUtil::convertToS32(value, secs_until_revert); - if (secs_until_revert > 0) - { - mSaleTimerExpires.start(); - mSaleTimerExpires.setTimerExpirySec((F32)secs_until_revert); - } - } - else if("extended_grace" == keyword) - { - LLStringUtil::convertToS32(value, mGraceExtension); - } - else if ("user_list_type" == keyword) - { - // deprecated - } - else if("auction_id" == keyword) - { - LLStringUtil::convertToU32(value, mAuctionID); - } - else if ("allow_modify" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_CREATE_OBJECTS, setting); - } - else if ("allow_group_modify" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_CREATE_GROUP_OBJECTS, setting); - } - else if ("allow_all_object_entry" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_ALL_OBJECT_ENTRY, setting); - } - else if ("allow_group_object_entry" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_GROUP_OBJECT_ENTRY, setting); - } - else if ("allow_deed_to_group" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_DEED_TO_GROUP, setting); - } - else if("contribute_with_deed" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_CONTRIBUTE_WITH_DEED, setting); - } - else if ("allow_terraform" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_TERRAFORM, setting); - } - else if ("allow_damage" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_DAMAGE, setting); - } - else if ("allow_fly" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_FLY, setting); - } - else if ("allow_landmark" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_LANDMARK, setting); - } - else if ("sound_local" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_SOUND_LOCAL, setting); - } - else if ("allow_group_scripts" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, setting); - } - else if ("allow_voice_chat" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_VOICE_CHAT, setting); - } - else if ("use_estate_voice_chan" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_USE_ESTATE_VOICE_CHAN, setting); - } - else if ("allow_scripts" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, setting); - } - else if ("for_sale" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_FOR_SALE, setting); - } - else if ("sell_w_objects" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_SELL_PARCEL_OBJECTS, setting); - } - else if ("use_pass_list" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_USE_PASS_LIST, setting); - } - else if ("show_directory" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_SHOW_DIRECTORY, setting); - } - else if ("allow_publish" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_ALLOW_PUBLISH, setting); - } - else if ("mature_publish" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_MATURE_PUBLISH, setting); - } - else if ("claim_date" == keyword) - { - // BUG: This will fail when time rolls over in 2038. - S32 time; - LLStringUtil::convertToS32(value, time); - mClaimDate = time; - } - else if ("claim_price" == keyword) - { - LLStringUtil::convertToS32(value, mClaimPricePerMeter); - } - else if ("rent_price" == keyword) - { - LLStringUtil::convertToS32(value, mRentPricePerMeter); - } - else if ("discount_rate" == keyword) - { - LLStringUtil::convertToF32(value, mDiscountRate); - } - else if ("draw_distance" == keyword) - { - LLStringUtil::convertToF32(value, mDrawDistance); - } - else if ("sale_price" == keyword) - { - LLStringUtil::convertToS32(value, mSalePrice); - } - else if ("pass_price" == keyword) - { - LLStringUtil::convertToS32(value, mPassPrice); - } - else if ("pass_hours" == keyword) - { - LLStringUtil::convertToF32(value, mPassHours); - } - else if ("box" == keyword) - { - // deprecated - } - else if ("aabb_min" == keyword) - { - sscanf(value.c_str(), "%f %f %f", - &mAABBMin.mV[VX], &mAABBMin.mV[VY], &mAABBMin.mV[VZ]); - } - else if ("use_access_group" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_USE_ACCESS_GROUP, setting); - } - else if ("use_access_list" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_USE_ACCESS_LIST, setting); - } - else if ("use_ban_list" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_USE_BAN_LIST, setting); - } - else if ("group_name" == keyword) - { - llinfos << "found deprecated keyword group_name" << llendl; - } - else if ("group_id" == keyword) - { - mGroupID.set( value ); - } - // TODO: DEPRECATED FLAG - // Flag removed from simstate files in 1.11.1 - // Remove at some point where we have guarenteed this flag - // no longer exists anywhere in simstate files. - else if ("require_identified" == keyword) - { - // LLStringUtil::convertToU32(value, setting); - // setParcelFlag(PF_DENY_ANONYMOUS, setting); - } - // TODO: DEPRECATED FLAG - // Flag removed from simstate files in 1.11.1 - // Remove at some point where we have guarenteed this flag - // no longer exists anywhere in simstate files. - else if ("require_transacted" == keyword) - { - // LLStringUtil::convertToU32(value, setting); - // setParcelFlag(PF_DENY_ANONYMOUS, setting); - // setParcelFlag(PF_DENY_IDENTIFIED, setting); - } - else if ("restrict_pushobject" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_RESTRICT_PUSHOBJECT, setting); - } - else if ("deny_anonymous" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_DENY_ANONYMOUS, setting); - } - else if ("deny_identified" == keyword) - { -// LLStringUtil::convertToU32(value, setting); -// setParcelFlag(PF_DENY_IDENTIFIED, setting); - } - else if ("deny_transacted" == keyword) - { -// LLStringUtil::convertToU32(value, setting); -// setParcelFlag(PF_DENY_TRANSACTED, setting); - } - else if ("deny_age_unverified" == keyword) - { - LLStringUtil::convertToU32(value, setting); - setParcelFlag(PF_DENY_AGEUNVERIFIED, setting); - } - else if ("access_list" == keyword) - { - S32 entry_count = 0; - LLStringUtil::convertToS32(value, entry_count); - for (S32 i = 0; i < entry_count; i++) - { - LLAccessEntry entry; - if (importAccessEntry(input_stream, &entry)) - { - mAccessList[entry.mID] = entry; - } - } - } - else if ("ban_list" == keyword) - { - S32 entry_count = 0; - LLStringUtil::convertToS32(value, entry_count); - for (S32 i = 0; i < entry_count; i++) - { - LLAccessEntry entry; - if (importAccessEntry(input_stream, &entry)) - { - mBanList[entry.mID] = entry; - } - } - } - else if ("renter_list" == keyword) - { - /* - S32 entry_count = 0; - LLStringUtil::convertToS32(value, entry_count); - for (S32 i = 0; i < entry_count; i++) - { - LLAccessEntry entry; - if (importAccessEntry(input_stream, &entry)) - { - mRenterList.put(entry); - } - }*/ - } - else if ("pass_list" == keyword) - { - // legacy - put into access list - S32 entry_count = 0; - LLStringUtil::convertToS32(value, entry_count); - for (S32 i = 0; i < entry_count; i++) - { - LLAccessEntry entry; - if (importAccessEntry(input_stream, &entry)) - { - mAccessList[entry.mID] = entry; - } - } - } - - else - { - llwarns << "Unknown keyword in parcel section: <" - << keyword << ">" << llendl; - } - } - - // this code block detects if we have loaded a 1.1 simstate file, - // and follows the conversion rules specified in - // design_docs/land/pay_for_parcel.txt. - F32 time_to_expire = 0.0f; - if(mID.isNull()) - { - mID.generate(); - mStatus = OS_LEASE_PENDING; - //mBuyerID = mOwnerID; - if(getIsGroupOwned()) - { - time_to_expire += GROUP_USEC_CONVERSION_TIMEOUT / SEC_TO_MICROSEC; - } - else - { - time_to_expire += DEFAULT_USEC_CONVERSION_TIMEOUT / SEC_TO_MICROSEC; - } - //mExpireAction = STEA_PUBLIC; - mRecordTransaction = TRUE; - } - - // this code block deals with giving an extension to pending - // parcels to the midday of 2004-01-19 if they were originally set - // for some time on 2004-01-12. - if((0 == mGraceExtension) - && (EXTEND_GRACE_IF_MORE_THAN_SEC < secs_until_revert)) - { - const S32 NEW_CONVERSION_DATE = 1074538800; // 2004-01-19T11:00:00 - time_t now = time(NULL); // now in epoch - secs_until_revert = (S32)(NEW_CONVERSION_DATE - now); - time_to_expire = (F32)secs_until_revert; - mGraceExtension = 1; - } - - // This code block adds yet another week to the deadline. :( - if(1 == mGraceExtension) - { - time_to_expire += SEVEN_DAYS_IN_USEC / SEC_TO_MICROSEC; - mGraceExtension = 2; - } - - if (time_to_expire > 0) - { - mSaleTimerExpires.setTimerExpirySec(time_to_expire); - mSaleTimerExpires.start(); - } - - // successful import - return TRUE; -} - - BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entry) { skip_to_end_of_next_keyword("{", input_stream); @@ -1085,230 +565,6 @@ BOOL LLParcel::importAccessEntry(std::istream& input_stream, LLAccessEntry* entr return input_stream.good(); } -BOOL LLParcel::exportStream(std::ostream& output_stream) -{ - S32 setting; - std::string id_string; - - std::ios::fmtflags old_flags = output_stream.flags(); - output_stream.setf(std::ios::showpoint); - output_stream << "\t{\n"; - - mID.toString(id_string); - output_stream << "\t\t parcel_id " << id_string << "\n"; - output_stream << "\t\t status " << ownership_status_to_string(mStatus) << "\n"; - output_stream << "\t\t category " << category_to_string(mCategory) << "\n"; - - output_stream << "\t\t local_id " << mLocalID << "\n"; - - const char* name = (mName.empty() ? "" : mName.c_str() ); - output_stream << "\t\t name " << name << "\n"; - - const char* desc = (mDesc.empty() ? "" : mDesc.c_str() ); - output_stream << "\t\t desc " << desc << "\n"; - - const char* music_url = (mMusicURL.empty() ? "" : mMusicURL.c_str() ); - output_stream << "\t\t music_url " << music_url << "\n"; - - const char* media_url = (mMediaURL.empty() ? "" : mMediaURL.c_str() ); - output_stream << "\t\t media_url " << media_url << "\n"; - - const char* media_type = (mMediaType.empty() ? "" : mMediaType.c_str() ); - output_stream << "\t\t media_type " << media_type << "\n"; - - const char* media_desc = (mMediaDesc.empty() ? "" : mMediaDesc.c_str() ); - output_stream << "\t\t media_desc " << media_desc << "\n"; - - output_stream << "\t\t media_auto_scale " << (mMediaAutoScale ? 1 : 0) << "\n"; - output_stream << "\t\t media_loop " << (mMediaLoop ? 1 : 0) << "\n"; - output_stream << "\t\t obscure_media " << (mObscureMedia ? 1 : 0) << "\n"; - output_stream << "\t\t obscure_music " << (mObscureMusic ? 1 : 0) << "\n"; - - mMediaID.toString(id_string); - output_stream << "\t\t media_id " << id_string << "\n"; - - output_stream << "\t\t media_width " << mMediaWidth << "\n"; - output_stream << "\t\t media_height " << mMediaHeight << "\n"; - - mOwnerID.toString(id_string); - output_stream << "\t\t owner_id " << id_string << "\n"; - output_stream << "\t\t group_owned " << (mGroupOwned ? 1 : 0) << "\n"; - output_stream << "\t\t clean_other_time " << getCleanOtherTime() << "\n"; - - if(!mAuthBuyerID.isNull()) - { - mAuthBuyerID.toString(id_string); - output_stream << "\t\t auth_buyer_id " << id_string << "\n"; - } - if (!mSnapshotID.isNull()) - { - mSnapshotID.toString(id_string); - output_stream << "\t\t snapshot_id " << id_string << "\n"; - } - if (!mUserLocation.isExactlyZero()) - { - output_stream << "\t\t user_location " - << (F64)mUserLocation.mV[VX] - << " " << (F64)mUserLocation.mV[VY] - << " " << (F64)mUserLocation.mV[VZ] << "\n"; - output_stream << "\t\t user_look_at " - << (F64)mUserLookAt.mV[VX] - << " " << (F64)mUserLookAt.mV[VY] - << " " << (F64)mUserLookAt.mV[VZ] << "\n"; - } - output_stream << "\t\t landing_type " << mLandingType << "\n"; - //if(mJoinNeighbors) - //{ - // output_stream << "\t\t join_neighbors " << mJoinNeighbors << "\n"; - //} - if(mSaleTimerExpires.getStarted()) - { - S32 dt_sec = (S32) mSaleTimerExpires.getRemainingTimeF32()+60; // Add a minute to prevent race conditions - output_stream << "\t\t revert_sale " << dt_sec << "\n"; - //output_stream << "\t\t revert_action " << revert_action_to_string(mExpireAction) << "\n"; - output_stream << "\t\t extended_grace " << mGraceExtension << "\n"; - } - - if(0 != mAuctionID) - { - output_stream << "\t\t auction_id " << mAuctionID << "\n"; - } - - output_stream << "\t\t allow_modify " << getAllowModify() << "\n"; - output_stream << "\t\t allow_group_modify " << getAllowGroupModify() << "\n"; - output_stream << "\t\t allow_all_object_entry " << getAllowAllObjectEntry() << "\n"; - output_stream << "\t\t allow_group_object_entry " << getAllowGroupObjectEntry() << "\n"; - output_stream << "\t\t allow_terraform " << getAllowTerraform() << "\n"; - output_stream << "\t\t allow_deed_to_group " << getAllowDeedToGroup() << "\n"; - output_stream << "\t\t contribute_with_deed " << getContributeWithDeed() << "\n"; - output_stream << "\t\t allow_damage " << getAllowDamage() << "\n"; - output_stream << "\t\t claim_date " << (S32)mClaimDate << "\n"; - output_stream << "\t\t claim_price " << mClaimPricePerMeter << "\n"; - output_stream << "\t\t rent_price " << mRentPricePerMeter << "\n"; - output_stream << "\t\t discount_rate " << mDiscountRate << "\n"; - output_stream << "\t\t allow_fly " << (getAllowFly() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_landmark " << (getAllowLandmark() ? 1 : 0) << "\n"; - output_stream << "\t\t sound_local " << (getSoundLocal() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_scripts " << (getAllowOtherScripts() ? 1 : 0) << "\n"; - output_stream << "\t\t allow_group_scripts " << (getAllowGroupScripts() ? 1 : 0) << "\n"; - output_stream << "\t\t use_estate_voice_chan " << (getParcelFlagUseEstateVoiceChannel() ? 1 : 0) << "\n"; - - output_stream << "\t\t allow_voice_chat " << (getParcelFlagAllowVoice() ? 1 : 0) << "\n"; - output_stream << "\t\t use_estate_voice_chan " << (getParcelFlagUseEstateVoiceChannel() ? 1 : 0) << "\n"; - output_stream << "\t\t for_sale " << (getForSale() ? 1 : 0) << "\n"; - output_stream << "\t\t sell_w_objects " << (getSellWithObjects() ? 1 : 0) << "\n"; - output_stream << "\t\t draw_distance " << mDrawDistance << "\n"; - output_stream << "\t\t sale_price " << mSalePrice << "\n"; - - setting = (getParcelFlag(PF_USE_ACCESS_GROUP) ? 1 : 0); - output_stream << "\t\t use_access_group " << setting << "\n"; - - setting = (getParcelFlag(PF_USE_ACCESS_LIST) ? 1 : 0); - output_stream << "\t\t use_access_list " << setting << "\n"; - - setting = (getParcelFlag(PF_USE_BAN_LIST) ? 1 : 0); - output_stream << "\t\t use_ban_list " << setting << "\n"; - - mGroupID.toString(id_string); - output_stream << "\t\t group_id " << id_string << "\n"; - - //const char* group_name - // = (mGroupName.isEmpty() ? "" : mGroupName.c_str() ); - //output_stream << "\t\t group_name " << group_name << "\n"; - - setting = (getParcelFlag(PF_USE_PASS_LIST) ? 1 : 0); - output_stream << "\t\t use_pass_list " << setting << "\n"; - - output_stream << "\t\t pass_price " << mPassPrice << "\n"; - output_stream << "\t\t pass_hours " << mPassHours << "\n"; - - setting = (getParcelFlag(PF_SHOW_DIRECTORY) ? 1 : 0); - output_stream << "\t\t show_directory " << setting << "\n"; - - setting = (getParcelFlag(PF_ALLOW_PUBLISH) ? 1 : 0); - output_stream << "\t\t allow_publish " << setting << "\n"; - - setting = (getParcelFlag(PF_MATURE_PUBLISH) ? 1 : 0); - output_stream << "\t\t mature_publish " << setting << "\n"; - - setting = (getParcelFlag(PF_DENY_ANONYMOUS) ? 1 : 0); - output_stream << "\t\t deny_anonymous " << setting << "\n"; - -// setting = (getParcelFlag(PF_DENY_IDENTIFIED) ? 1 : 0); -// output_stream << "\t\t deny_identified " << setting << "\n"; - -// setting = (getParcelFlag(PF_DENY_TRANSACTED) ? 1 : 0); -// output_stream << "\t\t deny_transacted " << setting << "\n"; - - setting = (getParcelFlag(PF_DENY_AGEUNVERIFIED) ? 1 : 0); - output_stream << "\t\t deny_age_unverified " << setting << "\n"; - - setting = (getParcelFlag(PF_RESTRICT_PUSHOBJECT) ? 1 : 0); - output_stream << "\t\t restrict_pushobject " << setting << "\n"; - - output_stream << "\t\t aabb_min " - << mAABBMin.mV[VX] - << " " << mAABBMin.mV[VY] - << " " << mAABBMin.mV[VZ] << "\n"; - - if (!mAccessList.empty()) - { - output_stream << "\t\t access_list " << mAccessList.size() << "\n"; - access_map_const_iterator cit = mAccessList.begin(); - access_map_const_iterator end = mAccessList.end(); - - for ( ; cit != end; ++cit) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = (*cit).second; - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - } - - if (!mBanList.empty()) - { - output_stream << "\t\t ban_list " << mBanList.size() << "\n"; - access_map_const_iterator cit = mBanList.begin(); - access_map_const_iterator end = mBanList.end(); - - for ( ; cit != end; ++cit) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = (*cit).second; - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - } - - /*if (mRenterList.count() > 0) - { - output_stream << "\t\t renter_list " << mRenterList.count() << "\n"; - for (i = 0; i < mRenterList.count(); i++) - { - output_stream << "\t\t{\n"; - const LLAccessEntry& entry = mRenterList.get(i); - entry.mID.toString(id_string); - output_stream << "\t\t\tid " << id_string << "\n"; - output_stream << "\t\t\ttime " << entry.mTime << "\n"; - output_stream << "\t\t\tflags " << entry.mFlags << "\n"; - output_stream << "\t\t}\n"; - } - }*/ - - output_stream << "\t}\n"; - output_stream.flags(old_flags); - - return TRUE; -} - - // Assumes we are in a block "ParcelData" void LLParcel::packMessage(LLMessageSystem* msg) { diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 12d0fdf1e9..6f5ae87ebd 100644 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -103,6 +103,32 @@ const U32 RT_OTHER = 0x1 << 3; const U32 RT_LIST = 0x1 << 4; const U32 RT_SELL = 0x1 << 5; + +// Timeouts for parcels +// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000 +const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000); +// ***** TESTING is 10 minutes +//const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(600000000); + +// group is 60 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 5184000000000 +const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(5184000000000); +// ***** TESTING is 10 minutes +//const U64 GROUP_USEC_CONVERSION_TIMEOUT = U64L(600000000); + +// default sale timeout is 2 days -> 172800000000 +const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(172800000000); +// ***** TESTING is 10 minutes +//const U64 DEFAULT_USEC_SALE_TIMEOUT = U64L(600000000); + +// more grace period extensions. +const U64 SEVEN_DAYS_IN_USEC = U64L(604800000000); + +// if more than 100,000s before sale revert, and no extra extension +// has been given, go ahead and extend it more. That's about 1.2 days. +const S32 EXTEND_GRACE_IF_MORE_THAN_SEC = 100000; + + + class LLMessageSystem; class LLSD; @@ -271,9 +297,9 @@ public: void setPassPrice(S32 price) { mPassPrice = price; } void setPassHours(F32 hours) { mPassHours = hours; } - BOOL importStream(std::istream& input_stream); +// BOOL importStream(std::istream& input_stream); BOOL importAccessEntry(std::istream& input_stream, LLAccessEntry* entry); - BOOL exportStream(std::ostream& output_stream); +// BOOL exportStream(std::ostream& output_stream); void packMessage(LLMessageSystem* msg); void packMessage(LLSD& msg); @@ -633,4 +659,10 @@ public: }; +const std::string& ownership_status_to_string(LLParcel::EOwnershipStatus status); +LLParcel::EOwnershipStatus ownership_string_to_status(const std::string& s); +LLParcel::ECategory category_string_to_category(const std::string& s); +const std::string& category_to_string(LLParcel::ECategory category); + + #endif diff --git a/indra/llmath/v3math.cpp b/indra/llmath/v3math.cpp index 101e9d075a..d4031796ad 100644 --- a/indra/llmath/v3math.cpp +++ b/indra/llmath/v3math.cpp @@ -134,6 +134,7 @@ BOOL LLVector3::clampLength( F32 length_limit ) mV[0] *= length_limit; mV[1] *= length_limit; mV[2] *= length_limit; + changed = TRUE; } } 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)) + } +} diff --git a/indra/llprimitive/llprimlinkinfo.h b/indra/llprimitive/llprimlinkinfo.h index 7f1840303b..946fa75bfa 100644 --- a/indra/llprimitive/llprimlinkinfo.h +++ b/indra/llprimitive/llprimlinkinfo.h @@ -50,7 +50,7 @@ const F32 MAX_OBJECT_SPAN = 54.f; // max distance from outside edge of an object to the farthest edge const F32 OBJECT_SPAN_BONUS = 2.f; // infinitesimally small prims can always link up to this distance -const S32 MAX_PRIMS_PER_OBJECT = 255; +const S32 MAX_PRIMS_PER_OBJECT = 256; template < typename DATA_TYPE > diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 85b64a8788..cfd333f618 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -1,6 +1,7 @@ /* Localized versions of Info.plist keys */ CFBundleName = "Second Life"; + CFBundleShortVersionString = "Second Life version 1.23.0.0"; CFBundleGetInfoString = "Second Life version 1.23.0.0, Copyright 2004-2008 Linden Research, Inc."; diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt index 0000cc237b..b9e0e3dbdd 100644 --- a/indra/test/CMakeLists.txt +++ b/indra/test/CMakeLists.txt @@ -60,6 +60,7 @@ set(test_SOURCE_FILES llstreamtools_tut.cpp llstring_tut.cpp lltemplatemessagebuilder_tut.cpp + lltimestampcache_tut.cpp lltiming_tut.cpp lltranscode_tut.cpp lltut.cpp diff --git a/indra/test/llblowfish_tut.cpp b/indra/test/llblowfish_tut.cpp index 5146bb6b97..4a128a8984 100644 --- a/indra/test/llblowfish_tut.cpp +++ b/indra/test/llblowfish_tut.cpp @@ -94,7 +94,6 @@ namespace tut template<> template<> void blowfish_object::test<1>() { -#if LL_LINUX LLUUID blank; LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); @@ -107,15 +106,11 @@ namespace tut dst_len = cipher.requiredEncryptionSpace(8); ensure("encryption space 8", (dst_len == 16) ); -#else - skip("Blowfish only supported on Linux."); -#endif // LL_LINUX } template<> template<> void blowfish_object::test<2>() { -#if LL_LINUX LLUUID blank; LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); @@ -129,15 +124,11 @@ namespace tut result.resize(count); ensure("encrypt null key", matchFile("blowfish.1.bin", result)); -#else - skip("Blowfish only supported on Linux."); -#endif // LL_LINUX } template<> template<> void blowfish_object::test<3>() { -#if LL_LINUX // same as base64 test id LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e"); LLBlowfishCipher cipher(&id.mData[0], UUID_BYTES); @@ -152,8 +143,5 @@ namespace tut result.resize(count); ensure("encrypt real key", matchFile("blowfish.2.bin", result)); -#else - skip("Blowfish only supported on Linux."); -#endif // LL_LINUX } } diff --git a/indra/test/llsdmessagebuilder_tut.cpp b/indra/test/llsdmessagebuilder_tut.cpp index 60a50cf75f..27ab127772 100755 --- a/indra/test/llsdmessagebuilder_tut.cpp +++ b/indra/test/llsdmessagebuilder_tut.cpp @@ -35,6 +35,7 @@ #include "linden_common.h" #include "lltut.h" +#include "llmessagetemplate.h" #include "llsdmessagebuilder.h" #include "llsdmessagereader.h" #include "llsdtraits.h" @@ -43,10 +44,24 @@ #include "v3dmath.h" #include "v3math.h" #include "v4math.h" +#include "llsdutil_math.cpp" +#include "lltemplatemessagebuilder.h" namespace tut { + static LLTemplateMessageBuilder::message_template_name_map_t templateNameMap; + + LLMsgData* messageData = NULL; + LLMsgBlkData* messageBlockData = NULL; + struct LLSDMessageBuilderTestData { + + LLSDMessageBuilderTestData() + { + messageData = new LLMsgData("testMessage"); + messageBlockData = new LLMsgBlkData("testBlock", 0); + } + static LLSDMessageBuilder defaultBuilder() { LLSDMessageBuilder builder; @@ -61,6 +76,43 @@ namespace tut reader.setMessage("name", builder.getMessage()); return reader; } + + static void addValue(LLMsgBlkData* mbd, char* name, void* v, EMsgVariableType type, int size, int data_size = -1) + { + LLMsgVarData tmp(name, type); + tmp.addData(v, size, type, data_size); + mbd->mMemberVarData[name] = tmp; + } + + + static LLMessageBlock* defaultTemplateBlock(const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE) + { + return createTemplateBlock(_PREHASH_Test0, type, size, block); + } + + static LLMessageBlock* createTemplateBlock(char* name, const EMsgVariableType type = MVT_NULL, const S32 size = 0, EMsgBlockType block = MBT_VARIABLE) + { + LLMessageBlock* result = new LLMessageBlock(name, block); + if(type != MVT_NULL) + { + result->addVariable(_PREHASH_Test0, type, size); + } + return result; + } + + static LLTemplateMessageBuilder* defaultTemplateBuilder(LLMessageTemplate& messageTemplate, char* name = _PREHASH_Test0) + { + templateNameMap[_PREHASH_TestMessage] = &messageTemplate; + LLTemplateMessageBuilder* builder = new LLTemplateMessageBuilder(templateNameMap); + builder->newMessage(_PREHASH_TestMessage); + builder->nextBlock(name); + return builder; + } + + static LLMessageTemplate defaultTemplate() + { + return LLMessageTemplate(_PREHASH_TestMessage, 1, MFT_HIGH); + } }; typedef test_group<LLSDMessageBuilderTestData> LLSDMessageBuilderTestGroup; @@ -280,5 +332,509 @@ namespace tut outValue = buffer; ensure_equals("Ensure String", inValue, outValue); } + + template<> template<> + void LLSDMessageBuilderTestObject::test<19>() + { + LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0); + LLMsgData* md = new LLMsgData("testMessage"); + md->addBlock(mbd); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*md); + LLSD output = builder.getMessage(); + + ensure("Ensure message block created when copied from legacy message to llsd", output["testBlock"].isDefined()); + } + + // MVT_FIXED + template<> template<> + void LLSDMessageBuilderTestObject::test<20>() + { + char binData[] = "abcdefghijklmnop"; + + addValue(messageBlockData, "testBinData", &binData, MVT_FIXED, sizeof(binData)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); + ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + + ensure_memory_matches("Ensure fixed binary data works in a message copied from legacy to llsd", + &v[0], sizeof(binData), binData, sizeof(binData)); + } + + // MVT_VARIABLE data_size 1 (U8's) + template<> template<> + void LLSDMessageBuilderTestObject::test<21>() + { + /* U8 binData[] = "abcdefghijklmnop"; + + addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData), 1); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); + ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + + ensure_memory_matches("Ensure MVT_VARIABLE U8 binary data works in a message copied from legacy to llsd", + &v[0], sizeof(binData), binData, sizeof(binData));*/ + } + + // MVT_VARIABLE data_size 2 (U16's) + template<> template<> + void LLSDMessageBuilderTestObject::test<22>() + { + U16 binData[] = {1,2,3,4,5,6,7,8,9}; //9 shorts + + addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 1, 2); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); + ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + + ensure_memory_matches("Ensure MVT_VARIABLE U16 binary data works in a message copied from legacy to llsd", + &v[0], sizeof(binData) >> 1, binData, sizeof(binData) >> 1); + } + + // MVT_VARIABLE data_size 4 (S32's) + template<> template<> + void LLSDMessageBuilderTestObject::test<23>() + { + U32 binData[] = {9,8,7,6,5,4,3,2,1}; + + addValue(messageBlockData, "testBinData", &binData, MVT_VARIABLE, sizeof(binData) >> 2, 4); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); + ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + + ensure_memory_matches("Ensure MVT_VARIABLE S32 binary data works in a message copied from legacy to llsd", + &v[0], sizeof(binData) >> 2, binData, sizeof(binData) >> 2); + } + + // MVT_U8 + template<> template<> + void LLSDMessageBuilderTestObject::test<24>() + { + U8 data = 0xa5; + + addValue(messageBlockData, "testBinData", &data, MVT_U8, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_U8 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asInteger(), data); + } + + // MVT_U16 + template<> template<> + void LLSDMessageBuilderTestObject::test<25>() + { + U16 data = 0xa55a; + + addValue(messageBlockData, "testBinData", &data, MVT_U16, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_U16 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asInteger(), data); + } + + // MVT_U32 + template<> template<> + void LLSDMessageBuilderTestObject::test<26>() + { + U32 data = 0xa55a7117; + + addValue(messageBlockData, "testBinData", &data, MVT_U32, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_U32 data works in a message copied from legacy to llsd", + ll_U32_from_sd(output["testBlock"][0]["testBinData"]), data); + } + + // MVT_U64 - crush into an s32: LLSD does not support 64 bit values + template<> template<> + void LLSDMessageBuilderTestObject::test<27>() + { + U64 data = U64L(0xa55a711711223344); + addValue(messageBlockData, "testBinData", &data, MVT_U64, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_U64 data works in a message copied from legacy to llsd", + ll_U64_from_sd(output["testBlock"][0]["testBinData"]), data); + } + + // MVT_S8 + template<> template<> + void LLSDMessageBuilderTestObject::test<28>() + { + S8 data = -31; + + addValue(messageBlockData, "testBinData", &data, MVT_S8, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_S8 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asInteger(), data); + } + + // MVT_S16 + template<> template<> + void LLSDMessageBuilderTestObject::test<29>() + { + S16 data = -31; + + addValue(messageBlockData, "testBinData", &data, MVT_S16, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_S16 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asInteger(), data); + } + + // MVT_S32 + template<> template<> + void LLSDMessageBuilderTestObject::test<30>() + { + S32 data = -3100; + + addValue(messageBlockData, "testBinData", &data, MVT_S32, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_S32 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asInteger(), data); + } + + // MVT_S64 - crush into an s32: LLSD does not support 64 bit values + template<> template<> + void LLSDMessageBuilderTestObject::test<31>() + { + S64 data = -31003100; + + addValue(messageBlockData, "testBinData", &data, MVT_S64, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_S64 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asInteger(), (S32)data); + } + + // MVT_F32 + template<> template<> + void LLSDMessageBuilderTestObject::test<32>() + { + F32 data = 1234.1234f; + + addValue(messageBlockData, "testBinData", &data, MVT_F32, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_F32 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asReal(), data); + } + + // MVT_F64 + template<> template<> + void LLSDMessageBuilderTestObject::test<33>() + { + F64 data = 1234.1234; + + addValue(messageBlockData, "testBinData", &data, MVT_F64, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_F64 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asReal(), data); + } + + // MVT_LLVector3 + template<> template<> + void LLSDMessageBuilderTestObject::test<34>() + { + LLVector3 data(1,2,3); + + addValue(messageBlockData, "testBinData", &data, MVT_LLVector3, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd", + ll_vector3_from_sd(output["testBlock"][0]["testBinData"]), data); + } + + // MVT_LLVector3d + template<> template<> + void LLSDMessageBuilderTestObject::test<35>() + { + LLVector3d data(1,2,3); + + addValue(messageBlockData, "testBinData", &data, MVT_LLVector3d, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_LLVector3 data works in a message copied from legacy to llsd", + ll_vector3d_from_sd(output["testBlock"][0]["testBinData"]), data); + } + + // MVT_LLVector4 + template<> template<> + void LLSDMessageBuilderTestObject::test<36>() + { + LLVector4 data(1,2,3,4); + LLSD v = ll_sd_from_vector4(data); + + addValue(messageBlockData, "testBinData", &data, MVT_LLVector4, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_LLVector4 data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"], v); + } + + // MVT_LLQuaternion + template<> template<> + void LLSDMessageBuilderTestObject::test<37>() + { + LLQuaternion data(1,2,3,0); + + //we send a quaternion packed into a vec3 (w is infered) - so sizeof(vec) == 12 bytes not 16. + LLVector3 vec = data.packToVector3(); + + addValue(messageBlockData, "testBinData", &vec, MVT_LLQuaternion, sizeof(vec)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_LLQuaternion data works in a message copied from legacy to llsd", + ll_quaternion_from_sd(output["testBlock"][0]["testBinData"]), data); + } + + // MVT_LLUUID + template<> template<> + void LLSDMessageBuilderTestObject::test<38>() + { + LLUUID data("01234567-0123-0123-0123-234567abcdef"); + + addValue(messageBlockData, "testBinData", &data, MVT_LLUUID, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + std::string v = output["testBlock"][0]["testBinData"].asUUID().asString(); + + ensure_equals("Ensure MVT_LLUUID data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asUUID(), data); + } + + // MVT_BOOL + template<> template<> + void LLSDMessageBuilderTestObject::test<39>() + { + BOOL valueTrue = true; + BOOL valueFalse = false; + + LLMsgData* md = new LLMsgData("testMessage"); + LLMsgBlkData* mbd = new LLMsgBlkData("testBlock", 0); + addValue(mbd, "testBoolFalse", &valueFalse, MVT_BOOL, sizeof(BOOL)); + addValue(mbd, "testBoolTrue", &valueTrue, MVT_BOOL, sizeof(BOOL)); + md->addBlock(mbd); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*md); + LLSD output = builder.getMessage(); + + ensure("Ensure bools work in a message copied from legacy to llsd", + output["testBlock"][0]["testBoolTrue"].asBoolean() && !output["testBlock"][0]["testBoolFalse"].asBoolean()); + } + + // MVT_IP_ADDR + template<> template<> + void LLSDMessageBuilderTestObject::test<40>() + { + U32 data(0xff887766); + LLSD v = ll_sd_from_ipaddr(data); + + addValue(messageBlockData, "testBinData", &data, MVT_IP_ADDR, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_IP_ADDR data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"], v); + } + + // MVT_IP_PORT + template<> template<> + void LLSDMessageBuilderTestObject::test<41>() + { + U16 data = 0xff88; + + addValue(messageBlockData, "testBinData", &data, MVT_IP_PORT, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + ensure_equals("Ensure MVT_IP_PORT data works in a message copied from legacy to llsd", + output["testBlock"][0]["testBinData"].asInteger(), data); + } + + // MVT_U16Vec3 + template<> template<> + void LLSDMessageBuilderTestObject::test<42>() + { + U16 data[3] = {0,1,2}; + + addValue(messageBlockData, "testBinData", &data, MVT_U16Vec3, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); + ensure("Ensure MVT_U16Vec3 data copied from legacy to llsd give a valid vector", v.size() > 0); + + ensure_memory_matches("Ensure MVT_U16Vec3 data works in a message copied from legacy to llsd", + (U16*)&v[0], 6, data, 6); + } + + // MVT_U16Quat + template<> template<> + void LLSDMessageBuilderTestObject::test<43>() + { + U16 data[4] = {0,1,2,4}; + + addValue(messageBlockData, "testBinData", &data, MVT_U16Quat, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); + ensure("Ensure MVT_U16Quat data copied from legacy to llsd give a valid vector", v.size() > 0); + + ensure_memory_matches("Ensure MVT_U16Quat data works in a message copied from legacy to llsd", + (U16*)&v[0], 8, data, 8); + } + + // MVT_S16Array + template<> template<> + void LLSDMessageBuilderTestObject::test<44>() + { + S16 data[19] = {0,-1,2,-4,5,-6,7,-8,9,-10,11,-12,13,-14,15,16,17,18}; + + addValue(messageBlockData, "testBinData", &data, MVT_S16Array, sizeof(data)); + messageData->addBlock(messageBlockData); + LLSDMessageBuilder builder = defaultBuilder(); + + builder.copyFromMessageData(*messageData); + LLSD output = builder.getMessage(); + + std::vector<U8> v = output["testBlock"][0]["testBinData"].asBinary(); + ensure("Ensure MVT_S16Array data copied from legacy to llsd give a valid vector", v.size() > 0); + + ensure_memory_matches("Ensure MVT_S16Array data works in a message copied from legacy to llsd", + (U16*)&v[0], 19, data, 19); + } + + template<> template<> + void LLSDMessageBuilderTestObject::test<45>() + { + LLMessageTemplate messageTemplate = defaultTemplate(); + messageTemplate.addBlock(defaultTemplateBlock(MVT_U8, 1)); + U8 inValue = 2; + LLTemplateMessageBuilder* template_builder = defaultTemplateBuilder(messageTemplate); + template_builder->addU8(_PREHASH_Test0, inValue); + + LLSDMessageBuilder builder; + builder.copyFromMessageData(*template_builder->getCurrentMessage()); + LLSD output = builder.getMessage(); + + ensure_equals(output["Test0"][0]["Test0"].asInteger(), 2); + + } + + template<> template<> + void LLSDMessageBuilderTestObject::test<46>() + { + LLMessageTemplate messageTemplate = defaultTemplate(); + messageTemplate.addBlock(defaultTemplateBlock(MVT_VARIABLE, 1)); + std::string inValue = "testing"; + LLTemplateMessageBuilder* builder = defaultTemplateBuilder(messageTemplate); + builder->addString(_PREHASH_Test0, inValue.c_str()); + + LLSDMessageBuilder sd_builder; + sd_builder.copyFromMessageData(*builder->getCurrentMessage()); + LLSD output = sd_builder.getMessage(); + + ensure_equals(output["Test0"][0]["Test0"].asString(), std::string("testing")); + } + } diff --git a/indra/test/lltimestampcache_tut.cpp b/indra/test/lltimestampcache_tut.cpp new file mode 100644 index 0000000000..9e0de0fe60 --- /dev/null +++ b/indra/test/lltimestampcache_tut.cpp @@ -0,0 +1,129 @@ +/** + * @file lltimestampcache_tut.cpp + * @author James Tess + * @date 2008-12-03 + * + * $LicenseInfo:firstyear=2008&license=viewergpl$ + * + * Copyright (c) 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 <tut/tut.hpp> + +#include "linden_common.h" +#include "../mapserver/lltimestampcache.h" +#include "lltut.h" + + +namespace tut +{ + struct LLTimestampCacheTestData + { + }; + + typedef test_group<LLTimestampCacheTestData> LLTimestampCacheTestGroup; + typedef LLTimestampCacheTestGroup::object LLTimestampCacheTestObject; + + LLTimestampCacheTestGroup timestampCacheTestGroup("LLTimestampCache"); + + // Most common usage + template<> template<> + void LLTimestampCacheTestObject::test<1>() + { + LLTimestampCache<std::string, std::string> cache; + // put in some data + cache.insert("key1", "val1", 1); + cache.insert("key2", "val2", 2); + cache.insert("key3", "val3", 3); + ensure_equals("size is 3", cache.size(), 3); + // check some items + ensure("has key1", cache.has("key1")); + ensure("no invalid key", !cache.has("invalid key")); + // get some items + ensure_equals("get key1", cache.get("key1", 4), "val1"); + ensure_equals("get invalid key", + cache.get("invalid key", 4), std::string() ); + // timestamps + ensure_equals("key1 timestamp updated", cache.getTimestamp("key1"), 4); + ensure_equals("invalid key timestamp", + cache.getTimestamp("invalid key"), 0); + } + + // New empty cache shouldn't have any entries + template<> template<> + void LLTimestampCacheTestObject::test<2>() + { + LLTimestampCache<std::string, std::string> cache; + ensure_equals("starts empty", cache.size(), 0); + ensure_equals("has nothing", cache.has("foo"), false); + ensure_equals("gets nothing", cache.get("foo", 0), std::string() ); + U32 max_time = 0xFFFFFFFF; + ensure_equals("erases nothing", cache.eraseBefore(max_time), 0); + } + + // Non empty cache + template<> template<> + void LLTimestampCacheTestObject::test<3>() + { + LLTimestampCache<std::string, std::string> cache; + cache.insert("foo", "bar", 123); + ensure_equals("size one", cache.size(), 1); + ensure_equals("has it", cache.has("foo"), true); + ensure_equals("timestamp correct", cache.getTimestamp("foo"), 123); + std::string value = cache.get("foo", 456); + ensure_equals("get value", value, "bar"); + ensure_equals("timestamp updated", cache.getTimestamp("foo"), 456); + ensure_equals("erase nothing", cache.eraseBefore(0), 0); + ensure_equals("erase one", cache.eraseBefore(789), 1); + ensure_equals("empty after erase", cache.size(), 0); + } + + // Recache of item should update timestamp + template<> template<> + void LLTimestampCacheTestObject::test<4>() + { + LLTimestampCache<std::string, std::string> cache; + cache.insert("foo", "bar", 123); + cache.insert("foo", "bar", 456); + ensure_equals("duplicate suppressed", cache.size(), 1); + ensure_equals("timestamp replaced", cache.getTimestamp("foo"), 456); + } + + // Erasing some items + template<> template<> + void LLTimestampCacheTestObject::test<5>() + { + LLTimestampCache<std::string, std::string> cache; + cache.insert("key1", "val1", 1); + cache.insert("key2", "val2", 2); + cache.insert("key3", "val3", 3); + cache.insert("key4", "val4", 4); + size_t erased = cache.eraseBefore(3); + ensure_equals("erase range", erased, 2); + ensure_equals("cache post erase", cache.size(), 2); + ensure_equals("has key3", cache.has("key3"), true); + ensure_equals("not has key2", cache.has("key2"), false); + } +} diff --git a/indra/test/lltut.cpp b/indra/test/lltut.cpp index 64861c3115..201e174f9c 100644 --- a/indra/test/lltut.cpp +++ b/indra/test/lltut.cpp @@ -33,10 +33,13 @@ */ #include "linden_common.h" + #include "lltut.h" +#include "lldate.h" #include "llformat.h" #include "llsd.h" +#include "lluri.h" namespace tut { @@ -74,7 +77,7 @@ namespace tut void ensure_equals(const char* m, const LLSD& actual, const LLSD& expected) { - const std::string& msg = m; + const std::string& msg = m ? m : ""; ensure_equals(msg + " type", actual.type(), expected.type()); switch (actual.type()) @@ -196,3 +199,4 @@ namespace tut } } } + diff --git a/indra/test/lltut.h b/indra/test/lltut.h index 51e2ee2709..6d50ebad33 100644 --- a/indra/test/lltut.h +++ b/indra/test/lltut.h @@ -35,13 +35,13 @@ #ifndef LL_LLTUT_H #define LL_LLTUT_H -#include <tut/tut.hpp> - -#include "lldate.h" -#include "lluri.h" #include "llmath.h" +#include <tut/tut.hpp> + +class LLDate; class LLSD; +class LLURI; namespace tut { diff --git a/indra/test/test.cpp b/indra/test/test.cpp index 566459ee90..ba81c6e49e 100644 --- a/indra/test/test.cpp +++ b/indra/test/test.cpp @@ -54,9 +54,10 @@ # include "ctype_workaround.h" #endif - namespace tut { + std::string sSourceDir; + test_runner_singleton runner; } @@ -184,6 +185,7 @@ static const apr_getopt_option_t TEST_CL_OPTIONS[] = {"verbose", 'v', 0, "Verbose output."}, {"group", 'g', 1, "Run test group specified by option argument."}, {"output", 'o', 1, "Write output to the named file."}, + {"sourcedir", 's', 1, "Project source file directory from CMake."}, {"touch", 't', 1, "Touch the given file if all tests succeed"}, {"wait", 'w', 0, "Wait for input before exit."}, {"debug", 'd', 0, "Emit full debug logs."}, @@ -302,6 +304,11 @@ int main(int argc, char **argv) output = new std::ofstream; output->open(opt_arg); break; + case 's': // --sourcedir + tut::sSourceDir = opt_arg; + // For convenience, so you can use tut::sSourceDir + "myfile" + tut::sSourceDir += '/'; + break; case 't': touch = opt_arg; break; diff --git a/indra/test/test.h b/indra/test/test.h new file mode 100644 index 0000000000..16ec4effcf --- /dev/null +++ b/indra/test/test.h @@ -0,0 +1,49 @@ +/** + * @file test.h + * @author James + * @date 2009-01-12 + * + * $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 TEST_H +#define TEST_H + +#include <string> + +namespace tut +{ + // Source code directory from CMake, used for loading test data and + // configuration. For example: + // + // loadMyConfig( sSourceDir + "config.dat" ); + // + // Use sparingly, as hitting the file system slows down test execution + // and hence every compile. JC + extern std::string sSourceDir; +} + +#endif |