Switched TransferRequest (UDP packet handler) to sync. The permissions checks may block, so they get a FireAndForget. Everything else is non-blocking.

cpu-performance
Diva Canto 2013-07-11 09:44:48 -07:00
parent 9173130fde
commit 3b48b6a792
1 changed files with 126 additions and 110 deletions

View File

@ -5374,7 +5374,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.ObjectClickAction, HandleObjectClickAction, false);
AddLocalPacketHandler(PacketType.ObjectMaterial, HandleObjectMaterial, false);
AddLocalPacketHandler(PacketType.RequestImage, HandleRequestImage, false);
AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest);
AddLocalPacketHandler(PacketType.TransferRequest, HandleTransferRequest, false);
AddLocalPacketHandler(PacketType.AssetUploadRequest, HandleAssetUploadRequest);
AddLocalPacketHandler(PacketType.RequestXfer, HandleRequestXfer);
AddLocalPacketHandler(PacketType.SendXferPacket, HandleSendXferPacket);
@ -7751,129 +7751,145 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request");
TransferRequestPacket transfer = (TransferRequestPacket)Pack;
//m_log.Debug("Transfer Request: " + transfer.ToString());
// Validate inventory transfers
// Has to be done here, because AssetCache can't do it
//
UUID taskID = UUID.Zero;
if (transfer.TransferInfo.SourceType == (int)SourceType.SimInventoryItem)
{
taskID = new UUID(transfer.TransferInfo.Params, 48);
UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
// m_log.DebugFormat(
// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
// requestID, itemID, taskID, Name);
if (!(((Scene)m_scene).Permissions.BypassPermissions()))
{
if (taskID != UUID.Zero) // Prim
// We're spawning a thread because the permissions check can block this thread
Util.FireAndForget(delegate
{
SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
if (part == null)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
Name, requestID, itemID, taskID);
return true;
}
TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
if (tii == null)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
Name, requestID, itemID, taskID);
return true;
}
if (tii.Type == (int)AssetType.LSLText)
{
if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
return true;
}
else if (tii.Type == (int)AssetType.Notecard)
{
if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
return true;
}
else
{
// TODO: Change this code to allow items other than notecards and scripts to be successfully
// shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
if (part.OwnerID != AgentId)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
Name, requestID, itemID, taskID, part.OwnerID);
return true;
}
if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
Name, requestID, itemID, taskID);
return true;
}
if (tii.OwnerID != AgentId)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
Name, requestID, itemID, taskID, tii.OwnerID);
return true;
}
if ((
tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
!= ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
Name, requestID, itemID, taskID);
return true;
}
if (tii.AssetID != requestID)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}",
Name, requestID, itemID, taskID, tii.AssetID);
return true;
}
}
}
else // Agent
{
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null)
{
if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
return false;
}
else
{
return false;
}
}
// This requests the asset if needed
HandleSimInventoryTransferRequestWithPermsCheck(sender, transfer);
});
return true;
}
}
else
if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
{
//TransferRequestPacket does not include covenant uuid?
//get scene covenant uuid
taskID = m_scene.RegionInfo.RegionSettings.Covenant;
}
else if (transfer.TransferInfo.SourceType == (int)SourceType.SimEstate)
{
//TransferRequestPacket does not include covenant uuid?
//get scene covenant uuid
taskID = m_scene.RegionInfo.RegionSettings.Covenant;
}
// This is non-blocking
MakeAssetRequest(transfer, taskID);
return true;
}
private void HandleSimInventoryTransferRequestWithPermsCheck(IClientAPI sender, TransferRequestPacket transfer)
{
UUID taskID = new UUID(transfer.TransferInfo.Params, 48);
UUID itemID = new UUID(transfer.TransferInfo.Params, 64);
UUID requestID = new UUID(transfer.TransferInfo.Params, 80);
//m_log.DebugFormat(
// "[CLIENT]: Got request for asset {0} from item {1} in prim {2} by {3}",
// requestID, itemID, taskID, Name);
//m_log.Debug("Transfer Request: " + transfer.ToString());
// Validate inventory transfers
// Has to be done here, because AssetCache can't do it
//
if (taskID != UUID.Zero) // Prim
{
SceneObjectPart part = ((Scene)m_scene).GetSceneObjectPart(taskID);
if (part == null)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but prim does not exist",
Name, requestID, itemID, taskID);
return;
}
TaskInventoryItem tii = part.Inventory.GetInventoryItem(itemID);
if (tii == null)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item does not exist",
Name, requestID, itemID, taskID);
return;
}
if (tii.Type == (int)AssetType.LSLText)
{
if (!((Scene)m_scene).Permissions.CanEditScript(itemID, taskID, AgentId))
return;
}
else if (tii.Type == (int)AssetType.Notecard)
{
if (!((Scene)m_scene).Permissions.CanEditNotecard(itemID, taskID, AgentId))
return;
}
else
{
// TODO: Change this code to allow items other than notecards and scripts to be successfully
// shared with group. In fact, this whole block of permissions checking should move to an IPermissionsModule
if (part.OwnerID != AgentId)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the prim is owned by {4}",
Name, requestID, itemID, taskID, part.OwnerID);
return;
}
if ((part.OwnerMask & (uint)PermissionMask.Modify) == 0)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but modify permissions are not set",
Name, requestID, itemID, taskID);
return;
}
if (tii.OwnerID != AgentId)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but the item is owned by {4}",
Name, requestID, itemID, taskID, tii.OwnerID);
return;
}
if ((
tii.CurrentPermissions & ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
!= ((uint)PermissionMask.Modify | (uint)PermissionMask.Copy | (uint)PermissionMask.Transfer))
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but item permissions are not modify/copy/transfer",
Name, requestID, itemID, taskID);
return;
}
if (tii.AssetID != requestID)
{
m_log.WarnFormat(
"[CLIENT]: {0} requested asset {1} from item {2} in prim {3} but this does not match item's asset {4}",
Name, requestID, itemID, taskID, tii.AssetID);
return;
}
}
}
else // Agent
{
IInventoryAccessModule invAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>();
if (invAccess != null)
{
if (!invAccess.CanGetAgentInventoryItem(this, itemID, requestID))
return;
}
else
{
return;
}
}
// Permissions out of the way, let's request the asset
MakeAssetRequest(transfer, taskID);
}
private bool HandleAssetUploadRequest(IClientAPI sender, Packet Pack)
{
AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;