summaryrefslogtreecommitdiff
path: root/indra/llmessage/lltransfermanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage/lltransfermanager.cpp')
-rw-r--r--indra/llmessage/lltransfermanager.cpp150
1 files changed, 122 insertions, 28 deletions
diff --git a/indra/llmessage/lltransfermanager.cpp b/indra/llmessage/lltransfermanager.cpp
index 436363672e..34344040b8 100644
--- a/indra/llmessage/lltransfermanager.cpp
+++ b/indra/llmessage/lltransfermanager.cpp
@@ -206,30 +206,43 @@ void LLTransferManager::processTransferRequest(LLMessageSystem *msgp, void **)
return;
}
+ S32 size = msgp->getSize("TransferInfo", "Params");
+ if(size > MAX_PARAMS_SIZE)
+ {
+ llwarns << "LLTransferManager::processTransferRequest params too big."
+ << llendl;
+ return;
+ }
//llinfos << transfer_id << ":" << source_type << ":" << channel_type << ":" << priority << llendl;
- LLTransferSource *tsp = LLTransferSource::createSource(source_type, transfer_id, priority);
- if (!tsp)
+ LLTransferSource* tsp = LLTransferSource::createSource(
+ source_type,
+ transfer_id,
+ priority);
+ if(!tsp)
{
- llwarns << "LLTransferManager::processTransferRequest couldn't create transfer source!" << llendl;
+ llwarns << "LLTransferManager::processTransferRequest couldn't create"
+ << " transfer source!" << llendl;
return;
}
- tscp->addTransferSource(tsp);
-
U8 tmp[MAX_PARAMS_SIZE];
- S32 size = msgp->getSize("TransferInfo", "Params");
- gMessageSystem->getBinaryData("TransferInfo", "Params", tmp, size);
+ msgp->getBinaryData("TransferInfo", "Params", tmp, size);
LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE);
BOOL unpack_ok = tsp->unpackParams(dpb);
if (!unpack_ok)
{
- llwarns << "Got bad parameters for a transfer request!" << llendl;
+ // This should only happen if the data is corrupt or
+ // incorrectly packed.
+ // *NOTE: We may want to call abortTransfer().
+ llwarns << "LLTransferManager::processTransferRequest: bad parameters."
+ << llendl;
+ delete tsp;
+ return;
}
+ tscp->addTransferSource(tsp);
tsp->initTransfer();
- // Don't use the status code from initTransfer for anything right now, was used before but the logic
- // changed.
}
@@ -277,6 +290,31 @@ void LLTransferManager::processTransferInfo(LLMessageSystem *msgp, void **)
return;
}
+ // unpack the params
+ S32 params_size = msgp->getSize("TransferInfo", "Params");
+ if(params_size > MAX_PARAMS_SIZE)
+ {
+ llwarns << "LLTransferManager::processTransferInfo params too big."
+ << llendl;
+ return;
+ }
+ else if(params_size > 0)
+ {
+ U8 tmp[MAX_PARAMS_SIZE];
+ msgp->getBinaryData("TransferInfo", "Params", tmp, params_size);
+ LLDataPackerBinaryBuffer dpb(tmp, MAX_PARAMS_SIZE);
+ if (!ttp->unpackParams(dpb))
+ {
+ // This should only happen if the data is corrupt or
+ // incorrectly packed.
+ llwarns << "LLTransferManager::processTransferRequest: bad params."
+ << llendl;
+ ttp->abortTransfer();
+ ttcp->deleteTransfer(ttp);
+ return;
+ }
+ }
+
llinfos << "Receiving " << transfer_id << ", size " << size << " bytes" << llendl;
ttp->setSize(size);
ttp->setGotInfo(TRUE);
@@ -373,9 +411,9 @@ void LLTransferManager::processTransferPacket(LLMessageSystem *msgp, void **)
LLTransferTarget *ttp = ttcp->findTransferTarget(transfer_id);
if (!ttp)
{
- llwarns << "Didn't find matching transfer for " << transfer_id << ", aborting!" << llendl;
- llwarns << "Packet ID: " << packet_id << llendl;
- llwarns << "Should notify source of this!" << llendl;
+ llwarns << "Didn't find matching transfer for " << transfer_id
+ << " processing packet " << packet_id
+ << " from " << msgp->getSender() << llendl;
return;
}
@@ -407,11 +445,29 @@ void LLTransferManager::processTransferPacket(LLMessageSystem *msgp, void **)
if ((!ttp->gotInfo()) || (ttp->getNextPacketID() != packet_id))
{
-
- llwarns << "Out of order packet in transfer " << transfer_id << ", got " << packet_id << " expecting " << ttp->getNextPacketID() << llendl;
-
// Put this on a list of packets to be delivered later.
- ttp->addDelayedPacket(packet_id, status, tmp_data, size);
+ if(!ttp->addDelayedPacket(packet_id, status, tmp_data, size))
+ {
+ // Whoops - failed to add a delayed packet for some reason.
+ llwarns << "Too many delayed packets processing transfer "
+ << transfer_id << " from " << msgp->getSender() << llendl;
+ ttp->abortTransfer();
+ ttcp->deleteTransfer(ttp);
+ return;
+ }
+ const S32 LL_TRANSFER_WARN_GAP = 10;
+ if(!ttp->gotInfo())
+ {
+ llwarns << "Got data packet before information in transfer "
+ << transfer_id << " from " << msgp->getSender()
+ << ", got " << packet_id << llendl;
+ }
+ else if((packet_id - ttp->getNextPacketID()) > LL_TRANSFER_WARN_GAP)
+ {
+ llwarns << "Out of order packet in transfer " << transfer_id
+ << " from " << msgp->getSender() << ", got " << packet_id
+ << " expecting " << ttp->getNextPacketID() << llendl;
+ }
return;
}
@@ -862,13 +918,17 @@ LLTransferTargetChannel::~LLTransferTargetChannel()
}
-void LLTransferTargetChannel::requestTransfer(const LLTransferSourceParams &source_params,
- const LLTransferTargetParams &target_params,
- const F32 priority)
+void LLTransferTargetChannel::requestTransfer(
+ const LLTransferSourceParams& source_params,
+ const LLTransferTargetParams& target_params,
+ const F32 priority)
{
LLUUID id;
id.generate();
- LLTransferTarget *ttp = LLTransferTarget::createTarget(target_params.getType(), id);
+ LLTransferTarget* ttp = LLTransferTarget::createTarget(
+ target_params.getType(),
+ id,
+ source_params.getType());
if (!ttp)
{
llwarns << "LLTransferManager::requestTransfer aborting due to target creation failure!" << llendl;
@@ -988,6 +1048,11 @@ void LLTransferSource::sendTransferStatus(LLTSCode status)
gMessageSystem->addS32("ChannelType", mChannelp->getChannelType());
gMessageSystem->addS32("Status", status);
gMessageSystem->addS32("Size", mSize);
+ U8 tmp[MAX_PARAMS_SIZE];
+ LLDataPackerBinaryBuffer dp(tmp, MAX_PARAMS_SIZE);
+ packParams(dp);
+ S32 len = dp.getCurrentSize();
+ gMessageSystem->addBinaryData("Params", tmp, len);
gMessageSystem->sendReliable(mChannelp->getHost());
// Abort if there was as asset system issue.
@@ -1105,9 +1170,13 @@ LLTransferPacket::~LLTransferPacket()
// LLTransferTarget implementation
//
-LLTransferTarget::LLTransferTarget(LLTransferTargetType type, const LLUUID &id) :
+LLTransferTarget::LLTransferTarget(
+ LLTransferTargetType type,
+ const LLUUID& transfer_id,
+ LLTransferSourceType source_type) :
mType(type),
- mID(id),
+ mSourceType(source_type),
+ mID(transfer_id),
mGotInfo(FALSE),
mSize(0),
mLastPacketID(-1)
@@ -1143,27 +1212,48 @@ void LLTransferTarget::abortTransfer()
completionCallback(LLTS_ABORT);
}
-void LLTransferTarget::addDelayedPacket(const S32 packet_id, const LLTSCode status, U8 *datap, const S32 size)
+bool LLTransferTarget::addDelayedPacket(
+ const S32 packet_id,
+ const LLTSCode status,
+ U8* datap,
+ const S32 size)
{
- LLTransferPacket *tpp = new LLTransferPacket(packet_id, status, datap, size);
+ const transfer_packet_map::size_type LL_MAX_DELAYED_PACKETS = 100;
+ if(mDelayedPacketMap.size() > LL_MAX_DELAYED_PACKETS)
+ {
+ // too many delayed packets
+ return false;
+ }
+
+ LLTransferPacket* tpp = new LLTransferPacket(
+ packet_id,
+ status,
+ datap,
+ size);
+
#ifdef _DEBUG
if (mDelayedPacketMap.find(packet_id) != mDelayedPacketMap.end())
{
llerrs << "Packet ALREADY in delayed packet map!" << llendl;
}
#endif
+
mDelayedPacketMap[packet_id] = tpp;
+ return true;
}
-LLTransferTarget *LLTransferTarget::createTarget(const LLTransferTargetType type, const LLUUID &id)
+LLTransferTarget* LLTransferTarget::createTarget(
+ LLTransferTargetType type,
+ const LLUUID& id,
+ LLTransferSourceType source_type)
{
switch (type)
{
case LLTTT_FILE:
- return new LLTransferTargetFile(id);
+ return new LLTransferTargetFile(id, source_type);
case LLTTT_VFILE:
- return new LLTransferTargetVFile(id);
+ return new LLTransferTargetVFile(id, source_type);
default:
llwarns << "Unknown transfer target type: " << type << llendl;
return NULL;
@@ -1200,6 +1290,7 @@ void LLTransferSourceParamsInvItem::setAsset(const LLUUID &asset_id, const LLAss
void LLTransferSourceParamsInvItem::packParams(LLDataPacker &dp) const
{
+ lldebugs << "LLTransferSourceParamsInvItem::packParams()" << llendl;
dp.packUUID(mAgentID, "AgentID");
dp.packUUID(mSessionID, "SessionID");
dp.packUUID(mOwnerID, "OwnerID");
@@ -1252,6 +1343,9 @@ void LLTransferSourceParamsEstate::setAsset(const LLUUID &asset_id, const LLAsse
void LLTransferSourceParamsEstate::packParams(LLDataPacker &dp) const
{
dp.packUUID(mAgentID, "AgentID");
+ // *NOTE: We do not want to pass the session id from the server to
+ // the client, but I am not sure if anyone expects this value to
+ // be set on the client.
dp.packUUID(mSessionID, "SessionID");
dp.packS32(mEstateAssetType, "EstateAssetType");
}