From e6acc57e0b218a40957adb6c8de11aa1533da904 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Mon, 10 Aug 2020 20:49:41 +0100 Subject: [PATCH] a few changes on (HG)EntityTransfer plus a few use of ExpiringcacheOS --- OpenSim/Framework/Util.cs | 2 +- .../ClientStack/Linden/UDP/LLUDPServer.cs | 8 +- .../EntityTransfer/EntityTransferModule.cs | 138 ++++++++++++------ .../EntityTransfer/HGEntityTransferModule.cs | 21 +-- 4 files changed, 110 insertions(+), 59 deletions(-) diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index ad6bfb1a21..4246dc96df 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1296,7 +1296,7 @@ namespace OpenSim.Framework return output.ToString(); } - private static ExpiringCache dnscache = new ExpiringCache(); + private static ExpiringCacheOS dnscache = new ExpiringCacheOS(10000); /// /// Converts a URL to a IPAddress diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index b1df1b69af..63a5eb25c1 100755 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -326,7 +326,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// Flag to signal when clients should send pings protected bool m_sendPing; - protected ExpiringCache> m_pendingCache = new ExpiringCache>(); + protected ExpiringCacheOS> m_pendingCache = new ExpiringCacheOS>(10000); protected int m_defaultRTO = 0; protected int m_maxRTO = 0; @@ -1338,8 +1338,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // If this is a pending connection, enqueue, don't process yet lock (m_pendingCache) { - Queue queue; - if (m_pendingCache.TryGetValue(endPoint, out queue)) + if (m_pendingCache.TryGetValue(endPoint, out Queue queue)) { //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); queue.Enqueue(buffer); @@ -1654,12 +1653,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP return; } - // Now we know we can handle more data - //Thread.Sleep(200); // Obtain the pending queue and remove it from the cache Queue queue = null; - lock (m_pendingCache) { if (!m_pendingCache.TryGetValue(endPoint, out queue)) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index fa49546ee6..896583bff4 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -49,19 +49,49 @@ using Mono.Addins; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")] - public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule + public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule, IDisposable { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]"; private static readonly string OutfitTPError = "destination region does not support the Outfit you are wearing. Please retry with a simpler one"; - public const bool WaitForAgentArrivedAtDestinationDefault = true; + public EntityTransferModule() + { + } + + ~EntityTransferModule() + { + Dispose(false); + } + + public void Dispose() + { + if (!disposed) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + bool disposed; + private void Dispose(bool disposing) + { + if (!disposed) + { + disposed = true; + if(m_bannedRegionCache != null) + { + m_bannedRegionCache.Dispose(); + m_bannedRegionCache = null; + } + } + } /// /// If true then on a teleport, the source region waits for a callback from the destination region. If /// a callback fails to arrive within a set time then the user is pulled back into the source region. /// - public bool WaitForAgentArrivedAtDestination { get; set; } + public bool WaitForAgentArrivedAtDestination { get; set; } = true; /// /// If true then we ask the viewer to disable teleport cancellation and ignore teleport requests. @@ -116,51 +146,78 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // to the grid service. private class BannedRegionCache { - private ExpiringCache> m_bannedRegions = - new ExpiringCache>(); - ExpiringCache m_idCache; - DateTime m_banUntil; + private ExpiringCacheOS> m_bannedRegions = + new ExpiringCacheOS>(15000); + public BannedRegionCache() { } + + ~BannedRegionCache() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + if (m_bannedRegions != null) + { + m_bannedRegions.Dispose(); + m_bannedRegions = null; + } + } + // Return 'true' if there is a valid ban entry for this agent in this region public bool IfBanned(ulong pRegionHandle, UUID pAgentID) { - bool ret = false; - if (m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) + if (m_bannedRegions.TryGetValue(pAgentID, out Dictionary idCache)) { - if (m_idCache.TryGetValue(pRegionHandle, out m_banUntil)) + lock(idCache) { - if (DateTime.UtcNow < m_banUntil) + if (idCache.TryGetValue(pRegionHandle, out double exp)) { - ret = true; + if(exp < Util.GetTimeStamp()) + return true; + else + idCache.Remove(pRegionHandle); } } } - return ret; - } - // Add this agent in this region as a banned person - public void Add(ulong pRegionHandle, UUID pAgentID) - { - this.Add(pRegionHandle, pAgentID, 45, 15); + return false; } - public void Add(ulong pRegionHandle, UUID pAgentID, double newTime, double extendTime) + public void Add(ulong pRegionHandle, UUID pAgentID, double newTime) { - if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) + Dictionary idCache; + if (!m_bannedRegions.TryGetValue(pAgentID, out idCache)) { - m_idCache = new ExpiringCache(); - m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(newTime)); + idCache = new Dictionary(); + idCache[pRegionHandle] = Util.GetTimeStamp() + newTime; + m_bannedRegions.AddOrUpdate(pAgentID, idCache, newTime); + } + else + { + lock(idCache) + { + idCache[pRegionHandle] = Util.GetTimeStamp() + newTime; + m_bannedRegions.AddOrUpdate(pAgentID, idCache, newTime); + } } - m_idCache.Add(pRegionHandle, DateTime.UtcNow + TimeSpan.FromSeconds(extendTime), extendTime); } // Remove the agent from the region's banned list public void Remove(ulong pRegionHandle, UUID pAgentID) { - if (m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) + if (m_bannedRegions.TryGetValue(pAgentID, out Dictionary idCache)) { - m_idCache.Remove(pRegionHandle); + lock (idCache) + idCache.Remove(pRegionHandle); } } } @@ -220,7 +277,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false); WaitForAgentArrivedAtDestination - = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestinationDefault); + = transferConfig.GetBoolean("wait_for_callback", WaitForAgentArrivedAtDestination); } @@ -309,7 +366,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer client.OnConnectionClosed += OnConnectionClosed; } - public virtual void Close() {} + public virtual void Close() + { + Dispose(); + } public virtual void RemoveRegion(Scene scene) { @@ -319,6 +379,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer StatsManager.DeregisterStat(m_interRegionTeleportAborts); StatsManager.DeregisterStat(m_interRegionTeleportCancels); StatsManager.DeregisterStat(m_interRegionTeleportFailures); + scene.EventManager.OnNewClient -= OnNewClient; } } @@ -334,7 +395,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Teleports - private void OnConnectionClosed(IClientAPI client) + public virtual void OnConnectionClosed(IClientAPI client) { if (client.IsLoggingOut && m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting)) { @@ -1066,15 +1127,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } } - else - { - if(!sp.IsInLocalTransit || sp.RegionViewDistance == 0) - { - // this will be closed by callback - if (agentCircuit.ChildrenCapSeeds != null) - agentCircuit.ChildrenCapSeeds.Remove(sp.RegionHandle); - } - } + + if (OutSideViewRange && agentCircuit.ChildrenCapSeeds != null) + agentCircuit.ChildrenCapSeeds.Remove(sp.RegionHandle); string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);; @@ -1221,7 +1276,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer break; } while (--count > 0); - if (!sp.IsDeleted) { m_log.DebugFormat( @@ -1495,13 +1549,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!ascene.SimulationService.QueryAccess(destiny, agentID, homeURI, false, position, agent.Scene.GetFormatsOffered(), ctx, out reason)) { - m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0); + m_bannedRegionCache.Add(destinyHandle, agentID, 30.0); return false; } if (!agent.Appearance.CanTeleport(ctx.OutboundVersion)) { reason = OutfitTPError; - m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0); + m_bannedRegionCache.Add(destinyHandle, agentID, 30.0); return false; } @@ -1542,8 +1596,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return null; } - m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID); - // Compute the entity's position relative to the new region newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX), (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), @@ -1556,7 +1608,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer scene.GetFormatsOffered(), ctx, out failureReason)) { // remember the fail - m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID); + m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID, 45); if(String.IsNullOrWhiteSpace(failureReason)) failureReason = "Access Denied"; return null; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 8bbb70e851..6c5b699e29 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -183,13 +183,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } - protected override void OnNewClient(IClientAPI client) - { - client.OnTeleportHomeRequest += TriggerTeleportHome; - client.OnTeleportLandmarkRequest += RequestTeleportLandmark; - client.OnConnectionClosed += new Action(OnConnectionClosed); - } - public override void RegionLoaded(Scene scene) { base.RegionLoaded(scene); @@ -639,11 +632,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override bool HandleIncomingSceneObject(SceneObjectGroup so, Vector3 newPosition) { + UUID OwnerID = so.OwnerID; + if (Scene.RegionInfo.EstateSettings.IsBanned(OwnerID)) + { + m_log.DebugFormat( + "[HG TRANSFER MODULE]: Denied prim crossing of {0} {1} into {2} for banned avatar {3}", + so.Name, so.UUID, Scene.Name, so.OwnerID); + + return false; + } + // FIXME: We must make it so that we can use SOG.IsAttachment here. At the moment it is always null! if (!so.IsAttachmentCheckFull()) return base.HandleIncomingSceneObject(so, newPosition); - UUID OwnerID = so.OwnerID; // Equally, we can't use so.AttachedAvatar here. if (OwnerID == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(OwnerID)) return base.HandleIncomingSceneObject(so, newPosition); @@ -760,7 +762,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } - void OnConnectionClosed(IClientAPI obj) + public override void OnConnectionClosed(IClientAPI obj) { if (obj.SceneAgent.IsChildAgent) return; @@ -788,6 +790,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId); } + base.OnConnectionClosed(obj); } #endregion