summaryrefslogtreecommitdiff
path: root/indra/llmessage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage')
-rw-r--r--indra/llmessage/CMakeLists.txt10
-rw-r--r--indra/llmessage/llassetstorage.cpp27
-rw-r--r--indra/llmessage/llassetstorage.h3
-rw-r--r--indra/llmessage/llblowfishcipher.cpp6
-rw-r--r--indra/llmessage/llbuffer.cpp16
-rw-r--r--indra/llmessage/llbufferstream.cpp4
-rw-r--r--indra/llmessage/llcircuit.cpp4
-rw-r--r--indra/llmessage/llcoproceduremanager.cpp7
-rw-r--r--indra/llmessage/llcorehttputil.cpp16
-rw-r--r--indra/llmessage/llexperiencecache.cpp2
-rw-r--r--indra/llmessage/llfiltersd2xmlrpc.cpp778
-rw-r--r--indra/llmessage/llfiltersd2xmlrpc.h271
-rw-r--r--indra/llmessage/llhost.cpp3
-rw-r--r--indra/llmessage/lliohttpserver.cpp2
-rw-r--r--indra/llmessage/lliopipe.h3
-rw-r--r--indra/llmessage/lliosocket.h2
-rw-r--r--indra/llmessage/llmail.cpp1
-rw-r--r--indra/llmessage/llpacketbuffer.cpp26
-rw-r--r--indra/llmessage/llpacketbuffer.h12
-rw-r--r--indra/llmessage/llpacketring.cpp468
-rw-r--r--indra/llmessage/llpacketring.h87
-rw-r--r--indra/llmessage/llproxy.cpp1
-rw-r--r--indra/llmessage/llservice.h64
-rw-r--r--indra/llmessage/llstoredmessage.h1
-rw-r--r--indra/llmessage/lltemplatemessagebuilder.cpp4
-rw-r--r--indra/llmessage/lltemplatemessagedispatcher.cpp6
-rw-r--r--indra/llmessage/lltemplatemessagereader.cpp4
-rw-r--r--indra/llmessage/message.cpp14
-rw-r--r--indra/llmessage/message.h7
-rw-r--r--indra/llmessage/message_prehash.cpp1
-rw-r--r--indra/llmessage/message_prehash.h1
-rw-r--r--indra/llmessage/net.cpp12
32 files changed, 392 insertions, 1471 deletions
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index 56c93ca5af..f661e2c348 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -29,7 +29,6 @@ set(llmessage_SOURCE_FILES
lldatapacker.cpp
lldispatcher.cpp
llexperiencecache.cpp
- llfiltersd2xmlrpc.cpp
llgenericstreamingmessage.cpp
llhost.cpp
llhttpnode.cpp
@@ -113,7 +112,6 @@ set(llmessage_HEADER_FILES
lleventflags.h
llexperiencecache.h
llextendedstatus.h
- llfiltersd2xmlrpc.h
llfollowcamparams.h
llgenericstreamingmessage.h
llhost.h
@@ -196,15 +194,11 @@ target_link_libraries(
llfilesystem
llmath
llcorehttp
- ll::xmlrpc-epi
)
target_include_directories( llmessage INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
-if (NOT (USE_AUTOBUILD_3P OR USE_CONAN))
- if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
- set_source_files_properties(llnamevalue.cpp PROPERTIES
- COMPILE_FLAGS -Wno-stringop-truncation)
- endif()
+if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
+ set_source_files_properties(llnamevalue.cpp PROPERTIES COMPILE_FLAGS -Wno-stringop-truncation)
endif ()
include(LibraryInstall)
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 70a7a34a70..10fd56a68e 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -484,6 +484,8 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
void *user_data,
bool is_priority)
{
+ LL_PROFILE_ZONE_SCOPED;
+
LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << LL_ENDL;
LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << LL_ENDL;
@@ -529,6 +531,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
if (size > 0)
{
+ LL_PROFILE_ZONE_NAMED("gad - file in cache");
// we've already got the file
// theoretically, partial files w/o a pending request shouldn't happen
// unless there's a weird error
@@ -548,7 +551,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
}
bool duplicate = false;
-
+ LL_PROFILE_ZONE_NAMED("gad - check pending downloads");
// check to see if there's a pending download of this uuid already
for (request_list_t::iterator iter = mPendingDownloads.begin();
iter != mPendingDownloads.end(); ++iter )
@@ -582,7 +585,8 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
// static
void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type,
const LLUUID& callback_id, LLAssetType::EType callback_type,
- S32 result_code, LLExtStat ext_status)
+ S32 result_code, LLExtStat ext_status,
+ S32 bytes_fetched)
{
// find and callback ALL pending requests for this UUID
// SJB: We process the callbacks in reverse order, I do not know if this is important,
@@ -595,6 +599,10 @@ void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LL
LLAssetRequest* tmp = *curiter;
if ((tmp->getUUID() == file_id) && (tmp->getType()== file_type))
{
+ if (bytes_fetched > 0)
+ {
+ tmp->mBytesFetched = bytes_fetched;
+ }
requests.push_front(tmp);
iter = gAssetStorage->mPendingDownloads.erase(curiter);
}
@@ -661,6 +669,7 @@ void LLAssetStorage::downloadCompleteCallback(
callback_type = req->getType();
}
+ S32 bytes_fetched = 0;
if (LL_ERR_NOERR == result)
{
// we might have gotten a zero-size file
@@ -674,21 +683,11 @@ void LLAssetStorage::downloadCompleteCallback(
}
else
{
-#if 1
- for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin();
- iter != gAssetStorage->mPendingDownloads.end(); ++iter )
- {
- LLAssetRequest* dlreq = *iter;
- if ((dlreq->getUUID() == file_id) && (dlreq->getType()== file_type))
- {
- dlreq->mBytesFetched = vfile.getSize();
- }
- }
-#endif
+ bytes_fetched = vfile.getSize();
}
}
- removeAndCallbackPendingDownloads(file_id, file_type, callback_id, callback_type, result, ext_status);
+ removeAndCallbackPendingDownloads(file_id, file_type, callback_id, callback_type, result, ext_status, bytes_fetched);
}
void LLAssetStorage::getEstateAsset(
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index 88fa572092..6d6526757d 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -324,7 +324,8 @@ public:
static void removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type,
const LLUUID& callback_id, LLAssetType::EType callback_type,
- S32 result_code, LLExtStat ext_status);
+ S32 result_code, LLExtStat ext_status,
+ S32 bytes_fetched);
// download process callbacks
static void downloadCompleteCallback(
diff --git a/indra/llmessage/llblowfishcipher.cpp b/indra/llmessage/llblowfishcipher.cpp
index ed036e396d..3973565e22 100644
--- a/indra/llmessage/llblowfishcipher.cpp
+++ b/indra/llmessage/llblowfishcipher.cpp
@@ -88,7 +88,7 @@ U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
src_len))
{
LL_WARNS() << "LLBlowfishCipher::encrypt EVP_EncryptUpdate failure" << LL_ENDL;
- goto ERROR;
+ goto BF_ENCRYPT_ERROR;
}
// There may be some final data left to encrypt if the input is
@@ -96,14 +96,14 @@ U32 LLBlowfishCipher::encrypt(const U8* src, U32 src_len, U8* dst, U32 dst_len)
if (!EVP_EncryptFinal_ex(context, (unsigned char*)(dst + output_len), &temp_len))
{
LL_WARNS() << "LLBlowfishCipher::encrypt EVP_EncryptFinal failure" << LL_ENDL;
- goto ERROR;
+ goto BF_ENCRYPT_ERROR;
}
output_len += temp_len;
EVP_CIPHER_CTX_free(context);
return output_len;
-ERROR:
+BF_ENCRYPT_ERROR:
EVP_CIPHER_CTX_free(context);
return 0;
}
diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp
index dc7115b167..3a4b493b26 100644
--- a/indra/llmessage/llbuffer.cpp
+++ b/indra/llmessage/llbuffer.cpp
@@ -142,7 +142,7 @@ LLHeapBuffer::~LLHeapBuffer()
S32 LLHeapBuffer::bytesLeft() const
{
- return (mSize - (mNextFree - mBuffer));
+ return (mSize - (S32)(mNextFree - mBuffer));
}
// virtual
@@ -371,11 +371,11 @@ LLBufferArray::segment_iterator_t LLBufferArray::splitAfter(U8* address)
return it;
}
S32 channel = (*it).getChannel();
- LLSegment segment1(channel, base, (address - base) + 1);
+ LLSegment segment1(channel, base, (S32)((address - base) + 1));
*it = segment1;
segment_iterator_t rv = it;
++it;
- LLSegment segment2(channel, address + 1, size - (address - base) - 1);
+ LLSegment segment2(channel, address + 1, (S32)(size - (address - base) - 1));
mSegments.insert(it, segment2);
return rv;
}
@@ -424,7 +424,7 @@ LLBufferArray::segment_iterator_t LLBufferArray::constructSegmentAfter(
segment = LLSegment(
(*rv).getChannel(),
address,
- (*rv).size() - (address - (*rv).data()));
+ (*rv).size() - (S32)(address - (*rv).data()));
}
else
{
@@ -533,7 +533,7 @@ S32 LLBufferArray::countAfter(S32 channel, U8* start) const
if(++start < ((*it).data() + (*it).size()))
{
// it's in the same segment
- offset = start - (*it).data();
+ offset = (S32)(start - (*it).data());
}
else if(++it == end)
{
@@ -586,7 +586,7 @@ U8* LLBufferArray::readAfter(
&& (*it).isOnChannel(channel))
{
// copy the data out of this segment
- S32 bytes_in_segment = (*it).size() - (start - (*it).data());
+ S32 bytes_in_segment = (*it).size() - (S32)(start - (*it).data());
bytes_to_copy = llmin(bytes_left, bytes_in_segment);
memcpy(dest, start, bytes_to_copy); /*Flawfinder: ignore*/
len += bytes_to_copy;
@@ -681,7 +681,7 @@ U8* LLBufferArray::seek(
{
if(delta > 0)
{
- S32 bytes_in_segment = (*it).size() - (start - (*it).data());
+ S32 bytes_in_segment = (*it).size() - (S32)(start - (*it).data());
S32 local_delta = llmin(delta, bytes_in_segment);
rv += local_delta;
delta -= local_delta;
@@ -689,7 +689,7 @@ U8* LLBufferArray::seek(
}
else
{
- S32 bytes_in_segment = start - (*it).data();
+ S32 bytes_in_segment = (S32)(start - (*it).data());
S32 local_delta = llmin(llabs(delta), bytes_in_segment);
rv -= local_delta;
delta += local_delta;
diff --git a/indra/llmessage/llbufferstream.cpp b/indra/llmessage/llbufferstream.cpp
index e51b489813..2c745f6fe4 100644
--- a/indra/llmessage/llbufferstream.cpp
+++ b/indra/llmessage/llbufferstream.cpp
@@ -273,7 +273,7 @@ streampos LLBufferStreamBuf::seekoff(
}
LLMutexLock lock(mBuffer->getMutex());
- address = mBuffer->seek(mChannels.in(), base_addr, off);
+ address = mBuffer->seek(mChannels.in(), base_addr, (S32)off);
if(address)
{
LLBufferArray::segment_iterator_t iter;
@@ -306,7 +306,7 @@ streampos LLBufferStreamBuf::seekoff(
}
LLMutexLock lock(mBuffer->getMutex());
- address = mBuffer->seek(mChannels.out(), base_addr, off);
+ address = mBuffer->seek(mChannels.out(), base_addr, (S32)off);
if(address)
{
LLBufferArray::segment_iterator_t iter;
diff --git a/indra/llmessage/llcircuit.cpp b/indra/llmessage/llcircuit.cpp
index bf22f3d3f0..8f9c02bdca 100644
--- a/indra/llmessage/llcircuit.cpp
+++ b/indra/llmessage/llcircuit.cpp
@@ -525,13 +525,13 @@ void LLCircuitData::checkPeriodTime()
F64Seconds period_length = mt_sec - mPeriodTime;
if ( period_length > TARGET_PERIOD_LENGTH)
{
- F32 bps_in = F32Bits(mBytesInThisPeriod).value() / period_length.value();
+ F32 bps_in = F32Bits(mBytesInThisPeriod).value() / (F32)period_length.value();
if (bps_in > mPeakBPSIn)
{
mPeakBPSIn = bps_in;
}
- F32 bps_out = F32Bits(mBytesOutThisPeriod).value() / period_length.value();
+ F32 bps_out = F32Bits(mBytesOutThisPeriod).value() / (F32)period_length.value();
if (bps_out > mPeakBPSOut)
{
mPeakBPSOut = bps_out;
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index 263670bdac..6a663a8e97 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -301,12 +301,12 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
mPoolSize(size),
mActiveCoprocsCount(0),
mPending(0),
- mPendingCoprocs(std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)),
mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
mCoroMapping()
{
try
{
+ mPendingCoprocs = std::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE);
// store in our LLTempBoundListener so that when the LLCoprocedurePool is
// destroyed, we implicitly disconnect from this LLEventPump
// Monitores application status
@@ -339,6 +339,11 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
llassert(0); // Fix Me! Ignoring missing listener!
}
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("CoProcMgr") << "Bad memory allocation in LLCoprocedurePool::LLCoprocedurePool!" << LL_ENDL;
+ }
for (size_t count = 0; count < mPoolSize; ++count)
{
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 684e96883f..992e145758 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -295,7 +295,15 @@ void HttpCoroHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRespons
}
else
{
- result = this->handleSuccess(response, status);
+ try
+ {
+ result = this->handleSuccess(response, status);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("CoreHTTP") << "Failed to allocate memory for response handling." << LL_ENDL;
+ }
}
buildStatusEntry(response, status, result);
@@ -523,7 +531,7 @@ LLSD HttpCoroRawHandler::handleSuccess(LLCore::HttpResponse * response, LLCore::
bas >> std::noskipws;
data.assign(std::istream_iterator<U8>(bas), std::istream_iterator<U8>());
- result[HttpCoroutineAdapter::HTTP_RESULTS_RAW] = data;
+ result[HttpCoroutineAdapter::HTTP_RESULTS_RAW] = std::move(data);
#else
// This is disabled because it's dangerous. See the other case for an
@@ -585,7 +593,7 @@ LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
LLCore::BufferArrayStream bas(body);
- boost::json::error_code ec;
+ boost::system::error_code ec;
boost::json::value jsonRoot = boost::json::parse(bas, ec);
if(ec.failed())
{ // deserialization failed. Record the reason and pass back an empty map for markup.
@@ -610,7 +618,7 @@ LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &succes
LLCore::BufferArrayStream bas(body);
- boost::json::error_code ec;
+ boost::system::error_code ec;
boost::json::value jsonRoot = boost::json::parse(bas, ec);
if (ec.failed())
{
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index b5d0c93376..83a070df32 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -94,6 +94,8 @@ LLExperienceCache::LLExperienceCache()
LLExperienceCache::~LLExperienceCache()
{
+ // can exit without cleanup()
+ sShutdown = true;
}
void LLExperienceCache::initSingleton()
diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp
deleted file mode 100644
index 84b56d54bf..0000000000
--- a/indra/llmessage/llfiltersd2xmlrpc.cpp
+++ /dev/null
@@ -1,778 +0,0 @@
-/**
- * @file llfiltersd2xmlrpc.cpp
- * @author Phoenix
- * @date 2005-04-26
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/**
- * xml rpc request:
- * <code>
- * <?xml version="1.0"?>
- * <methodCall><methodName>examples.getStateName</methodName>
- * <params><param><value><i4>41</i4></value></param></params>
- * </methodCall>
- * </code>
- *
- * xml rpc response:
- * <code>
- * <?xml version="1.0"?>
- * <methodResponse>
- * <params><param><value><string>South Dakota</string></value></param></params>
- * </methodResponse>
- * </code>
- *
- * xml rpc fault:
- * </code>
- * <?xml version="1.0"?>
- * <methodResponse>
- * <fault><value><struct>
- * <member><name>faultCode</name><value><int>4</int></value></member>
- * <member><name>faultString</name><value><string>...</string></value></member>
- * </struct></value></fault>
- * </methodResponse>
- * </code>
- *
- * llsd rpc request:
- * <code>
- * { 'method':'...', 'parameter':...]}
- * </code>
- *
- * llsd rpc response:
- * <code>
- * { 'response':... }
- * </code>
- *
- * llsd rpc fault:
- * <code>
- * { 'fault': {'code':i..., 'description':'...'} }
- * </code>
- *
- */
-
-#include "linden_common.h"
-#include "llfiltersd2xmlrpc.h"
-
-#include <sstream>
-#include <iterator>
-
-#ifdef LL_USESYSTEMLIBS
-#include <xmlrpc.h>
-#else
-#include <xmlrpc-epi/xmlrpc.h>
-#endif
-
-#include "apr_base64.h"
-
-#include "llbuffer.h"
-#include "llbufferstream.h"
-#include "llfasttimer.h"
-#include "llmemorystream.h"
-#include "llsd.h"
-#include "llsdserialize.h"
-#include "lluuid.h"
-
-// spammy mode
-//#define LL_SPEW_STREAM_OUT_DEBUGGING 1
-
-/**
- * String constants
- */
-static const char XML_HEADER[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
-static const char XMLRPC_REQUEST_HEADER_1[] = "<methodCall><methodName>";
-static const char XMLRPC_REQUEST_HEADER_2[] = "</methodName><params>";
-static const char XMLRPC_REQUEST_FOOTER[] = "</params></methodCall>";
-static const char XMLRPC_METHOD_RESPONSE_HEADER[] = "<methodResponse>";
-static const char XMLRPC_METHOD_RESPONSE_FOOTER[] = "</methodResponse>";
-static const char XMLRPC_RESPONSE_HEADER[] = "<params><param>";
-static const char XMLRPC_RESPONSE_FOOTER[] = "</param></params>";
-static const char XMLRPC_FAULT_1[] = "<fault><value><struct><member><name>faultCode</name><value><int>";
-static const char XMLRPC_FAULT_2[] = "</int></value></member><member><name>faultString</name><value><string>";
-static const char XMLRPC_FAULT_3[] = "</string></value></member></struct></value></fault>";
-static const char LLSDRPC_RESPONSE_HEADER[] = "{'response':";
-static const char LLSDRPC_RESPONSE_FOOTER[] = "}";
-const char LLSDRPC_REQUEST_HEADER_1[] = "{'method':'";
-const char LLSDRPC_REQUEST_HEADER_2[] = "', 'parameter': ";
-const char LLSDRPC_REQUEST_FOOTER[] = "}";
-static const char LLSDRPC_FAULT_HADER_1[] = "{ 'fault': {'code':i";
-static const char LLSDRPC_FAULT_HADER_2[] = ", 'description':";
-static const char LLSDRPC_FAULT_FOOTER[] = "} }";
-static const S32 DEFAULT_PRECISION = 20;
-
-/**
- * LLFilterSD2XMLRPC
- */
-LLFilterSD2XMLRPC::LLFilterSD2XMLRPC()
-{
-}
-
-LLFilterSD2XMLRPC::~LLFilterSD2XMLRPC()
-{
-}
-
-std::string xml_escape_string(const std::string& in)
-{
- std::ostringstream out;
- std::string::const_iterator it = in.begin();
- std::string::const_iterator end = in.end();
- for(; it != end; ++it)
- {
- switch((*it))
- {
- case '<':
- out << "&lt;";
- break;
- case '>':
- out << "&gt;";
- break;
- case '&':
- out << "&amp;";
- break;
- case '\'':
- out << "&apos;";
- break;
- case '"':
- out << "&quot;";
- break;
- default:
- out << (*it);
- break;
- }
- }
- return out.str();
-}
-
-void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd)
-{
- ostr << "<value>";
- switch(sd.type())
- {
- case LLSD::TypeMap:
- {
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(map) BEGIN" << LL_ENDL;
-#endif
- ostr << "<struct>";
- if(ostr.fail())
- {
- LL_INFOS() << "STREAM FAILURE writing struct" << LL_ENDL;
- }
- LLSD::map_const_iterator it = sd.beginMap();
- LLSD::map_const_iterator end = sd.endMap();
- for(; it != end; ++it)
- {
- ostr << "<member><name>" << xml_escape_string((*it).first)
- << "</name>";
- streamOut(ostr, (*it).second);
- if(ostr.fail())
- {
- LL_INFOS() << "STREAM FAILURE writing '" << (*it).first
- << "' with sd type " << (*it).second.type() << LL_ENDL;
- }
- ostr << "</member>";
- }
- ostr << "</struct>";
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(map) END" << LL_ENDL;
-#endif
- break;
- }
- case LLSD::TypeArray:
- {
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(array) BEGIN" << LL_ENDL;
-#endif
- ostr << "<array><data>";
- LLSD::array_const_iterator it = sd.beginArray();
- LLSD::array_const_iterator end = sd.endArray();
- for(; it != end; ++it)
- {
- streamOut(ostr, *it);
- if(ostr.fail())
- {
- LL_INFOS() << "STREAM FAILURE writing array element sd type "
- << (*it).type() << LL_ENDL;
- }
- }
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(array) END" << LL_ENDL;
-#endif
- ostr << "</data></array>";
- break;
- }
- case LLSD::TypeUndefined:
- // treat undefined as a bool with a false value.
- case LLSD::TypeBoolean:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(bool)" << LL_ENDL;
-#endif
- ostr << "<boolean>" << (sd.asBoolean() ? "1" : "0") << "</boolean>";
- break;
- case LLSD::TypeInteger:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(int)" << LL_ENDL;
-#endif
- ostr << "<i4>" << sd.asInteger() << "</i4>";
- break;
- case LLSD::TypeReal:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(real)" << LL_ENDL;
-#endif
- ostr << "<double>" << sd.asReal() << "</double>";
- break;
- case LLSD::TypeString:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(string)" << LL_ENDL;
-#endif
- ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>";
- break;
- case LLSD::TypeUUID:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(uuid)" << LL_ENDL;
-#endif
- // serialize it as a string
- ostr << "<string>" << sd.asString() << "</string>";
- break;
- case LLSD::TypeURI:
- {
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(uri)" << LL_ENDL;
-#endif
- // serialize it as a string
- ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>";
- break;
- }
- case LLSD::TypeBinary:
- {
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(binary)" << LL_ENDL;
-#endif
- // this is pretty inefficient, but we'll deal with that
- // problem when it becomes one.
- ostr << "<base64>";
- LLSD::Binary buffer = sd.asBinary();
- if(!buffer.empty())
- {
- // *TODO: convert to LLBase64
- int b64_buffer_length = apr_base64_encode_len(static_cast<int>(buffer.size()));
- char* b64_buffer = new char[b64_buffer_length];
- b64_buffer_length = apr_base64_encode_binary(
- b64_buffer,
- &buffer[0],
- static_cast<int>(buffer.size()));
- ostr.write(b64_buffer, b64_buffer_length - 1);
- delete[] b64_buffer;
- }
- ostr << "</base64>";
- break;
- }
- case LLSD::TypeDate:
-#if LL_SPEW_STREAM_OUT_DEBUGGING
- LL_INFOS() << "streamOut(date)" << LL_ENDL;
-#endif
- // no need to escape this since it will be alpha-numeric.
- ostr << "<dateTime.iso8601>" << sd.asString() << "</dateTime.iso8601>";
- break;
- default:
- // unhandled type
- LL_WARNS() << "Unhandled structured data type: " << sd.type()
- << LL_ENDL;
- break;
- }
- ostr << "</value>";
-}
-
-/**
- * LLFilterSD2XMLRPCResponse
- */
-
-LLFilterSD2XMLRPCResponse::LLFilterSD2XMLRPCResponse()
-{
-}
-
-LLFilterSD2XMLRPCResponse::~LLFilterSD2XMLRPCResponse()
-{
-}
-
-
-// virtual
-LLIOPipe::EStatus LLFilterSD2XMLRPCResponse::process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump)
-{
- LL_PROFILE_ZONE_SCOPED;
-
- PUMP_DEBUG;
- // This pipe does not work if it does not have everyting. This
- // could be addressed by making a stream parser for llsd which
- // handled partial information.
- if(!eos)
- {
- return STATUS_BREAK;
- }
-
- PUMP_DEBUG;
- // we have everyting in the buffer, so turn the structure data rpc
- // response into an xml rpc response.
- LLBufferStream stream(channels, buffer.get());
- stream << XML_HEADER << XMLRPC_METHOD_RESPONSE_HEADER;
- LLSD sd;
- LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in()));
-
- PUMP_DEBUG;
- LLIOPipe::EStatus rv = STATUS_ERROR;
- if(sd.has("response"))
- {
- PUMP_DEBUG;
- // it is a normal response. pack it up and ship it out.
- stream.precision(DEFAULT_PRECISION);
- stream << XMLRPC_RESPONSE_HEADER;
- streamOut(stream, sd["response"]);
- stream << XMLRPC_RESPONSE_FOOTER << XMLRPC_METHOD_RESPONSE_FOOTER;
- rv = STATUS_DONE;
- }
- else if(sd.has("fault"))
- {
- PUMP_DEBUG;
- // it is a fault.
- stream << XMLRPC_FAULT_1 << sd["fault"]["code"].asInteger()
- << XMLRPC_FAULT_2
- << xml_escape_string(sd["fault"]["description"].asString())
- << XMLRPC_FAULT_3 << XMLRPC_METHOD_RESPONSE_FOOTER;
- rv = STATUS_DONE;
- }
- else
- {
- LL_WARNS() << "Unable to determine the type of LLSD response." << LL_ENDL;
- }
- PUMP_DEBUG;
- return rv;
-}
-
-/**
- * LLFilterSD2XMLRPCRequest
- */
-LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest()
-{
-}
-
-LLFilterSD2XMLRPCRequest::LLFilterSD2XMLRPCRequest(const char* method)
-{
- if(method)
- {
- mMethod.assign(method);
- }
-}
-
-LLFilterSD2XMLRPCRequest::~LLFilterSD2XMLRPCRequest()
-{
-}
-
-// virtual
-LLIOPipe::EStatus LLFilterSD2XMLRPCRequest::process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump)
-{
- LL_PROFILE_ZONE_SCOPED;
- // This pipe does not work if it does not have everyting. This
- // could be addressed by making a stream parser for llsd which
- // handled partial information.
- PUMP_DEBUG;
- if(!eos)
- {
- LL_INFOS() << "!eos" << LL_ENDL;
- return STATUS_BREAK;
- }
-
- // See if we can parse it
- LLBufferStream stream(channels, buffer.get());
- LLSD sd;
- LLSDSerialize::fromNotation(sd, stream, buffer->count(channels.in()));
- if(stream.fail())
- {
- LL_INFOS() << "STREAM FAILURE reading structure data." << LL_ENDL;
- }
-
- PUMP_DEBUG;
- // We can get the method and parameters from either the member
- // function or passed in via the buffer. We prefer the buffer if
- // we found a parameter and a method, or fall back to using
- // mMethod and putting everyting in the buffer into the parameter.
- std::string method;
- LLSD param_sd;
- if(sd.has("method") && sd.has("parameter"))
- {
- method = sd["method"].asString();
- param_sd = sd["parameter"];
- }
- else
- {
- method = mMethod;
- param_sd = sd;
- }
- if(method.empty())
- {
- LL_WARNS() << "SD -> XML Request no method found." << LL_ENDL;
- return STATUS_ERROR;
- }
-
- PUMP_DEBUG;
- // We have a method, and some kind of parameter, so package it up
- // and send it out.
- LLBufferStream ostream(channels, buffer.get());
- ostream.precision(DEFAULT_PRECISION);
- if(ostream.fail())
- {
- LL_INFOS() << "STREAM FAILURE setting precision" << LL_ENDL;
- }
- ostream << XML_HEADER << XMLRPC_REQUEST_HEADER_1
- << xml_escape_string(method) << XMLRPC_REQUEST_HEADER_2;
- if(ostream.fail())
- {
- LL_INFOS() << "STREAM FAILURE writing method headers" << LL_ENDL;
- }
- switch(param_sd.type())
- {
- case LLSD::TypeMap:
- // If the params are a map, then we do not want to iterate
- // through them since the iterators returned will be map
- // ordered un-named values, which will lose the names, and
- // only stream the values, turning it into an array.
- ostream << "<param>";
- streamOut(ostream, param_sd);
- ostream << "</param>";
- break;
- case LLSD::TypeArray:
- {
-
- LLSD::array_iterator it = param_sd.beginArray();
- LLSD::array_iterator end = param_sd.endArray();
- for(; it != end; ++it)
- {
- ostream << "<param>";
- streamOut(ostream, *it);
- ostream << "</param>";
- }
- break;
- }
- default:
- ostream << "<param>";
- streamOut(ostream, param_sd);
- ostream << "</param>";
- break;
- }
-
- stream << XMLRPC_REQUEST_FOOTER;
- return STATUS_DONE;
-}
-
-/**
- * LLFilterXMLRPCResponse2LLSD
- */
-// this is a c function here since it's really an implementation
-// detail that requires a header file just get the definition of the
-// parameters.
-LLIOPipe::EStatus stream_out(std::ostream& ostr, XMLRPC_VALUE value)
-{
- XMLRPC_VALUE_TYPE_EASY type = XMLRPC_GetValueTypeEasy(value);
- LLIOPipe::EStatus status = LLIOPipe::STATUS_OK;
- switch(type)
- {
- case xmlrpc_type_base64:
- {
- S32 len = XMLRPC_GetValueStringLen(value);
- const char* buf = XMLRPC_GetValueBase64(value);
- ostr << " b(";
- if((len > 0) && buf)
- {
- ostr << len << ")\"";
- ostr.write(buf, len);
- ostr << "\"";
- }
- else
- {
- ostr << "0)\"\"";
- }
- break;
- }
- case xmlrpc_type_boolean:
- //LL_DEBUGS() << "stream_out() bool" << LL_ENDL;
- ostr << " " << (XMLRPC_GetValueBoolean(value) ? "true" : "false");
- break;
- case xmlrpc_type_datetime:
- ostr << " d\"" << XMLRPC_GetValueDateTime_ISO8601(value) << "\"";
- break;
- case xmlrpc_type_double:
- ostr << " r" << XMLRPC_GetValueDouble(value);
- //LL_DEBUGS() << "stream_out() double" << XMLRPC_GetValueDouble(value)
- // << LL_ENDL;
- break;
- case xmlrpc_type_int:
- ostr << " i" << XMLRPC_GetValueInt(value);
- //LL_DEBUGS() << "stream_out() integer:" << XMLRPC_GetValueInt(value)
- // << LL_ENDL;
- break;
- case xmlrpc_type_string:
- //LL_DEBUGS() << "stream_out() string: " << str << LL_ENDL;
- ostr << " s(" << XMLRPC_GetValueStringLen(value) << ")'"
- << XMLRPC_GetValueString(value) << "'";
- break;
- case xmlrpc_type_array: // vector
- case xmlrpc_type_mixed: // vector
- {
- //LL_DEBUGS() << "stream_out() array" << LL_ENDL;
- ostr << " [";
- U32 needs_comma = 0;
- XMLRPC_VALUE current = XMLRPC_VectorRewind(value);
- while(current && (LLIOPipe::STATUS_OK == status))
- {
- if(needs_comma++) ostr << ",";
- status = stream_out(ostr, current);
- current = XMLRPC_VectorNext(value);
- }
- ostr << "]";
- break;
- }
- case xmlrpc_type_struct: // still vector
- {
- //LL_DEBUGS() << "stream_out() struct" << LL_ENDL;
- ostr << " {";
- std::string name;
- U32 needs_comma = 0;
- XMLRPC_VALUE current = XMLRPC_VectorRewind(value);
- while(current && (LLIOPipe::STATUS_OK == status))
- {
- if(needs_comma++) ostr << ",";
- name.assign(XMLRPC_GetValueID(current));
- ostr << "'" << LLSDNotationFormatter::escapeString(name) << "':";
- status = stream_out(ostr, current);
- current = XMLRPC_VectorNext(value);
- }
- ostr << "}";
- break;
- }
- case xmlrpc_type_empty:
- case xmlrpc_type_none:
- default:
- status = LLIOPipe::STATUS_ERROR;
- LL_WARNS() << "Found an empty xmlrpc type.." << LL_ENDL;
- // not much we can do here...
- break;
- };
- return status;
-}
-
-LLFilterXMLRPCResponse2LLSD::LLFilterXMLRPCResponse2LLSD()
-{
-}
-
-LLFilterXMLRPCResponse2LLSD::~LLFilterXMLRPCResponse2LLSD()
-{
-}
-
-LLIOPipe::EStatus LLFilterXMLRPCResponse2LLSD::process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump)
-{
- LL_PROFILE_ZONE_SCOPED;
-
- PUMP_DEBUG;
- if(!eos) return STATUS_BREAK;
- if(!buffer) return STATUS_ERROR;
-
- PUMP_DEBUG;
- // *FIX: This technique for reading data is far from optimal. We
- // need to have some kind of istream interface into the xml
- // parser...
- S32 bytes = buffer->countAfter(channels.in(), NULL);
- if(!bytes) return STATUS_ERROR;
- char* buf = new char[bytes + 1];
- buf[bytes] = '\0';
- buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes);
-
- //LL_DEBUGS() << "xmlrpc response: " << buf << LL_ENDL;
-
- PUMP_DEBUG;
- XMLRPC_REQUEST response = XMLRPC_REQUEST_FromXML(
- buf,
- bytes,
- NULL);
- if(!response)
- {
- LL_WARNS() << "XML -> SD Response unable to parse xml." << LL_ENDL;
- delete[] buf;
- return STATUS_ERROR;
- }
-
- PUMP_DEBUG;
- LLBufferStream stream(channels, buffer.get());
- stream.precision(DEFAULT_PRECISION);
- if(XMLRPC_ResponseIsFault(response))
- {
- PUMP_DEBUG;
- stream << LLSDRPC_FAULT_HADER_1
- << XMLRPC_GetResponseFaultCode(response)
- << LLSDRPC_FAULT_HADER_2;
- const char* fault_str = XMLRPC_GetResponseFaultString(response);
- std::string fault_string;
- if(fault_str)
- {
- fault_string.assign(fault_str);
- }
- stream << "'" << LLSDNotationFormatter::escapeString(fault_string)
- << "'" <<LLSDRPC_FAULT_FOOTER;
- }
- else
- {
- PUMP_DEBUG;
- stream << LLSDRPC_RESPONSE_HEADER;
- XMLRPC_VALUE param = XMLRPC_RequestGetData(response);
- if(param)
- {
- stream_out(stream, param);
- }
- stream << LLSDRPC_RESPONSE_FOOTER;
- }
- PUMP_DEBUG;
- XMLRPC_RequestFree(response, 1);
- delete[] buf;
- PUMP_DEBUG;
- return STATUS_DONE;
-}
-
-/**
- * LLFilterXMLRPCRequest2LLSD
- */
-LLFilterXMLRPCRequest2LLSD::LLFilterXMLRPCRequest2LLSD()
-{
-}
-
-LLFilterXMLRPCRequest2LLSD::~LLFilterXMLRPCRequest2LLSD()
-{
-}
-
-LLIOPipe::EStatus LLFilterXMLRPCRequest2LLSD::process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump)
-{
- LL_PROFILE_ZONE_SCOPED;
- PUMP_DEBUG;
- if(!eos) return STATUS_BREAK;
- if(!buffer) return STATUS_ERROR;
-
- PUMP_DEBUG;
- // *FIX: This technique for reading data is far from optimal. We
- // need to have some kind of istream interface into the xml
- // parser...
- S32 bytes = buffer->countAfter(channels.in(), NULL);
- if(!bytes) return STATUS_ERROR;
- char* buf = new char[bytes + 1];
- buf[bytes] = '\0';
- buffer->readAfter(channels.in(), NULL, (U8*)buf, bytes);
-
- //LL_DEBUGS() << "xmlrpc request: " << buf << LL_ENDL;
-
- // Check the value in the buffer. XMLRPC_REQUEST_FromXML will report a error code 4 if
- // values that are less than 0x20 are passed to it, except
- // 0x09: Horizontal tab; 0x0a: New Line; 0x0d: Carriage
- U8* cur_pBuf = (U8*)buf;
- U8 cur_char;
- for (S32 i=0; i<bytes; i++)
- {
- cur_char = *cur_pBuf;
- if ( cur_char < 0x20
- && 0x09 != cur_char
- && 0x0a != cur_char
- && 0x0d != cur_char )
- {
- *cur_pBuf = '?';
- }
- ++cur_pBuf;
- }
-
- PUMP_DEBUG;
- XMLRPC_REQUEST request = XMLRPC_REQUEST_FromXML(
- buf,
- bytes,
- NULL);
- if(!request)
- {
- LL_WARNS() << "XML -> SD Request process parse error." << LL_ENDL;
- delete[] buf;
- return STATUS_ERROR;
- }
-
- PUMP_DEBUG;
- LLBufferStream stream(channels, buffer.get());
- stream.precision(DEFAULT_PRECISION);
- const char* name = XMLRPC_RequestGetMethodName(request);
- stream << LLSDRPC_REQUEST_HEADER_1 << (name ? name : "")
- << LLSDRPC_REQUEST_HEADER_2;
- XMLRPC_VALUE param = XMLRPC_RequestGetData(request);
- if(param)
- {
- PUMP_DEBUG;
- S32 size = XMLRPC_VectorSize(param);
- if(size > 1)
- {
- // if there are multiple parameters, stuff the values into
- // an array so that the next step in the chain can read them.
- stream << "[";
- }
- XMLRPC_VALUE current = XMLRPC_VectorRewind(param);
- bool needs_comma = false;
- while(current)
- {
- if(needs_comma)
- {
- stream << ",";
- }
- needs_comma = true;
- stream_out(stream, current);
- current = XMLRPC_VectorNext(param);
- }
- if(size > 1)
- {
- // close the array
- stream << "]";
- }
- }
- stream << LLSDRPC_REQUEST_FOOTER;
- XMLRPC_RequestFree(request, 1);
- delete[] buf;
- PUMP_DEBUG;
- return STATUS_DONE;
-}
-
diff --git a/indra/llmessage/llfiltersd2xmlrpc.h b/indra/llmessage/llfiltersd2xmlrpc.h
deleted file mode 100644
index 55938d3e2b..0000000000
--- a/indra/llmessage/llfiltersd2xmlrpc.h
+++ /dev/null
@@ -1,271 +0,0 @@
-/**
- * @file llfiltersd2xmlrpc.h
- * @author Phoenix
- * @date 2005-04-26
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLFILTERSD2XMLRPC_H
-#define LL_LLFILTERSD2XMLRPC_H
-
-/**
- * These classes implement the necessary pipes for translating between
- * xmlrpc and llsd rpc. The llsd rpcs mechanism was developed as an
- * extensible and easy to parse serialization grammer which maintains
- * a time efficient in-memory representation.
- */
-
-#include <iosfwd>
-#include "lliopipe.h"
-
-/**
- * @class LLFilterSD2XMLRPC
- * @brief Filter from serialized LLSD to an XMLRPC method call
- *
- * This clas provides common functionality for the LLFilterSD2XMLRPRC
- * request and response classes.
- */
-class LLFilterSD2XMLRPC : public LLIOPipe
-{
-public:
- LLFilterSD2XMLRPC();
- virtual ~LLFilterSD2XMLRPC();
-
-protected:
- /**
- * @brief helper method
- */
- void streamOut(std::ostream& ostr, const LLSD& sd);
-};
-
-/**
- * @class LLFilterSD2XMLRPCResponse
- * @brief Filter from serialized LLSD to an XMLRPC response
- *
- * This class filters a serialized LLSD object to an xmlrpc
- * repsonse. Since resonses are limited to a single param, the xmlrprc
- * response only serializes it as one object.
- * This class correctly handles normal llsd responses as well as llsd
- * rpc faults.
- *
- * For example, if given:
- * <code>{'response':[ i200, r3.4, {"foo":"bar"} ]}</code>
- * Would generate:
- * <code>
- * <?xml version="1.0"?>
- * <methodResponse><params><param><array><data>
- * <value><int>200</int></value>
- * <value><double>3.4</double></value>
- * <value><struct><member>
- * <name>foo</name><value><string>bar</string></value></member>
- * </struct></value>
- * </data></array></param></params></methodResponse>
- * </code>
- */
-class LLFilterSD2XMLRPCResponse : public LLFilterSD2XMLRPC
-{
-public:
- // constructor
- LLFilterSD2XMLRPCResponse();
-
- // destructor
- virtual ~LLFilterSD2XMLRPCResponse();
-
- /* @name LLIOPipe virtual implementations
- */
- //@{
-protected:
- /**
- * @brief Process the data in buffer.
- */
- virtual EStatus process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump);
- //@}
-};
-
-/**
- * @class LLFilterSD2XMLRPCRequest
- * @brief Filter from serialized LLSD to an XMLRPC method call
- *
- * This class will accept any kind of serialized LLSD object, but you
- * probably want to have an array on the outer boundary since this
- * object will interpret each element in the top level LLSD as a
- * parameter into the xmlrpc spec.
- *
- * For example, you would represent 3 params as:
- * <code>
- * {'method'='foo', 'parameter':[i200, r3.4, {"foo":"bar"}]}
- * </code>
- * To generate:
- * <code>
- * <?xml version="1.0"?>
- * <methodCall><params>
- * <param><value><int>200</int></value></param>
- * <param><value><double>3.4</double></value></param>
- * <param><value><struct><member>
- * <name>foo</name><value><string>bar</string></value></member>
- * </struct></value></param>
- * </params></methodCall>
- *
- * This class will accept 2 different kinds of encodings. The first
- * just an array of params as long as you specify the method in the
- * constructor. It will also accept a structured data in the form:
- * {'method':'$method_name', 'parameter':[...] } In the latter form, the
- * encoded 'method' will be used regardless of the construction of the
- * object, and the 'parameter' will be used as parameter to the call.
- */
-class LLFilterSD2XMLRPCRequest : public LLFilterSD2XMLRPC
-{
-public:
- // constructor
- LLFilterSD2XMLRPCRequest();
-
- // constructor
- LLFilterSD2XMLRPCRequest(const char* method);
-
- // destructor
- virtual ~LLFilterSD2XMLRPCRequest();
-
- /* @name LLIOPipe virtual implementations
- */
- //@{
-protected:
- /**
- * @brief Process the data in buffer.
- */
- virtual EStatus process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump);
- //@}
-
-protected:
- // The method name of this request.
- std::string mMethod;
-};
-
-/**
- * @class LLFilterXMLRPCResponse2LLSD
- * @brief Filter from serialized XMLRPC method response to LLSD
- *
- * The xmlrpc spec states that responses can only have one element
- * which can be of any supported type.
- * This takes in xml of the form:
- * <code>
- * <?xml version=\"1.0\"?><methodResponse><params><param>
- * <value><string>ok</string></value></param></params></methodResponse>
- * </code>
- * And processes it into:
- * <code>'ok'</code>
- *
- */
-class LLFilterXMLRPCResponse2LLSD : public LLIOPipe
-{
-public:
- // constructor
- LLFilterXMLRPCResponse2LLSD();
-
- // destructor
- virtual ~LLFilterXMLRPCResponse2LLSD();
-
- /* @name LLIOPipe virtual implementations
- */
- //@{
-protected:
- /**
- * @brief Process the data in buffer.
- */
- virtual EStatus process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump);
- //@}
-
-protected:
-};
-
-/**
- * @class LLFilterXMLRPCRequest2LLSD
- * @brief Filter from serialized XMLRPC method call to LLSD
- *
- * This takes in xml of the form:
- * <code>
- * <?xml version=\"1.0\"?><methodCall>
- * <methodName>repeat</methodName>
- * <params>
- * <param><value><i4>4</i4></value></param>
- * <param><value><string>ok</string></value></param>
- * </params></methodCall>
- * </code>
- * And processes it into:
- * <code>{ 'method':'repeat', 'params':[i4, 'ok'] }</code>
- */
-class LLFilterXMLRPCRequest2LLSD : public LLIOPipe
-{
-public:
- // constructor
- LLFilterXMLRPCRequest2LLSD();
-
- // destructor
- virtual ~LLFilterXMLRPCRequest2LLSD();
-
- /* @name LLIOPipe virtual implementations
- */
- //@{
-protected:
- /**
- * @brief Process the data in buffer.
- */
- virtual EStatus process_impl(
- const LLChannelDescriptors& channels,
- buffer_ptr_t& buffer,
- bool& eos,
- LLSD& context,
- LLPumpIO* pump);
- //@}
-
-protected:
-};
-
-/**
- * @brief This function takes string, and escapes it appropritately
- * for inclusion as xml data.
- */
-std::string xml_escape_string(const std::string& in);
-
-/**
- * @brief Externally available constants
- */
-extern const char LLSDRPC_REQUEST_HEADER_1[];
-extern const char LLSDRPC_REQUEST_HEADER_2[];
-extern const char LLSDRPC_REQUEST_FOOTER[];
-
-#endif // LL_LLFILTERSD2XMLRPC_H
diff --git a/indra/llmessage/llhost.cpp b/indra/llmessage/llhost.cpp
index ace316512f..e7e3e27f58 100644
--- a/indra/llmessage/llhost.cpp
+++ b/indra/llmessage/llhost.cpp
@@ -31,8 +31,7 @@
#include "llerror.h"
#if LL_WINDOWS
- #define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>
+ #include <llwin32headers.h>
#else
#include <netdb.h>
#include <netinet/in.h> // ntonl()
diff --git a/indra/llmessage/lliohttpserver.cpp b/indra/llmessage/lliohttpserver.cpp
index e562f09844..edc431e538 100644
--- a/indra/llmessage/lliohttpserver.cpp
+++ b/indra/llmessage/lliohttpserver.cpp
@@ -625,7 +625,7 @@ bool LLHTTPResponder::readHeaderLine(
}
return false;
}
- S32 offset = -((len - 1) - (newline - dest));
+ S32 offset = -((len - 1) - (S32)(newline - dest));
++newline;
*newline = '\0';
mLastRead = buffer->seek(channels.in(), last, offset);
diff --git a/indra/llmessage/lliopipe.h b/indra/llmessage/lliopipe.h
index a58ee045c2..b40539f38c 100644
--- a/indra/llmessage/lliopipe.h
+++ b/indra/llmessage/lliopipe.h
@@ -30,8 +30,7 @@
#define LL_LLIOPIPE_H
#include <boost/intrusive_ptr.hpp>
-#include <boost/shared_ptr.hpp>
-#include "llwin32headerslean.h"
+#include "llwin32headers.h"
#include "apr_poll.h"
#include "llsd.h"
diff --git a/indra/llmessage/lliosocket.h b/indra/llmessage/lliosocket.h
index 0a3f2617e6..4b79c77b56 100644
--- a/indra/llmessage/lliosocket.h
+++ b/indra/llmessage/lliosocket.h
@@ -38,7 +38,7 @@
*/
#include "lliopipe.h"
-#include "llwin32headerslean.h"
+#include "llwin32headers.h"
#include "apr_pools.h"
#include "apr_network_io.h"
#include "llchainio.h"
diff --git a/indra/llmessage/llmail.cpp b/indra/llmessage/llmail.cpp
index 9e10a356db..b842aeda62 100644
--- a/indra/llmessage/llmail.cpp
+++ b/indra/llmessage/llmail.cpp
@@ -28,7 +28,6 @@
#include "llmail.h"
-// APR on Windows needs full windows headers
#include "llwin32headers.h"
#include <string>
#include <sstream>
diff --git a/indra/llmessage/llpacketbuffer.cpp b/indra/llmessage/llpacketbuffer.cpp
index dc5c7a73cb..0b04a560be 100644
--- a/indra/llmessage/llpacketbuffer.cpp
+++ b/indra/llmessage/llpacketbuffer.cpp
@@ -32,8 +32,6 @@
#include "lltimer.h"
#include "llhost.h"
-///////////////////////////////////////////////////////////
-
LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32 size) : mHost(host)
{
mSize = 0;
@@ -41,7 +39,7 @@ LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32
if (size > NET_BUFFER_SIZE)
{
- LL_ERRS() << "Sending packet > " << NET_BUFFER_SIZE << " of size " << size << LL_ENDL;
+ LL_ERRS() << "Constructing packet with size=" << size << " > " << NET_BUFFER_SIZE << LL_ENDL;
}
else
{
@@ -51,7 +49,6 @@ LLPacketBuffer::LLPacketBuffer(const LLHost &host, const char *datap, const S32
mSize = size;
}
}
-
}
LLPacketBuffer::LLPacketBuffer (S32 hSocket)
@@ -59,18 +56,29 @@ LLPacketBuffer::LLPacketBuffer (S32 hSocket)
init(hSocket);
}
-///////////////////////////////////////////////////////////
-
LLPacketBuffer::~LLPacketBuffer ()
{
}
-///////////////////////////////////////////////////////////
-
-void LLPacketBuffer::init (S32 hSocket)
+void LLPacketBuffer::init(S32 hSocket)
{
mSize = receive_packet(hSocket, mData);
mHost = ::get_sender();
mReceivingIF = ::get_receiving_interface();
}
+void LLPacketBuffer::init(const char* buffer, S32 data_size, const LLHost& host)
+{
+ if (data_size > NET_BUFFER_SIZE)
+ {
+ LL_ERRS() << "Initializing packet with size=" << data_size << " > " << NET_BUFFER_SIZE << LL_ENDL;
+ }
+ else
+ {
+ memcpy(mData, buffer, data_size);
+ mSize = data_size;
+ mHost = host;
+ mReceivingIF = ::get_receiving_interface();
+ }
+}
+
diff --git a/indra/llmessage/llpacketbuffer.h b/indra/llmessage/llpacketbuffer.h
index a2d2973fb0..ac4012d330 100644
--- a/indra/llmessage/llpacketbuffer.h
+++ b/indra/llmessage/llpacketbuffer.h
@@ -35,20 +35,22 @@ class LLPacketBuffer
{
public:
LLPacketBuffer(const LLHost &host, const char *datap, const S32 size);
- LLPacketBuffer(S32 hSocket); // receive a packet
+ LLPacketBuffer(S32 hSocket); // receive a packet
~LLPacketBuffer();
S32 getSize() const { return mSize; }
const char *getData() const { return mData; }
LLHost getHost() const { return mHost; }
LLHost getReceivingInterface() const { return mReceivingIF; }
+
void init(S32 hSocket);
+ void init(const char* buffer, S32 data_size, const LLHost& host);
protected:
- char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */
- S32 mSize; // size of buffer in bytes
- LLHost mHost; // source/dest IP and port
- LLHost mReceivingIF; // source/dest IP and port
+ char mData[NET_BUFFER_SIZE]; // packet data /* Flawfinder : ignore */
+ S32 mSize; // size of buffer in bytes
+ LLHost mHost; // source/dest IP and port
+ LLHost mReceivingIF; // source/dest IP and port
};
#endif
diff --git a/indra/llmessage/llpacketring.cpp b/indra/llmessage/llpacketring.cpp
index be838770a8..b8284334ea 100644
--- a/indra/llmessage/llpacketring.cpp
+++ b/indra/llmessage/llpacketring.cpp
@@ -1,6 +1,6 @@
/**
* @file llpacketring.cpp
- * @brief implementation of LLPacketRing class for a packet.
+ * @brief implementation of LLPacketRing class.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -43,329 +43,329 @@
#include "message.h"
#include "u64.h"
-///////////////////////////////////////////////////////////
-LLPacketRing::LLPacketRing () :
- mUseInThrottle(false),
- mUseOutThrottle(false),
- mInThrottle(256000.f),
- mOutThrottle(64000.f),
- mActualBitsIn(0),
- mActualBitsOut(0),
- mMaxBufferLength(64000),
- mInBufferLength(0),
- mOutBufferLength(0),
- mDropPercentage(0.0f),
- mPacketsToDrop(0x0)
+constexpr S16 MAX_BUFFER_RING_SIZE = 1024;
+constexpr S16 DEFAULT_BUFFER_RING_SIZE = 256;
+
+LLPacketRing::LLPacketRing ()
+ : mPacketRing(DEFAULT_BUFFER_RING_SIZE, nullptr)
{
+ LLHost invalid_host;
+ for (size_t i = 0; i < mPacketRing.size(); ++i)
+ {
+ mPacketRing[i] = new LLPacketBuffer(invalid_host, nullptr, 0);
+ }
}
-///////////////////////////////////////////////////////////
LLPacketRing::~LLPacketRing ()
{
- cleanup();
+ for (auto packet : mPacketRing)
+ {
+ delete packet;
+ }
+ mPacketRing.clear();
+ mNumBufferedPackets = 0;
+ mNumBufferedBytes = 0;
+ mHeadIndex = 0;
}
-///////////////////////////////////////////////////////////
-void LLPacketRing::cleanup ()
+S32 LLPacketRing::receivePacket (S32 socket, char *datap)
{
- LLPacketBuffer *packetp;
+ bool drop = computeDrop();
+ return (mNumBufferedPackets > 0) ?
+ receiveOrDropBufferedPacket(datap, drop) :
+ receiveOrDropPacket(socket, datap, drop);
+}
- while (!mReceiveQueue.empty())
+bool send_packet_helper(int socket, const char * datap, S32 data_size, LLHost host)
+{
+ if (!LLProxy::isSOCKSProxyEnabled())
{
- packetp = mReceiveQueue.front();
- delete packetp;
- mReceiveQueue.pop();
+ return send_packet(socket, datap, data_size, host.getAddress(), host.getPort());
}
- while (!mSendQueue.empty())
- {
- packetp = mSendQueue.front();
- delete packetp;
- mSendQueue.pop();
- }
-}
+ char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
-///////////////////////////////////////////////////////////
-void LLPacketRing::dropPackets (U32 num_to_drop)
-{
- mPacketsToDrop += num_to_drop;
-}
+ proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer));
+ socks_header->rsv = 0;
+ socks_header->addr = host.getAddress();
+ socks_header->port = htons(host.getPort());
+ socks_header->atype = ADDRESS_IPV4;
+ socks_header->frag = 0;
-///////////////////////////////////////////////////////////
-void LLPacketRing::setDropPercentage (F32 percent_to_drop)
-{
- mDropPercentage = percent_to_drop;
-}
+ memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, datap, data_size);
-void LLPacketRing::setUseInThrottle(const bool use_throttle)
-{
- mUseInThrottle = use_throttle;
+ return send_packet( socket,
+ headered_send_buffer,
+ data_size + SOCKS_HEADER_SIZE,
+ LLProxy::getInstance()->getUDPProxy().getAddress(),
+ LLProxy::getInstance()->getUDPProxy().getPort());
}
-void LLPacketRing::setUseOutThrottle(const bool use_throttle)
+bool LLPacketRing::sendPacket(int socket, const char * datap, S32 data_size, LLHost host)
{
- mUseOutThrottle = use_throttle;
+ mActualBytesOut += data_size;
+ return send_packet_helper(socket, datap, data_size, host);
}
-void LLPacketRing::setInBandwidth(const F32 bps)
+void LLPacketRing::dropPackets (U32 num_to_drop)
{
- mInThrottle.setRate(bps);
+ mPacketsToDrop += num_to_drop;
}
-void LLPacketRing::setOutBandwidth(const F32 bps)
+void LLPacketRing::setDropPercentage (F32 percent_to_drop)
{
- mOutThrottle.setRate(bps);
+ mDropPercentage = percent_to_drop;
}
-///////////////////////////////////////////////////////////
-S32 LLPacketRing::receiveFromRing (S32 socket, char *datap)
-{
-
- if (mInThrottle.checkOverflow(0))
- {
- // We don't have enough bandwidth, don't give them a packet.
- return 0;
- }
- LLPacketBuffer *packetp = NULL;
- if (mReceiveQueue.empty())
+bool LLPacketRing::computeDrop()
+{
+ bool drop= (mDropPercentage > 0.0f && (ll_frand(100.f) < mDropPercentage));
+ if (drop)
{
- // No packets on the queue, don't give them any.
- return 0;
+ ++mPacketsToDrop;
}
-
- S32 packet_size = 0;
- packetp = mReceiveQueue.front();
- mReceiveQueue.pop();
- packet_size = packetp->getSize();
- if (packetp->getData() != NULL)
+ if (mPacketsToDrop > 0)
{
- memcpy(datap, packetp->getData(), packet_size); /*Flawfinder: ignore*/
+ --mPacketsToDrop;
+ drop = true;
}
- // need to set sender IP/port!!
- mLastSender = packetp->getHost();
- mLastReceivingIF = packetp->getReceivingInterface();
- delete packetp;
-
- this->mInBufferLength -= packet_size;
-
- // Adjust the throttle
- mInThrottle.throttleOverflow(packet_size * 8.f);
- return packet_size;
+ return drop;
}
-///////////////////////////////////////////////////////////
-S32 LLPacketRing::receivePacket (S32 socket, char *datap)
+S32 LLPacketRing::receiveOrDropPacket(S32 socket, char *datap, bool drop)
{
S32 packet_size = 0;
- // If using the throttle, simulate a limited size input buffer.
- if (mUseInThrottle)
+ // pull straight from socket
+ if (LLProxy::isSOCKSProxyEnabled())
{
- bool done = false;
-
- // push any current net packet (if any) onto delay ring
- while (!done)
+ char buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; /* Flawfinder ignore */
+ packet_size = receive_packet(socket, buffer);
+ if (packet_size > 0)
{
- LLPacketBuffer *packetp;
- packetp = new LLPacketBuffer(socket);
-
- if (packetp->getSize())
- {
- mActualBitsIn += packetp->getSize() * 8;
-
- // Fake packet loss
- if (mDropPercentage && (ll_frand(100.f) < mDropPercentage))
- {
- mPacketsToDrop++;
- }
-
- if (mPacketsToDrop)
- {
- delete packetp;
- packetp = NULL;
- packet_size = 0;
- mPacketsToDrop--;
- }
- }
+ mActualBytesIn += packet_size;
+ }
- // If we faked packet loss, then we don't have a packet
- // to use for buffer overflow testing
- if (packetp)
+ if (packet_size > SOCKS_HEADER_SIZE)
+ {
+ if (drop)
{
- if (mInBufferLength + packetp->getSize() > mMaxBufferLength)
- {
- // Toss it.
- LL_WARNS() << "Throwing away packet, overflowing buffer" << LL_ENDL;
- delete packetp;
- packetp = NULL;
- }
- else if (packetp->getSize())
- {
- mReceiveQueue.push(packetp);
- mInBufferLength += packetp->getSize();
- }
- else
- {
- delete packetp;
- packetp = NULL;
- done = true;
- }
+ packet_size = 0;
}
else
{
- // No packetp, keep going? - no packetp == faked packet loss
- }
- }
-
- // Now, grab data off of the receive queue according to our
- // throttled bandwidth settings.
- packet_size = receiveFromRing(socket, datap);
- }
- else
- {
- // no delay, pull straight from net
- if (LLProxy::isSOCKSProxyEnabled())
- {
- U8 buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
- packet_size = receive_packet(socket, static_cast<char*>(static_cast<void*>(buffer)));
-
- if (packet_size > SOCKS_HEADER_SIZE)
- {
// *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
- memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size - SOCKS_HEADER_SIZE);
+ packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
+ memcpy(datap, buffer + SOCKS_HEADER_SIZE, packet_size);
proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
mLastSender.setAddress(header->addr);
mLastSender.setPort(ntohs(header->port));
-
- packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
- }
- else
- {
- packet_size = 0;
+ mLastReceivingIF = ::get_receiving_interface();
}
}
else
{
- packet_size = receive_packet(socket, datap);
- mLastSender = ::get_sender();
+ packet_size = 0;
}
-
- mLastReceivingIF = ::get_receiving_interface();
-
- if (packet_size) // did we actually get a packet?
+ }
+ else
+ {
+ packet_size = receive_packet(socket, datap);
+ if (packet_size > 0)
{
- if (mDropPercentage && (ll_frand(100.f) < mDropPercentage))
+ mActualBytesIn += packet_size;
+ if (drop)
{
- mPacketsToDrop++;
+ packet_size = 0;
}
-
- if (mPacketsToDrop)
+ else
{
- packet_size = 0;
- mPacketsToDrop--;
+ mLastSender = ::get_sender();
+ mLastReceivingIF = ::get_receiving_interface();
}
}
}
-
return packet_size;
}
-bool LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host)
+S32 LLPacketRing::receiveOrDropBufferedPacket(char *datap, bool drop)
{
- bool status = true;
- if (!mUseOutThrottle)
+ assert(mNumBufferedPackets > 0);
+ S32 packet_size = 0;
+
+ S16 ring_size = (S16)(mPacketRing.size());
+ S16 packet_index = (mHeadIndex + ring_size - mNumBufferedPackets) % ring_size;
+ LLPacketBuffer* packet = mPacketRing[packet_index];
+ packet_size = packet->getSize();
+ mLastSender = packet->getHost();
+ mLastReceivingIF = packet->getReceivingInterface();
+
+ --mNumBufferedPackets;
+ mNumBufferedBytes -= packet_size;
+ if (mNumBufferedPackets == 0)
{
- return sendPacketImpl(h_socket, send_buffer, buf_size, host );
+ assert(mNumBufferedBytes == 0);
}
- else
+
+ if (!drop)
{
- mActualBitsOut += buf_size * 8;
- LLPacketBuffer *packetp = NULL;
- // See if we've got enough throttle to send a packet.
- while (!mOutThrottle.checkOverflow(0.f))
+ if (packet_size > 0)
+ {
+ memcpy(datap, packet->getData(), packet_size);
+ }
+ else
{
- // While we have enough bandwidth, send a packet from the queue or the current packet
+ assert(false);
+ }
+ }
+ else
+ {
+ packet_size = 0;
+ }
+ return packet_size;
+}
- S32 packet_size = 0;
- if (!mSendQueue.empty())
+S32 LLPacketRing::bufferInboundPacket(S32 socket)
+{
+ if (mNumBufferedPackets == mPacketRing.size() && mNumBufferedPackets < MAX_BUFFER_RING_SIZE)
+ {
+ expandRing();
+ }
+
+ LLPacketBuffer* packet = mPacketRing[mHeadIndex];
+ S32 old_packet_size = packet->getSize();
+ S32 packet_size = 0;
+ if (LLProxy::isSOCKSProxyEnabled())
+ {
+ char buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE]; /* Flawfinder ignore */
+ packet_size = receive_packet(socket, buffer);
+ if (packet_size > 0)
+ {
+ mActualBytesIn += packet_size;
+ if (packet_size > SOCKS_HEADER_SIZE)
{
- // Send a packet off of the queue
- LLPacketBuffer *packetp = mSendQueue.front();
- mSendQueue.pop();
+ // *FIX We are assuming ATYP is 0x01 (IPv4), not 0x03 (hostname) or 0x04 (IPv6)
- mOutBufferLength -= packetp->getSize();
- packet_size = packetp->getSize();
+ proxywrap_t * header = static_cast<proxywrap_t*>(static_cast<void*>(buffer));
+ LLHost sender;
+ sender.setAddress(header->addr);
+ sender.setPort(ntohs(header->port));
- status = sendPacketImpl(h_socket, packetp->getData(), packet_size, packetp->getHost());
+ packet_size -= SOCKS_HEADER_SIZE; // The unwrapped packet size
+ packet->init(buffer + SOCKS_HEADER_SIZE, packet_size, sender);
- delete packetp;
- // Update the throttle
- mOutThrottle.throttleOverflow(packet_size * 8.f);
+ mHeadIndex = (mHeadIndex + 1) % (S16)(mPacketRing.size());
+ if (mNumBufferedPackets < MAX_BUFFER_RING_SIZE)
+ {
+ ++mNumBufferedPackets;
+ mNumBufferedBytes += packet_size;
+ }
+ else
+ {
+ // we overwrote an older packet
+ mNumBufferedBytes += packet_size - old_packet_size;
+ }
}
else
{
- // If the queue's empty, we can just send this packet right away.
- status = sendPacketImpl(h_socket, send_buffer, buf_size, host );
- packet_size = buf_size;
-
- // Update the throttle
- mOutThrottle.throttleOverflow(packet_size * 8.f);
-
- // This was the packet we're sending now, there are no other packets
- // that we need to send
- return status;
+ packet_size = 0;
}
-
- }
-
- // We haven't sent the incoming packet, add it to the queue
- if (mOutBufferLength + buf_size > mMaxBufferLength)
- {
- // Nuke this packet, we overflowed the buffer.
- // Toss it.
- LL_WARNS() << "Throwing away outbound packet, overflowing buffer" << LL_ENDL;
}
- else
+ }
+ else
+ {
+ packet->init(socket);
+ packet_size = packet->getSize();
+ if (packet_size > 0)
{
- static LLTimer queue_timer;
- if ((mOutBufferLength > 4192) && queue_timer.getElapsedTimeF32() > 1.f)
+ mActualBytesIn += packet_size;
+
+ mHeadIndex = (mHeadIndex + 1) % (S16)(mPacketRing.size());
+ if (mNumBufferedPackets < MAX_BUFFER_RING_SIZE)
{
- // Add it to the queue
- LL_INFOS() << "Outbound packet queue " << mOutBufferLength << " bytes" << LL_ENDL;
- queue_timer.reset();
+ ++mNumBufferedPackets;
+ mNumBufferedBytes += packet_size;
+ }
+ else
+ {
+ // we overwrote an older packet
+ mNumBufferedBytes += packet_size - old_packet_size;
}
- packetp = new LLPacketBuffer(host, send_buffer, buf_size);
-
- mOutBufferLength += packetp->getSize();
- mSendQueue.push(packetp);
}
}
+ return packet_size;
+}
- return status;
+S32 LLPacketRing::drainSocket(S32 socket)
+{
+ // drain into buffer
+ S32 packet_size = 1;
+ S32 num_loops = 0;
+ S32 old_num_packets = mNumBufferedPackets;
+ while (packet_size > 0)
+ {
+ packet_size = bufferInboundPacket(socket);
+ ++num_loops;
+ }
+ S32 num_dropped_packets = (num_loops - 1 + old_num_packets) - mNumBufferedPackets;
+ if (num_dropped_packets > 0)
+ {
+ // It will eventually be accounted by mDroppedPackets
+ // and mPacketsLost, but track it here for logging purposes.
+ mNumDroppedPackets += num_dropped_packets;
+ }
+ return (S32)(mNumBufferedPackets);
}
-bool LLPacketRing::sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host)
+bool LLPacketRing::expandRing()
{
+ // compute larger size
+ constexpr S16 BUFFER_RING_EXPANSION = 256;
+ S16 old_size = (S16)(mPacketRing.size());
+ S16 new_size = llmin(old_size + BUFFER_RING_EXPANSION, MAX_BUFFER_RING_SIZE);
+ if (new_size == old_size)
+ {
+ // mPacketRing is already maxed out
+ return false;
+ }
- if (!LLProxy::isSOCKSProxyEnabled())
+ // make a larger ring and copy packet pointers
+ std::vector<LLPacketBuffer*> new_ring(new_size, nullptr);
+ for (S16 i = 0; i < old_size; ++i)
{
- return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
+ S16 j = (mHeadIndex + i) % old_size;
+ new_ring[i] = mPacketRing[j];
}
- char headered_send_buffer[NET_BUFFER_SIZE + SOCKS_HEADER_SIZE];
+ // allocate new packets for the remainder of new_ring
+ LLHost invalid_host;
+ for (S16 i = old_size; i < new_size; ++i)
+ {
+ new_ring[i] = new LLPacketBuffer(invalid_host, nullptr, 0);
+ }
- proxywrap_t *socks_header = static_cast<proxywrap_t*>(static_cast<void*>(&headered_send_buffer));
- socks_header->rsv = 0;
- socks_header->addr = host.getAddress();
- socks_header->port = htons(host.getPort());
- socks_header->atype = ADDRESS_IPV4;
- socks_header->frag = 0;
+ // swap the rings and reset mHeadIndex
+ mPacketRing.swap(new_ring);
+ mHeadIndex = mNumBufferedPackets;
+ return true;
+}
- memcpy(headered_send_buffer + SOCKS_HEADER_SIZE, send_buffer, buf_size);
+F32 LLPacketRing::getBufferLoadRate() const
+{
+ // goes up to MAX_BUFFER_RING_SIZE
+ return (F32)mNumBufferedPackets / (F32)DEFAULT_BUFFER_RING_SIZE;
+}
- return send_packet( h_socket,
- headered_send_buffer,
- buf_size + SOCKS_HEADER_SIZE,
- LLProxy::getInstance()->getUDPProxy().getAddress(),
- LLProxy::getInstance()->getUDPProxy().getPort());
+void LLPacketRing::dumpPacketRingStats()
+{
+ mNumDroppedPacketsTotal += mNumDroppedPackets;
+ LL_INFOS("Messaging") << "Packet ring stats: " << std::endl
+ << "Buffered packets: " << mNumBufferedPackets << std::endl
+ << "Buffered bytes: " << mNumBufferedBytes << std::endl
+ << "Dropped packets current: " << mNumDroppedPackets << std::endl
+ << "Dropped packets total: " << mNumDroppedPacketsTotal << std::endl
+ << "Dropped packets percentage: " << mDropPercentage << "%" << std::endl
+ << "Actual in bytes: " << mActualBytesIn << std::endl
+ << "Actual out bytes: " << mActualBytesOut << LL_ENDL;
+ mNumDroppedPackets = 0;
}
diff --git a/indra/llmessage/llpacketring.h b/indra/llmessage/llpacketring.h
index f0e95f8524..572dcbd271 100644
--- a/indra/llmessage/llpacketring.h
+++ b/indra/llmessage/llpacketring.h
@@ -25,16 +25,14 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLPACKETRING_H
-#define LL_LLPACKETRING_H
+#pragma once
-#include <queue>
+#include <vector>
#include "llhost.h"
#include "llpacketbuffer.h"
-#include "llproxy.h"
#include "llthrottle.h"
-#include "net.h"
+
class LLPacketRing
{
@@ -42,60 +40,71 @@ public:
LLPacketRing();
~LLPacketRing();
- void cleanup();
+ // receive one packet: either buffered or from the socket
+ S32 receivePacket (S32 socket, char *datap);
+
+ // send one packet
+ bool sendPacket(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
+
+ // drains packets from socket and returns final mNumBufferedPackets
+ S32 drainSocket(S32 socket);
void dropPackets(U32);
void setDropPercentage (F32 percent_to_drop);
- void setUseInThrottle(const bool use_throttle);
- void setUseOutThrottle(const bool use_throttle);
- void setInBandwidth(const F32 bps);
- void setOutBandwidth(const F32 bps);
- S32 receivePacket (S32 socket, char *datap);
- S32 receiveFromRing (S32 socket, char *datap);
- bool sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host);
+ inline LLHost getLastSender() const;
+ inline LLHost getLastReceivingInterface() const;
- inline LLHost getLastSender();
- inline LLHost getLastReceivingInterface();
+ S32 getActualInBytes() const { return mActualBytesIn; }
+ S32 getActualOutBytes() const { return mActualBytesOut; }
+ S32 getAndResetActualInBits() { S32 bits = mActualBytesIn * 8; mActualBytesIn = 0; return bits;}
+ S32 getAndResetActualOutBits() { S32 bits = mActualBytesOut * 8; mActualBytesOut = 0; return bits;}
- S32 getAndResetActualInBits() { S32 bits = mActualBitsIn; mActualBitsIn = 0; return bits;}
- S32 getAndResetActualOutBits() { S32 bits = mActualBitsOut; mActualBitsOut = 0; return bits;}
-protected:
- bool mUseInThrottle;
- bool mUseOutThrottle;
+ S32 getNumBufferedPackets() const { return (S32)(mNumBufferedPackets); }
+ S32 getNumBufferedBytes() const { return mNumBufferedBytes; }
+ S32 getNumDroppedPackets() const { return mNumDroppedPacketsTotal + mNumDroppedPackets; }
- // For simulating a lower-bandwidth connection - BPS
- LLThrottle mInThrottle;
- LLThrottle mOutThrottle;
+ F32 getBufferLoadRate() const; // from 0 to 4 (0 - empty, 1 - default size is full)
+ void dumpPacketRingStats();
+protected:
+ // returns 'true' if we should intentionally drop a packet
+ bool computeDrop();
- S32 mActualBitsIn;
- S32 mActualBitsOut;
- S32 mMaxBufferLength; // How much data can we queue up before dropping data.
- S32 mInBufferLength; // Current incoming buffer length
- S32 mOutBufferLength; // Current outgoing buffer length
+ // returns packet_size of received packet, zero or less if no packet found
+ S32 receiveOrDropPacket(S32 socket, char *datap, bool drop);
+ S32 receiveOrDropBufferedPacket(char *datap, bool drop);
- F32 mDropPercentage; // % of packets to drop
- U32 mPacketsToDrop; // drop next n packets
+ // returns packet_size of packet buffered
+ S32 bufferInboundPacket(S32 socket);
- std::queue<LLPacketBuffer *> mReceiveQueue;
- std::queue<LLPacketBuffer *> mSendQueue;
+ // returns 'true' if ring was expanded
+ bool expandRing();
+protected:
+ std::vector<LLPacketBuffer*> mPacketRing;
+ S16 mHeadIndex { 0 };
+ S16 mNumBufferedPackets { 0 };
+ S32 mNumDroppedPackets { 0 };
+ S32 mNumDroppedPacketsTotal { 0 };
+ S32 mNumBufferedBytes { 0 };
+
+ S32 mActualBytesIn { 0 };
+ S32 mActualBytesOut { 0 };
+ F32 mDropPercentage { 0.0f }; // % of inbound packets to drop
+ U32 mPacketsToDrop { 0 }; // drop next inbound n packets
+
+ // These are the sender and receiving_interface for the last packet delivered by receivePacket()
LLHost mLastSender;
LLHost mLastReceivingIF;
-
-private:
- bool sendPacketImpl(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
};
-inline LLHost LLPacketRing::getLastSender()
+inline LLHost LLPacketRing::getLastSender() const
{
return mLastSender;
}
-inline LLHost LLPacketRing::getLastReceivingInterface()
+inline LLHost LLPacketRing::getLastReceivingInterface() const
{
return mLastReceivingIF;
}
-
-#endif
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp
index d713cb20d9..5d105eba34 100644
--- a/indra/llmessage/llproxy.cpp
+++ b/indra/llmessage/llproxy.cpp
@@ -504,6 +504,7 @@ static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataou
rv = apr_socket_recv(apr_socket, datain, &maxinlen);
if (rv != APR_SUCCESS)
{
+ // if rv == 70060 it's WSAETIMEDOUT
char buf[MAX_STRING];
LL_WARNS("Proxy") << "Error receiving data from proxy control channel, status: " << rv << " " << apr_strerror(rv, buf, MAX_STRING) << LL_ENDL;
ll_apr_warn_status(rv);
diff --git a/indra/llmessage/llservice.h b/indra/llmessage/llservice.h
index 6c32fa8102..7853e357f9 100644
--- a/indra/llmessage/llservice.h
+++ b/indra/llmessage/llservice.h
@@ -31,72 +31,10 @@
#include <string>
#include <map>
-//#include <boost/intrusive_ptr.hpp>
-//#include <boost/shared_ptr.hpp>
-//#include "llframetimer.h"
#include "lliopipe.h"
#include "llchainio.h"
-#if 0
-class LLServiceCreator;
-/**
- * intrusive pointer support
- */
-namespace boost
-{
- void intrusive_ptr_add_ref(LLServiceCreator* p);
- void intrusive_ptr_release(LLServiceCreator* p);
-};
-#endif
-
-/**
- * @class LLServiceCreator
- * @brief This class is an abstract base class for classes which create
- * new <code>LLService</code> instances.
- *
- * Derive classes from this class which appropriately implement the
- * <code>operator()</code> and destructor.
- * @see LLService
- */
-#if 0
-class LLServiceCreator
-{
-public:
- typedef boost::intrusive_ptr<LLService> service_t;
- virtual ~LLServiceCreator() {}
- virtual service_t activate() = 0;
- virtual void discard() = 0;
-
-protected:
- LLServiceCreator() : mReferenceCount(0)
- {
- }
-
-private:
- friend void boost::intrusive_ptr_add_ref(LLServiceCreator* p);
- friend void boost::intrusive_ptr_release(LLServiceCreator* p);
- U32 mReferenceCount;
-};
-#endif
-
-#if 0
-namespace boost
-{
- inline void intrusive_ptr_add_ref(LLServiceCreator* p)
- {
- ++p->mReferenceCount;
- }
- inline void intrusive_ptr_release(LLServiceCreator* p)
- {
- if(p && 0 == --p->mReferenceCount)
- {
- delete p;
- }
- }
-};
-#endif
-
/**
* @class LLService
* @brief This class is the base class for the service classes.
@@ -114,8 +52,6 @@ namespace boost
class LLService : public LLIOPipe
{
public:
- //typedef boost::intrusive_ptr<LLServiceCreator> creator_t;
- //typedef boost::intrusive_ptr<LLService> service_t;
typedef std::shared_ptr<LLChainIOFactory> creator_t;
/**
diff --git a/indra/llmessage/llstoredmessage.h b/indra/llmessage/llstoredmessage.h
index 178b75ab04..2bd64fafd7 100644
--- a/indra/llmessage/llstoredmessage.h
+++ b/indra/llmessage/llstoredmessage.h
@@ -29,7 +29,6 @@
#include "linden_common.h"
#include "llsd.h"
-#include <boost/shared_ptr.hpp>
#include <string>
diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp
index 758d6d343f..883c84c6a5 100644
--- a/indra/llmessage/lltemplatemessagebuilder.cpp
+++ b/indra/llmessage/lltemplatemessagebuilder.cpp
@@ -28,6 +28,10 @@
#include "lltemplatemessagebuilder.h"
+#if __FreeBSD__
+#include <arpa/inet.h>
+#endif
+
#include "llmessagetemplate.h"
#include "llmath.h"
#include "llquaternion.h"
diff --git a/indra/llmessage/lltemplatemessagedispatcher.cpp b/indra/llmessage/lltemplatemessagedispatcher.cpp
index 0e709d6c75..edbeb4acc1 100644
--- a/indra/llmessage/lltemplatemessagedispatcher.cpp
+++ b/indra/llmessage/lltemplatemessagedispatcher.cpp
@@ -43,7 +43,7 @@ void LLTemplateMessageDispatcher::dispatch(const std::string& msg_name,
const LLSD& message,
LLHTTPNode::ResponsePtr responsep)
{
- std::vector<U8> data = message["body"]["binary-template-data"].asBinary();
+ const LLSD::Binary& data = message["body"]["binary-template-data"].asBinary();
auto size = data.size();
if(size == 0)
{
@@ -53,11 +53,11 @@ void LLTemplateMessageDispatcher::dispatch(const std::string& msg_name,
LLHost host;
host = gMessageSystem->getSender();
- bool validate_message = mTemplateMessageReader.validateMessage(&(data[0]), static_cast<S32>(size), host, true);
+ bool validate_message = mTemplateMessageReader.validateMessage(data.data(), static_cast<S32>(size), host, true);
if (validate_message)
{
- mTemplateMessageReader.readMessage(&(data[0]),host);
+ mTemplateMessageReader.readMessage(data.data(),host);
}
else
{
diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
index 1432fd1efd..7798e5692b 100644
--- a/indra/llmessage/lltemplatemessagereader.cpp
+++ b/indra/llmessage/lltemplatemessagereader.cpp
@@ -27,6 +27,10 @@
#include "linden_common.h"
#include "lltemplatemessagereader.h"
+#if __FreeBSD__
+#include <arpa/inet.h>
+#endif
+
#include "llfasttimer.h"
#include "llmessagebuilder.h"
#include "llmessagetemplate.h"
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index cfa5178fc6..ad1ff86807 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -656,8 +656,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count )
// UseCircuitCode is allowed in even from an invalid circuit, so that
// we can toss circuits around.
- if(
- valid_packet &&
+ else if (
!cdp &&
(mTemplateMessageReader->getMessageName() !=
_PREHASH_UseCircuitCode))
@@ -667,8 +666,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count )
valid_packet = false;
}
- if(
- valid_packet &&
+ if ( valid_packet &&
cdp &&
!cdp->getTrusted() &&
mTemplateMessageReader->isTrusted())
@@ -680,7 +678,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count )
valid_packet = false;
}
- if( valid_packet )
+ if ( valid_packet )
{
logValidMsg(cdp, host, recv_reliable, recv_resent, acks>0 );
valid_packet = mTemplateMessageReader->readMessage(buffer, host);
@@ -726,6 +724,7 @@ bool LLMessageSystem::checkMessages(LockMessageChecker&, S64 frame_count )
// Check to see if we need to print debug info
if ((mt_sec - mCircuitPrintTime) > mCircuitPrintFreq)
{
+ mPacketRing.dumpPacketRingStats();
dumpCircuitInfo();
mCircuitPrintTime = mt_sec;
}
@@ -821,6 +820,11 @@ void LLMessageSystem::processAcks(LockMessageChecker&, F32 collect_time)
}
}
+S32 LLMessageSystem::drainUdpSocket()
+{
+ return mPacketRing.drainSocket(mSocket);
+}
+
void LLMessageSystem::copyMessageReceivedToSend()
{
// NOTE: babbage: switch builder to match reader to avoid
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index b4b0d94021..30945cac51 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -417,6 +417,9 @@ public:
bool checkMessages(LockMessageChecker&, S64 frame_count = 0 );
void processAcks(LockMessageChecker&, F32 collect_time = 0.f);
+ // returns total number of buffered packets after the drain
+ S32 drainUdpSocket();
+
bool isMessageFast(const char *msg);
bool isMessage(const char *msg)
{
@@ -535,7 +538,6 @@ public:
//void buildMessage();
- S32 zeroCode(U8 **data, S32 *data_size);
S32 zeroCodeExpand(U8 **data, S32 *data_size);
S32 zeroCodeAdjustCurrentSendTotal();
@@ -752,6 +754,7 @@ public:
S32 getReceiveBytes() const;
S32 getUnackedListSize() const { return mUnackedListSize; }
+ F32 getBufferLoadRate() const { return mPacketRing.getBufferLoadRate(); }
//const char* getCurrentSMessageName() const { return mCurrentSMessageName; }
//const char* getCurrentSBlockName() const { return mCurrentSBlockName; }
@@ -839,12 +842,10 @@ private:
LLUUID mSessionID;
void addTemplate(LLMessageTemplate *templatep);
- bool decodeTemplate( const U8* buffer, S32 buffer_size, LLMessageTemplate** msg_template );
void logMsgFromInvalidCircuit( const LLHost& sender, bool recv_reliable );
void logTrustedMsgFromUntrustedCircuit( const LLHost& sender );
void logValidMsg(LLCircuitData *cdp, const LLHost& sender, bool recv_reliable, bool recv_resent, bool recv_acks );
- void logRanOffEndOfPacket( const LLHost& sender );
class LLMessageCountInfo
{
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index c264a9f086..21dbf35783 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -1402,3 +1402,4 @@ char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->ge
char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience");
char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID");
char const* const _PREHASH_LargeGenericMessage = LLMessageStringTable::getInstance()->getString("LargeGenericMessage");
+char const* const _PREHASH_MetaData = LLMessageStringTable::getInstance()->getString("MetaData");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 1d30b69b67..8a2ad1587c 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -1403,5 +1403,6 @@ extern char const* const _PREHASH_HoverHeight;
extern char const* const _PREHASH_Experience;
extern char const* const _PREHASH_ExperienceID;
extern char const* const _PREHASH_LargeGenericMessage;
+extern char const* const _PREHASH_MetaData;
#endif
diff --git a/indra/llmessage/net.cpp b/indra/llmessage/net.cpp
index 1c49f9be36..2be5a9e5b6 100644
--- a/indra/llmessage/net.cpp
+++ b/indra/llmessage/net.cpp
@@ -32,7 +32,7 @@
#include <stdexcept>
#if LL_WINDOWS
-#include "llwin32headerslean.h"
+#include "llwin32headers.h"
#else
#include <sys/types.h>
#include <sys/socket.h>
@@ -76,14 +76,8 @@ static U32 gsnReceivingIFAddr = INVALID_HOST_IP_ADDRESS; // Address to which dat
const char* LOOPBACK_ADDRESS_STRING = "127.0.0.1";
const char* BROADCAST_ADDRESS_STRING = "255.255.255.255";
-#if LL_DARWIN
- // macOS returns an error when trying to set these to 400000. Smaller values succeed.
- const int SEND_BUFFER_SIZE = 200000;
- const int RECEIVE_BUFFER_SIZE = 200000;
-#else // LL_DARWIN
- const int SEND_BUFFER_SIZE = 400000;
- const int RECEIVE_BUFFER_SIZE = 400000;
-#endif // LL_DARWIN
+const int SEND_BUFFER_SIZE = 200000;
+const int RECEIVE_BUFFER_SIZE = 800000;
// universal functions (cross-platform)