From 83d6722d31a3deb51b34a18c46bb4a904902dff0 Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Sat, 6 Aug 2016 22:12:38 +0100
Subject: if a viewer overloads region capability to process RequestMapBlocks,
ignore following requests for 300 seconds. This was necessary becaus some
viewers like FireStorm are doing it, saturating region and grid services for
no usefull reason
---
.../CoreModules/World/WorldMap/WorldMapModule.cs | 75 ++++++++++++++++++----
1 file changed, 64 insertions(+), 11 deletions(-)
(limited to 'OpenSim/Region')
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
index 6f10f51..959829c 100644
--- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
+++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs
@@ -1060,27 +1060,80 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
///
public void RequestMapBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
{
- m_log.DebugFormat("[WoldMapModule] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
+// m_log.DebugFormat("[WoldMapModule] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
GetAndSendBlocks(remoteClient, minX, minY, maxX, maxY, flag);
}
+ private const double SPAMBLOCKTIMEms = 300000; // 5 minutes
+ private Dictionary spamBlocked = new Dictionary();
+
protected virtual List GetAndSendBlocks(IClientAPI remoteClient, int minX, int minY, int maxX, int maxY, uint flag)
{
- MapBlockRequestData req = new MapBlockRequestData();
+ // anti spam because of FireStorm 4.7.7 absurd request repeat rates
+ // possible others
- req.client = remoteClient;
- req.minX = minX;
- req.maxX = maxX;
- req.minY = minY;
- req.maxY = maxY;
- req.flags = flag;
+ double now = Util.GetTimeStampMS();
+ UUID agentID = remoteClient.AgentId;
lock (m_mapBlockRequestEvent)
{
- if (!m_mapBlockRequests.ContainsKey(remoteClient.AgentId))
- m_mapBlockRequests[remoteClient.AgentId] = new Queue();
- m_mapBlockRequests[remoteClient.AgentId].Enqueue(req);
+ if(spamBlocked.ContainsKey(agentID))
+ {
+ if(spamBlocked[agentID] < now &&
+ (!m_mapBlockRequests.ContainsKey(agentID) ||
+ m_mapBlockRequests[agentID].Count == 0 ))
+ {
+ spamBlocked.Remove(agentID);
+ m_log.DebugFormat("[WoldMapModule] RequestMapBlocks release spammer {0}", agentID);
+ }
+ else
+ return new List();
+ }
+ else
+ {
+ // ugly slow expire spammers
+ if(spamBlocked.Count > 0)
+ {
+ UUID k = UUID.Zero;
+ bool expireone = false;
+ foreach(UUID k2 in spamBlocked.Keys)
+ {
+ if(spamBlocked[k2] < now &&
+ (!m_mapBlockRequests.ContainsKey(k2) ||
+ m_mapBlockRequests[k2].Count == 0 ))
+ {
+ m_log.DebugFormat("[WoldMapModule] RequestMapBlocks release spammer {0}", k2);
+ k = k2;
+ expireone = true;
+ }
+ break; // doing one at a time
+ }
+ if(expireone)
+ spamBlocked.Remove(k);
+ }
+ }
+
+// m_log.DebugFormat("[WoldMapModule] RequestMapBlocks {0}={1}={2}={3} {4}", minX, minY, maxX, maxY, flag);
+
+ MapBlockRequestData req = new MapBlockRequestData();
+
+ req.client = remoteClient;
+ req.minX = minX;
+ req.maxX = maxX;
+ req.minY = minY;
+ req.maxY = maxY;
+ req.flags = flag;
+
+ if (!m_mapBlockRequests.ContainsKey(agentID))
+ m_mapBlockRequests[agentID] = new Queue();
+ if(m_mapBlockRequests[agentID].Count < 150 )
+ m_mapBlockRequests[agentID].Enqueue(req);
+ else
+ {
+ spamBlocked[agentID] = now + SPAMBLOCKTIMEms;
+ m_log.DebugFormat("[WoldMapModule] RequestMapBlocks blocking spammer {0} for {1} s",agentID, SPAMBLOCKTIMEms/1000.0);
+ }
m_mapBlockRequestEvent.Set();
}
--
cgit v1.1