aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs9
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs21
-rw-r--r--OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs2
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs7
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs139
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs227
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs75
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs61
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs7
9 files changed, 400 insertions, 148 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 185f9ce..cc69645 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -163,8 +163,8 @@ namespace OpenSim.Region.ClientStack.Linden
163 m_HostCapsObj.RegisterHandler( 163 m_HostCapsObj.RegisterHandler(
164 "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null)); 164 "SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
165 165
166 m_log.DebugFormat( 166// m_log.DebugFormat(
167 "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID); 167// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
168 168
169 //m_capsHandlers["MapLayer"] = 169 //m_capsHandlers["MapLayer"] =
170 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST", 170 // new LLSDStreamhandler<OSDMapRequest, OSDMapLayerResponse>("POST",
@@ -254,11 +254,12 @@ namespace OpenSim.Region.ClientStack.Linden
254 public string SeedCapRequest(string request, string path, string param, 254 public string SeedCapRequest(string request, string path, string param,
255 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) 255 IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
256 { 256 {
257// m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName); 257 m_log.DebugFormat(
258 "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
258 259
259 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint)) 260 if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
260 { 261 {
261 m_log.DebugFormat( 262 m_log.WarnFormat(
262 "[CAPS]: Unauthorized CAPS client {0} from {1}", 263 "[CAPS]: Unauthorized CAPS client {0} from {1}",
263 m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint); 264 m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
264 265
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 594b229..47cb049 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden
94 94
95 //scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack); 95 //scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
96 96
97 scene.EventManager.OnNewClient += OnNewClient; 97// scene.EventManager.OnNewClient += OnNewClient;
98 98
99 // TODO: Leaving these open, or closing them when we 99 // TODO: Leaving these open, or closing them when we
100 // become a child is incorrect. It messes up TP in a big 100 // become a child is incorrect. It messes up TP in a big
@@ -102,6 +102,7 @@ namespace OpenSim.Region.ClientStack.Linden
102 // circuit is there. 102 // circuit is there.
103 103
104 scene.EventManager.OnClientClosed += ClientClosed; 104 scene.EventManager.OnClientClosed += ClientClosed;
105
105 scene.EventManager.OnMakeChildAgent += MakeChildAgent; 106 scene.EventManager.OnMakeChildAgent += MakeChildAgent;
106 scene.EventManager.OnRegisterCaps += OnRegisterCaps; 107 scene.EventManager.OnRegisterCaps += OnRegisterCaps;
107 108
@@ -110,10 +111,10 @@ namespace OpenSim.Region.ClientStack.Linden
110 false, 111 false,
111 "debug eq", 112 "debug eq",
112 "debug eq [0|1|2]", 113 "debug eq [0|1|2]",
113 "Turn on event queue debugging" 114 "Turn on event queue debugging\n"
114 + "<= 0 - turns off all event queue logging" 115 + " <= 0 - turns off all event queue logging\n"
115 + ">= 1 - turns on outgoing event logging" 116 + " >= 1 - turns on outgoing event logging\n"
116 + ">= 2 - turns on poll notification", 117 + " >= 2 - turns on poll notification",
117 HandleDebugEq); 118 HandleDebugEq);
118 } 119 }
119 else 120 else
@@ -226,16 +227,6 @@ namespace OpenSim.Region.ClientStack.Linden
226 227
227 #endregion 228 #endregion
228 229
229 private void OnNewClient(IClientAPI client)
230 {
231 //client.OnLogout += ClientClosed;
232 }
233
234// private void ClientClosed(IClientAPI client)
235// {
236// ClientClosed(client.AgentId);
237// }
238
239 private void ClientClosed(UUID agentID, Scene scene) 230 private void ClientClosed(UUID agentID, Scene scene)
240 { 231 {
241// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName); 232// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index 36af55f..17c7270 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -107,7 +107,7 @@ namespace OpenSim.Region.ClientStack.Linden
107 107
108 UUID capID = UUID.Random(); 108 UUID capID = UUID.Random();
109 109
110 m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName); 110// m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
111 caps.RegisterHandler( 111 caps.RegisterHandler(
112 "SimConsoleAsync", 112 "SimConsoleAsync",
113 new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene)); 113 new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene));
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
index 1b8535c..e22670b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
@@ -45,7 +45,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
45 public Packet Packet; 45 public Packet Packet;
46 46
47 /// <summary> 47 /// <summary>
48 /// Default constructor 48 /// No arg constructor.
49 /// </summary>
50 public IncomingPacket() {}
51
52 /// <summary>
53 /// Constructor
49 /// </summary> 54 /// </summary>
50 /// <param name="client">Reference to the client this packet came from</param> 55 /// <param name="client">Reference to the client this packet came from</param>
51 /// <param name="packet">Packet data</param> 56 /// <param name="packet">Packet data</param>
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 62f51d9..7427c59 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -347,7 +347,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
347 private int m_moneyBalance; 347 private int m_moneyBalance;
348 private int m_animationSequenceNumber = 1; 348 private int m_animationSequenceNumber = 1;
349 private bool m_SendLogoutPacketWhenClosing = true; 349 private bool m_SendLogoutPacketWhenClosing = true;
350 private AgentUpdateArgs lastarg; 350
351 /// <summary>
352 /// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for
353 /// every single incoming AgentUpdate. Every client sends 10 AgentUpdate UDP messages per second, even if it
354 /// is doing absolutely nothing.
355 /// </summary>
356 /// <remarks>
357 /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
358 /// cannot retain a reference to it outside of that method.
359 /// </remarks>
360 private AgentUpdateArgs m_lastAgentUpdateArgs;
351 361
352 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>(); 362 protected Dictionary<PacketType, PacketProcessor> m_packetHandlers = new Dictionary<PacketType, PacketProcessor>();
353 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 363 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
@@ -3922,7 +3932,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3922 { 3932 {
3923 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value; 3933 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
3924 3934
3925 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3935 ImprovedTerseObjectUpdatePacket packet
3936 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3937
3926 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3938 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3927 packet.RegionData.TimeDilation = timeDilation; 3939 packet.RegionData.TimeDilation = timeDilation;
3928 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3940 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -3967,7 +3979,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3967 { 3979 {
3968 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value; 3980 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
3969 3981
3970 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 3982 ImprovedTerseObjectUpdatePacket packet
3983 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
3984 PacketType.ImprovedTerseObjectUpdate);
3985
3971 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 3986 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
3972 packet.RegionData.TimeDilation = timeDilation; 3987 packet.RegionData.TimeDilation = timeDilation;
3973 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 3988 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -4959,7 +4974,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4959 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2; 4974 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
4960 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2; 4975 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
4961 4976
4962 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock(); 4977 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block
4978 = PacketPool.Instance.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4979
4963 block.Data = data; 4980 block.Data = data;
4964 4981
4965 if (textureEntry != null && textureEntry.Length > 0) 4982 if (textureEntry != null && textureEntry.Length > 0)
@@ -5191,7 +5208,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5191 protected virtual void RegisterLocalPacketHandlers() 5208 protected virtual void RegisterLocalPacketHandlers()
5192 { 5209 {
5193 AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout); 5210 AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
5211
5212 // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
5213 // for each AgentUpdate packet.
5194 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); 5214 AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
5215
5195 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); 5216 AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
5196 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); 5217 AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
5197 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); 5218 AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
@@ -5418,80 +5439,83 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5418 5439
5419 #region Scene/Avatar 5440 #region Scene/Avatar
5420 5441
5421 private bool HandleAgentUpdate(IClientAPI sener, Packet Pack) 5442 private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
5422 { 5443 {
5423 if (OnAgentUpdate != null) 5444 if (OnAgentUpdate != null)
5424 { 5445 {
5425 bool update = false; 5446 AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
5426 AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
5427 5447
5428 #region Packet Session and User Check 5448 #region Packet Session and User Check
5429 if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId) 5449 if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId)
5450 {
5451 PacketPool.Instance.ReturnPacket(packet);
5430 return false; 5452 return false;
5453 }
5431 #endregion 5454 #endregion
5432 5455
5433 AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData; 5456 bool update = false;
5434 5457 AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
5435 // We can only check when we have something to check
5436 // against.
5437 5458
5438 if (lastarg != null) 5459 if (m_lastAgentUpdateArgs != null)
5439 { 5460 {
5461 // These should be ordered from most-likely to
5462 // least likely to change. I've made an initial
5463 // guess at that.
5440 update = 5464 update =
5441 ( 5465 (
5442 (x.BodyRotation != lastarg.BodyRotation) || 5466 (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) ||
5443 (x.CameraAtAxis != lastarg.CameraAtAxis) || 5467 (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) ||
5444 (x.CameraCenter != lastarg.CameraCenter) || 5468 (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
5445 (x.CameraLeftAxis != lastarg.CameraLeftAxis) || 5469 (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
5446 (x.CameraUpAxis != lastarg.CameraUpAxis) || 5470 (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
5447 (x.ControlFlags != lastarg.ControlFlags) || 5471 (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
5448 (x.Far != lastarg.Far) || 5472 (x.Far != m_lastAgentUpdateArgs.Far) ||
5449 (x.Flags != lastarg.Flags) || 5473 (x.Flags != m_lastAgentUpdateArgs.Flags) ||
5450 (x.State != lastarg.State) || 5474 (x.State != m_lastAgentUpdateArgs.State) ||
5451 (x.HeadRotation != lastarg.HeadRotation) || 5475 (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
5452 (x.SessionID != lastarg.SessionID) || 5476 (x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
5453 (x.AgentID != lastarg.AgentID) 5477 (x.AgentID != m_lastAgentUpdateArgs.AgentID)
5454 ); 5478 );
5455 } 5479 }
5456 else 5480 else
5457 { 5481 {
5482 m_lastAgentUpdateArgs = new AgentUpdateArgs();
5458 update = true; 5483 update = true;
5459 } 5484 }
5460 5485
5461 // These should be ordered from most-likely to
5462 // least likely to change. I've made an initial
5463 // guess at that.
5464
5465 if (update) 5486 if (update)
5466 { 5487 {
5467// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name); 5488// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
5468 5489
5469 AgentUpdateArgs arg = new AgentUpdateArgs(); 5490 m_lastAgentUpdateArgs.AgentID = x.AgentID;
5470 arg.AgentID = x.AgentID; 5491 m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation;
5471 arg.BodyRotation = x.BodyRotation; 5492 m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
5472 arg.CameraAtAxis = x.CameraAtAxis; 5493 m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter;
5473 arg.CameraCenter = x.CameraCenter; 5494 m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
5474 arg.CameraLeftAxis = x.CameraLeftAxis; 5495 m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
5475 arg.CameraUpAxis = x.CameraUpAxis; 5496 m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags;
5476 arg.ControlFlags = x.ControlFlags; 5497 m_lastAgentUpdateArgs.Far = x.Far;
5477 arg.Far = x.Far; 5498 m_lastAgentUpdateArgs.Flags = x.Flags;
5478 arg.Flags = x.Flags; 5499 m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
5479 arg.HeadRotation = x.HeadRotation; 5500 m_lastAgentUpdateArgs.SessionID = x.SessionID;
5480 arg.SessionID = x.SessionID; 5501 m_lastAgentUpdateArgs.State = x.State;
5481 arg.State = x.State; 5502
5482 UpdateAgent handlerAgentUpdate = OnAgentUpdate; 5503 UpdateAgent handlerAgentUpdate = OnAgentUpdate;
5483 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate; 5504 UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
5484 lastarg = arg; // save this set of arguments for nexttime 5505
5485 if (handlerPreAgentUpdate != null) 5506 if (handlerPreAgentUpdate != null)
5486 OnPreAgentUpdate(this, arg); 5507 OnPreAgentUpdate(this, m_lastAgentUpdateArgs);
5508
5487 if (handlerAgentUpdate != null) 5509 if (handlerAgentUpdate != null)
5488 OnAgentUpdate(this, arg); 5510 OnAgentUpdate(this, m_lastAgentUpdateArgs);
5489 5511
5490 handlerAgentUpdate = null; 5512 handlerAgentUpdate = null;
5491 handlerPreAgentUpdate = null; 5513 handlerPreAgentUpdate = null;
5492 } 5514 }
5493 } 5515 }
5494 5516
5517 PacketPool.Instance.ReturnPacket(packet);
5518
5495 return true; 5519 return true;
5496 } 5520 }
5497 5521
@@ -9056,7 +9080,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9056 } 9080 }
9057 #endregion 9081 #endregion
9058 9082
9059 switch (Utils.BytesToString(messagePacket.MethodData.Method)) 9083 string method = Utils.BytesToString(messagePacket.MethodData.Method);
9084
9085 switch (method)
9060 { 9086 {
9061 case "getinfo": 9087 case "getinfo":
9062 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false)) 9088 if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
@@ -9372,7 +9398,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9372 return true; 9398 return true;
9373 9399
9374 default: 9400 default:
9375 m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket); 9401 m_log.WarnFormat(
9402 "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}",
9403 method, Name, Scene.Name);
9404
9405 for (int i = 0; i < messagePacket.ParamList.Length; i++)
9406 {
9407 EstateOwnerMessagePacket.ParamListBlock block = messagePacket.ParamList[i];
9408 string data = (string)Utils.BytesToString(block.Parameter);
9409 m_log.DebugFormat("[LLCLIENTVIEW]: Param {0}={1}", i, data);
9410 }
9411
9376 return true; 9412 return true;
9377 } 9413 }
9378 9414
@@ -11758,7 +11794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11758 logPacket = false; 11794 logPacket = false;
11759 11795
11760 if (DebugPacketLevel <= 50 11796 if (DebugPacketLevel <= 50
11761 & (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate)) 11797 && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
11762 logPacket = false; 11798 logPacket = false;
11763 11799
11764 if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily) 11800 if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
@@ -11832,8 +11868,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
11832 11868
11833 if (!ProcessPacketMethod(packet)) 11869 if (!ProcessPacketMethod(packet))
11834 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type); 11870 m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
11835
11836 PacketPool.Instance.ReturnPacket(packet);
11837 } 11871 }
11838 11872
11839 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) 11873 private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
@@ -12286,7 +12320,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
12286 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f); 12320 ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
12287 12321
12288 12322
12289 ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket(); 12323 ImprovedTerseObjectUpdatePacket packet
12324 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
12325 PacketType.ImprovedTerseObjectUpdate);
12326
12290 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 12327 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
12291 packet.RegionData.TimeDilation = timeDilation; 12328 packet.RegionData.TimeDilation = timeDilation;
12292 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; 12329 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d11fcbf..419de66 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -37,6 +37,7 @@ using log4net;
37using Nini.Config; 37using Nini.Config;
38using OpenMetaverse.Packets; 38using OpenMetaverse.Packets;
39using OpenSim.Framework; 39using OpenSim.Framework;
40using OpenSim.Framework.Console;
40using OpenSim.Framework.Monitoring; 41using OpenSim.Framework.Monitoring;
41using OpenSim.Region.Framework.Scenes; 42using OpenSim.Region.Framework.Scenes;
42using OpenMetaverse; 43using OpenMetaverse;
@@ -100,9 +101,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
100 101
101 /// <summary>The measured resolution of Environment.TickCount</summary> 102 /// <summary>The measured resolution of Environment.TickCount</summary>
102 public readonly float TickCountResolution; 103 public readonly float TickCountResolution;
104
103 /// <summary>Number of prim updates to put on the queue each time the 105 /// <summary>Number of prim updates to put on the queue each time the
104 /// OnQueueEmpty event is triggered for updates</summary> 106 /// OnQueueEmpty event is triggered for updates</summary>
105 public readonly int PrimUpdatesPerCallback; 107 public readonly int PrimUpdatesPerCallback;
108
106 /// <summary>Number of texture packets to put on the queue each time the 109 /// <summary>Number of texture packets to put on the queue each time the
107 /// OnQueueEmpty event is triggered for textures</summary> 110 /// OnQueueEmpty event is triggered for textures</summary>
108 public readonly int TextureSendLimit; 111 public readonly int TextureSendLimit;
@@ -111,6 +114,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
111 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 114 //PacketEventDictionary packetEvents = new PacketEventDictionary();
112 /// <summary>Incoming packets that are awaiting handling</summary> 115 /// <summary>Incoming packets that are awaiting handling</summary>
113 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 116 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
117
114 /// <summary></summary> 118 /// <summary></summary>
115 //private UDPClientCollection m_clients = new UDPClientCollection(); 119 //private UDPClientCollection m_clients = new UDPClientCollection();
116 /// <summary>Bandwidth throttle for this UDP server</summary> 120 /// <summary>Bandwidth throttle for this UDP server</summary>
@@ -121,28 +125,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
121 125
122 /// <summary>Manages authentication for agent circuits</summary> 126 /// <summary>Manages authentication for agent circuits</summary>
123 private AgentCircuitManager m_circuitManager; 127 private AgentCircuitManager m_circuitManager;
128
124 /// <summary>Reference to the scene this UDP server is attached to</summary> 129 /// <summary>Reference to the scene this UDP server is attached to</summary>
125 protected Scene m_scene; 130 protected Scene m_scene;
131
126 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> 132 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
127 private Location m_location; 133 private Location m_location;
134
128 /// <summary>The size of the receive buffer for the UDP socket. This value 135 /// <summary>The size of the receive buffer for the UDP socket. This value
129 /// is passed up to the operating system and used in the system networking 136 /// is passed up to the operating system and used in the system networking
130 /// stack. Use zero to leave this value as the default</summary> 137 /// stack. Use zero to leave this value as the default</summary>
131 private int m_recvBufferSize; 138 private int m_recvBufferSize;
139
132 /// <summary>Flag to process packets asynchronously or synchronously</summary> 140 /// <summary>Flag to process packets asynchronously or synchronously</summary>
133 private bool m_asyncPacketHandling; 141 private bool m_asyncPacketHandling;
142
134 /// <summary>Tracks whether or not a packet was sent each round so we know 143 /// <summary>Tracks whether or not a packet was sent each round so we know
135 /// whether or not to sleep</summary> 144 /// whether or not to sleep</summary>
136 private bool m_packetSent; 145 private bool m_packetSent;
137 146
138 /// <summary>Environment.TickCount of the last time that packet stats were reported to the scene</summary> 147 /// <summary>Environment.TickCount of the last time that packet stats were reported to the scene</summary>
139 private int m_elapsedMSSinceLastStatReport = 0; 148 private int m_elapsedMSSinceLastStatReport = 0;
149
140 /// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary> 150 /// <summary>Environment.TickCount of the last time the outgoing packet handler executed</summary>
141 private int m_tickLastOutgoingPacketHandler; 151 private int m_tickLastOutgoingPacketHandler;
152
142 /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary> 153 /// <summary>Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped</summary>
143 private int m_elapsedMSOutgoingPacketHandler; 154 private int m_elapsedMSOutgoingPacketHandler;
155
144 /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary> 156 /// <summary>Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed</summary>
145 private int m_elapsed100MSOutgoingPacketHandler; 157 private int m_elapsed100MSOutgoingPacketHandler;
158
146 /// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed</summary> 159 /// <summary>Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed</summary>
147 private int m_elapsed500MSOutgoingPacketHandler; 160 private int m_elapsed500MSOutgoingPacketHandler;
148 161
@@ -155,6 +168,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
155 /// <summary>Flag to signal when clients should send pings</summary> 168 /// <summary>Flag to signal when clients should send pings</summary>
156 protected bool m_sendPing; 169 protected bool m_sendPing;
157 170
171 private Pool<IncomingPacket> m_incomingPacketPool;
172
158 private int m_defaultRTO = 0; 173 private int m_defaultRTO = 0;
159 private int m_maxRTO = 0; 174 private int m_maxRTO = 0;
160 private int m_ackTimeout = 0; 175 private int m_ackTimeout = 0;
@@ -175,7 +190,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
175 /// </summary> 190 /// </summary>
176 private IClientAPI m_currentIncomingClient; 191 private IClientAPI m_currentIncomingClient;
177 192
178 public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) 193 public LLUDPServer(
194 IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
195 IConfigSource configSource, AgentCircuitManager circuitManager)
179 : base(listenIP, (int)port) 196 : base(listenIP, (int)port)
180 { 197 {
181 #region Environment.TickCount Measurement 198 #region Environment.TickCount Measurement
@@ -229,6 +246,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
229 { 246 {
230 PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); 247 PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
231 PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); 248 PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
249 UsePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", false);
232 } 250 }
233 251
234 #region BinaryStats 252 #region BinaryStats
@@ -258,20 +276,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
258 276
259 m_throttle = new TokenBucket(null, sceneThrottleBps); 277 m_throttle = new TokenBucket(null, sceneThrottleBps);
260 ThrottleRates = new ThrottleRates(configSource); 278 ThrottleRates = new ThrottleRates(configSource);
279
280 if (UsePools)
281 m_incomingPacketPool = new Pool<IncomingPacket>(() => new IncomingPacket(), 500);
261 } 282 }
262 283
263 public void Start() 284 public void Start()
264 { 285 {
265 if (m_scene == null) 286 StartInbound();
266 throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference"); 287 StartOutbound();
288
289 m_elapsedMSSinceLastStatReport = Environment.TickCount;
290 }
267 291
292 private void StartInbound()
293 {
268 m_log.InfoFormat( 294 m_log.InfoFormat(
269 "[LLUDPSERVER]: Starting the LLUDP server in {0} mode", 295 "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
270 m_asyncPacketHandling ? "asynchronous" : "synchronous"); 296 m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools);
271 297
272 base.Start(m_recvBufferSize, m_asyncPacketHandling); 298 base.StartInbound(m_recvBufferSize, m_asyncPacketHandling);
273 299
274 // Start the packet processing threads 300 // This thread will process the packets received that are placed on the packetInbox
275 Watchdog.StartThread( 301 Watchdog.StartThread(
276 IncomingPacketHandler, 302 IncomingPacketHandler,
277 string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName), 303 string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
@@ -280,6 +306,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
280 true, 306 true,
281 GetWatchdogIncomingAlarmData, 307 GetWatchdogIncomingAlarmData,
282 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); 308 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
309 }
310
311 private new void StartOutbound()
312 {
313 m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
314
315 base.StartOutbound();
283 316
284 Watchdog.StartThread( 317 Watchdog.StartThread(
285 OutgoingPacketHandler, 318 OutgoingPacketHandler,
@@ -289,8 +322,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
289 true, 322 true,
290 GetWatchdogOutgoingAlarmData, 323 GetWatchdogOutgoingAlarmData,
291 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); 324 Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
325 }
292 326
293 m_elapsedMSSinceLastStatReport = Environment.TickCount; 327 public void Stop()
328 {
329 m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
330 base.StopOutbound();
331 base.StopInbound();
294 } 332 }
295 333
296 /// <summary> 334 /// <summary>
@@ -315,12 +353,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
315 m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none"); 353 m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none");
316 } 354 }
317 355
318 public new void Stop()
319 {
320 m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
321 base.Stop();
322 }
323
324 public void AddScene(IScene scene) 356 public void AddScene(IScene scene)
325 { 357 {
326 if (m_scene != null) 358 if (m_scene != null)
@@ -337,6 +369,81 @@ namespace OpenSim.Region.ClientStack.LindenUDP
337 369
338 m_scene = (Scene)scene; 370 m_scene = (Scene)scene;
339 m_location = new Location(m_scene.RegionInfo.RegionHandle); 371 m_location = new Location(m_scene.RegionInfo.RegionHandle);
372
373 MainConsole.Instance.Commands.AddCommand(
374 "Debug",
375 false,
376 "debug lludp start",
377 "debug lludp start <in|out|all>",
378 "Control LLUDP packet processing.",
379 "No effect if packet processing has already started.\n"
380 + "in - start inbound processing.\n"
381 + "out - start outbound processing.\n"
382 + "all - start in and outbound processing.\n",
383 HandleStartCommand);
384
385 MainConsole.Instance.Commands.AddCommand(
386 "Debug",
387 false,
388 "debug lludp stop",
389 "debug lludp stop <in|out|all>",
390 "Stop LLUDP packet processing.",
391 "No effect if packet processing has already stopped.\n"
392 + "in - stop inbound processing.\n"
393 + "out - stop outbound processing.\n"
394 + "all - stop in and outbound processing.\n",
395 HandleStopCommand);
396
397 MainConsole.Instance.Commands.AddCommand(
398 "Debug",
399 false,
400 "debug lludp status",
401 "debug lludp status",
402 "Return status of LLUDP packet processing.",
403 HandleStatusCommand);
404 }
405
406 private void HandleStartCommand(string module, string[] args)
407 {
408 if (args.Length != 4)
409 {
410 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
411 return;
412 }
413
414 string subCommand = args[3];
415
416 if (subCommand == "in" || subCommand == "all")
417 StartInbound();
418
419 if (subCommand == "out" || subCommand == "all")
420 StartOutbound();
421 }
422
423 private void HandleStopCommand(string module, string[] args)
424 {
425 if (args.Length != 4)
426 {
427 MainConsole.Instance.Output("Usage: debug lludp stop <in|out|all>");
428 return;
429 }
430
431 string subCommand = args[3];
432
433 if (subCommand == "in" || subCommand == "all")
434 StopInbound();
435
436 if (subCommand == "out" || subCommand == "all")
437 StopOutbound();
438 }
439
440 private void HandleStatusCommand(string module, string[] args)
441 {
442 MainConsole.Instance.OutputFormat(
443 "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
444
445 MainConsole.Instance.OutputFormat(
446 "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
340 } 447 }
341 448
342 public bool HandlesRegion(Location x) 449 public bool HandlesRegion(Location x)
@@ -420,6 +527,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
420 byte[] data = packet.ToBytes(); 527 byte[] data = packet.ToBytes();
421 SendPacketData(udpClient, data, packet.Type, category, method); 528 SendPacketData(udpClient, data, packet.Type, category, method);
422 } 529 }
530
531 PacketPool.Instance.ReturnPacket(packet);
423 } 532 }
424 533
425 /// <summary> 534 /// <summary>
@@ -704,7 +813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
704 LLUDPClient udpClient = null; 813 LLUDPClient udpClient = null;
705 Packet packet = null; 814 Packet packet = null;
706 int packetEnd = buffer.DataLength - 1; 815 int packetEnd = buffer.DataLength - 1;
707 IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint; 816 IPEndPoint endPoint = (IPEndPoint)buffer.RemoteEndPoint;
708 817
709 #region Decoding 818 #region Decoding
710 819
@@ -714,7 +823,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
714// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", 823// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
715// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); 824// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
716 825
717 return; // Drop undersizd packet 826 return; // Drop undersized packet
718 } 827 }
719 828
720 int headerLen = 7; 829 int headerLen = 7;
@@ -737,7 +846,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
737 846
738 try 847 try
739 { 848 {
740 packet = Packet.BuildPacket(buffer.Data, ref packetEnd, 849// packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
850// // Only allocate a buffer for zerodecoding if the packet is zerocoded
851// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
852 // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
853 // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
854 // bytes are copied out).
855 packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
741 // Only allocate a buffer for zerodecoding if the packet is zerocoded 856 // Only allocate a buffer for zerodecoding if the packet is zerocoded
742 ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); 857 ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
743 } 858 }
@@ -752,11 +867,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
752 867
753 return; // Drop short packet 868 return; // Drop short packet
754 } 869 }
755 catch(Exception e) 870 catch (Exception e)
756 { 871 {
757 if (m_malformedCount < 100) 872 if (m_malformedCount < 100)
758 m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString()); 873 m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
874
759 m_malformedCount++; 875 m_malformedCount++;
876
760 if ((m_malformedCount % 100000) == 0) 877 if ((m_malformedCount % 100000) == 0)
761 m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount); 878 m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
762 } 879 }
@@ -777,7 +894,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
777 // UseCircuitCode handling 894 // UseCircuitCode handling
778 if (packet.Type == PacketType.UseCircuitCode) 895 if (packet.Type == PacketType.UseCircuitCode)
779 { 896 {
780 object[] array = new object[] { buffer, packet }; 897 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
898 // buffer.
899 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
781 900
782 Util.FireAndForget(HandleUseCircuitCode, array); 901 Util.FireAndForget(HandleUseCircuitCode, array);
783 902
@@ -786,7 +905,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
786 905
787 // Determine which agent this packet came from 906 // Determine which agent this packet came from
788 IClientAPI client; 907 IClientAPI client;
789 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView)) 908 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
790 { 909 {
791 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 910 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
792 return; 911 return;
@@ -810,6 +929,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
810 // Handle appended ACKs 929 // Handle appended ACKs
811 if (packet.Header.AppendedAcks && packet.Header.AckList != null) 930 if (packet.Header.AppendedAcks && packet.Header.AckList != null)
812 { 931 {
932// m_log.DebugFormat(
933// "[LLUDPSERVER]: Handling {0} appended acks from {1} in {2}",
934// packet.Header.AckList.Length, client.Name, m_scene.Name);
935
813 for (int i = 0; i < packet.Header.AckList.Length; i++) 936 for (int i = 0; i < packet.Header.AckList.Length; i++)
814 udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent); 937 udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent);
815 } 938 }
@@ -819,6 +942,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
819 { 942 {
820 PacketAckPacket ackPacket = (PacketAckPacket)packet; 943 PacketAckPacket ackPacket = (PacketAckPacket)packet;
821 944
945// m_log.DebugFormat(
946// "[LLUDPSERVER]: Handling {0} packet acks for {1} in {2}",
947// ackPacket.Packets.Length, client.Name, m_scene.Name);
948
822 for (int i = 0; i < ackPacket.Packets.Length; i++) 949 for (int i = 0; i < ackPacket.Packets.Length; i++)
823 udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent); 950 udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent);
824 951
@@ -832,6 +959,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
832 959
833 if (packet.Header.Reliable) 960 if (packet.Header.Reliable)
834 { 961 {
962// m_log.DebugFormat(
963// "[LLUDPSERVER]: Adding ack request for {0} {1} from {2} in {3}",
964// packet.Type, packet.Header.Sequence, client.Name, m_scene.Name);
965
835 udpClient.PendingAcks.Enqueue(packet.Header.Sequence); 966 udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
836 967
837 // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, 968 // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
@@ -878,6 +1009,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
878 1009
879 if (packet.Type == PacketType.StartPingCheck) 1010 if (packet.Type == PacketType.StartPingCheck)
880 { 1011 {
1012// m_log.DebugFormat("[LLUDPSERVER]: Handling ping from {0} in {1}", client.Name, m_scene.Name);
1013
881 // We don't need to do anything else with ping checks 1014 // We don't need to do anything else with ping checks
882 StartPingCheckPacket startPing = (StartPingCheckPacket)packet; 1015 StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
883 CompletePing(udpClient, startPing.PingID.PingID); 1016 CompletePing(udpClient, startPing.PingID.PingID);
@@ -897,8 +1030,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
897 1030
898 #endregion Ping Check Handling 1031 #endregion Ping Check Handling
899 1032
1033 IncomingPacket incomingPacket;
1034
900 // Inbox insertion 1035 // Inbox insertion
901 packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet)); 1036 if (UsePools)
1037 {
1038 incomingPacket = m_incomingPacketPool.GetObject();
1039 incomingPacket.Client = (LLClientView)client;
1040 incomingPacket.Packet = packet;
1041 }
1042 else
1043 {
1044 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1045 }
1046
1047 packetInbox.Enqueue(incomingPacket);
902 } 1048 }
903 1049
904 #region BinaryStats 1050 #region BinaryStats
@@ -984,21 +1130,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
984 1130
985 private void HandleUseCircuitCode(object o) 1131 private void HandleUseCircuitCode(object o)
986 { 1132 {
987 IPEndPoint remoteEndPoint = null; 1133 IPEndPoint endPoint = null;
988 IClientAPI client = null; 1134 IClientAPI client = null;
989 1135
990 try 1136 try
991 { 1137 {
992 // DateTime startTime = DateTime.Now; 1138 // DateTime startTime = DateTime.Now;
993 object[] array = (object[])o; 1139 object[] array = (object[])o;
994 UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; 1140 endPoint = (IPEndPoint)array[0];
995 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; 1141 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
996 1142
997 m_log.DebugFormat( 1143 m_log.DebugFormat(
998 "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}", 1144 "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
999 uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint); 1145 uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint);
1000
1001 remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
1002 1146
1003 AuthenticateResponse sessionInfo; 1147 AuthenticateResponse sessionInfo;
1004 if (IsClientAuthorized(uccp, out sessionInfo)) 1148 if (IsClientAuthorized(uccp, out sessionInfo))
@@ -1009,13 +1153,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1009 uccp.CircuitCode.Code, 1153 uccp.CircuitCode.Code,
1010 uccp.CircuitCode.ID, 1154 uccp.CircuitCode.ID,
1011 uccp.CircuitCode.SessionID, 1155 uccp.CircuitCode.SessionID,
1012 remoteEndPoint, 1156 endPoint,
1013 sessionInfo); 1157 sessionInfo);
1014 1158
1015 // Send ack straight away to let the viewer know that the connection is active. 1159 // Send ack straight away to let the viewer know that the connection is active.
1016 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use 1160 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use
1017 // circuit code to the existing child agent. This is not particularly obvious. 1161 // circuit code to the existing child agent. This is not particularly obvious.
1018 SendAckImmediate(remoteEndPoint, uccp.Header.Sequence); 1162 SendAckImmediate(endPoint, uccp.Header.Sequence);
1019 1163
1020 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1164 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1021 if (client != null) 1165 if (client != null)
@@ -1026,7 +1170,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1026 // Don't create clients for unauthorized requesters. 1170 // Don't create clients for unauthorized requesters.
1027 m_log.WarnFormat( 1171 m_log.WarnFormat(
1028 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1172 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1029 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); 1173 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1030 } 1174 }
1031 1175
1032 // m_log.DebugFormat( 1176 // m_log.DebugFormat(
@@ -1038,7 +1182,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1038 { 1182 {
1039 m_log.ErrorFormat( 1183 m_log.ErrorFormat(
1040 "[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}", 1184 "[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
1041 remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a", 1185 endPoint != null ? endPoint.ToString() : "n/a",
1042 client != null ? client.Name : "unknown", 1186 client != null ? client.Name : "unknown",
1043 client != null ? client.AgentId.ToString() : "unknown", 1187 client != null ? client.AgentId.ToString() : "unknown",
1044 e.Message, 1188 e.Message,
@@ -1103,20 +1247,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1103 { 1247 {
1104 IClientAPI client = null; 1248 IClientAPI client = null;
1105 1249
1106 // In priciple there shouldn't be more than one thread here, ever. 1250 // We currently synchronize this code across the whole scene to avoid issues such as
1107 // But in case that happens, we need to synchronize this piece of code 1251 // http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done
1108 // because it's too important 1252 // consistently, this lock could probably be removed.
1109 lock (this) 1253 lock (this)
1110 { 1254 {
1111 if (!m_scene.TryGetClient(agentID, out client)) 1255 if (!m_scene.TryGetClient(agentID, out client))
1112 { 1256 {
1113 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); 1257 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
1114 1258
1115 client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); 1259 client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
1116 client.OnLogout += LogoutHandler; 1260 client.OnLogout += LogoutHandler;
1117 1261
1118 ((LLClientView)client).DisableFacelights = m_disableFacelights; 1262 ((LLClientView)client).DisableFacelights = m_disableFacelights;
1119 1263
1120 client.Start(); 1264 client.Start();
1121 } 1265 }
1122 } 1266 }
@@ -1155,7 +1299,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1155 // on to en-US to avoid number parsing issues 1299 // on to en-US to avoid number parsing issues
1156 Culture.SetCurrentCulture(); 1300 Culture.SetCurrentCulture();
1157 1301
1158 while (base.IsRunning) 1302 while (IsRunningInbound)
1159 { 1303 {
1160 try 1304 try
1161 { 1305 {
@@ -1170,7 +1314,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1170 } 1314 }
1171 1315
1172 if (packetInbox.Dequeue(100, ref incomingPacket)) 1316 if (packetInbox.Dequeue(100, ref incomingPacket))
1317 {
1173 ProcessInPacket(incomingPacket);//, incomingPacket); Util.FireAndForget(ProcessInPacket, incomingPacket); 1318 ProcessInPacket(incomingPacket);//, incomingPacket); Util.FireAndForget(ProcessInPacket, incomingPacket);
1319
1320 if (UsePools)
1321 m_incomingPacketPool.ReturnObject(incomingPacket);
1322 }
1174 } 1323 }
1175 catch (Exception ex) 1324 catch (Exception ex)
1176 { 1325 {
@@ -1197,7 +1346,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1197 // Action generic every round 1346 // Action generic every round
1198 Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler; 1347 Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler;
1199 1348
1200 while (base.IsRunning) 1349 while (base.IsRunningOutbound)
1201 { 1350 {
1202 try 1351 try
1203 { 1352 {
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 039379d..6e6b3ef 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -30,6 +30,7 @@ using System.Net;
30using System.Net.Sockets; 30using System.Net.Sockets;
31using System.Threading; 31using System.Threading;
32using log4net; 32using log4net;
33using OpenSim.Framework;
33 34
34namespace OpenMetaverse 35namespace OpenMetaverse
35{ 36{
@@ -58,17 +59,29 @@ namespace OpenMetaverse
58 /// <summary>Flag to process packets asynchronously or synchronously</summary> 59 /// <summary>Flag to process packets asynchronously or synchronously</summary>
59 private bool m_asyncPacketHandling; 60 private bool m_asyncPacketHandling;
60 61
61 /// <summary>The all important shutdown flag</summary> 62 /// <summary>
62 private volatile bool m_shutdownFlag = true; 63 /// Pool to use for handling data. May be null if UsePools = false;
64 /// </summary>
65 protected OpenSim.Framework.Pool<UDPPacketBuffer> m_pool;
63 66
64 /// <summary>Returns true if the server is currently listening, otherwise false</summary> 67 /// <summary>
65 public bool IsRunning { get { return !m_shutdownFlag; } } 68 /// Are we to use object pool(s) to reduce memory churn when receiving data?
69 /// </summary>
70 public bool UsePools { get; protected set; }
71
72 /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary>
73 public bool IsRunningInbound { get; private set; }
74
75 /// <summary>Returns true if the server is currently sending outbound packets, otherwise false</summary>
76 /// <remarks>If IsRunningOut = false, then any request to send a packet is simply dropped.</remarks>
77 public bool IsRunningOutbound { get; private set; }
66 78
67 /// <summary> 79 /// <summary>
68 /// Default constructor 80 /// Default constructor
69 /// </summary> 81 /// </summary>
70 /// <param name="bindAddress">Local IP address to bind the server to</param> 82 /// <param name="bindAddress">Local IP address to bind the server to</param>
71 /// <param name="port">Port to listening for incoming UDP packets on</param> 83 /// <param name="port">Port to listening for incoming UDP packets on</param>
84 /// /// <param name="usePool">Are we to use an object pool to get objects for handing inbound data?</param>
72 public OpenSimUDPBase(IPAddress bindAddress, int port) 85 public OpenSimUDPBase(IPAddress bindAddress, int port)
73 { 86 {
74 m_localBindAddress = bindAddress; 87 m_localBindAddress = bindAddress;
@@ -76,7 +89,7 @@ namespace OpenMetaverse
76 } 89 }
77 90
78 /// <summary> 91 /// <summary>
79 /// Start the UDP server 92 /// Start inbound UDP packet handling.
80 /// </summary> 93 /// </summary>
81 /// <param name="recvBufferSize">The size of the receive buffer for 94 /// <param name="recvBufferSize">The size of the receive buffer for
82 /// the UDP socket. This value is passed up to the operating system 95 /// the UDP socket. This value is passed up to the operating system
@@ -91,11 +104,16 @@ namespace OpenMetaverse
91 /// manner (not throwing an exception when the remote side resets the 104 /// manner (not throwing an exception when the remote side resets the
92 /// connection). This call is ignored on Mono where the flag is not 105 /// connection). This call is ignored on Mono where the flag is not
93 /// necessary</remarks> 106 /// necessary</remarks>
94 public void Start(int recvBufferSize, bool asyncPacketHandling) 107 public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
95 { 108 {
109 if (UsePools)
110 m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500);
111 else
112 m_pool = null;
113
96 m_asyncPacketHandling = asyncPacketHandling; 114 m_asyncPacketHandling = asyncPacketHandling;
97 115
98 if (m_shutdownFlag) 116 if (!IsRunningInbound)
99 { 117 {
100 const int SIO_UDP_CONNRESET = -1744830452; 118 const int SIO_UDP_CONNRESET = -1744830452;
101 119
@@ -127,8 +145,7 @@ namespace OpenMetaverse
127 145
128 m_udpSocket.Bind(ipep); 146 m_udpSocket.Bind(ipep);
129 147
130 // we're not shutting down, we're starting up 148 IsRunningInbound = true;
131 m_shutdownFlag = false;
132 149
133 // kick off an async receive. The Start() method will return, the 150 // kick off an async receive. The Start() method will return, the
134 // actual receives will occur asynchronously and will be caught in 151 // actual receives will occur asynchronously and will be caught in
@@ -138,28 +155,41 @@ namespace OpenMetaverse
138 } 155 }
139 156
140 /// <summary> 157 /// <summary>
141 /// Stops the UDP server 158 /// Start outbound UDP packet handling.
142 /// </summary> 159 /// </summary>
143 public void Stop() 160 public void StartOutbound()
144 { 161 {
145 if (!m_shutdownFlag) 162 IsRunningOutbound = true;
163 }
164
165 public void StopInbound()
166 {
167 if (IsRunningInbound)
146 { 168 {
147 // wait indefinitely for a writer lock. Once this is called, the .NET runtime 169 // wait indefinitely for a writer lock. Once this is called, the .NET runtime
148 // will deny any more reader locks, in effect blocking all other send/receive 170 // will deny any more reader locks, in effect blocking all other send/receive
149 // threads. Once we have the lock, we set shutdownFlag to inform the other 171 // threads. Once we have the lock, we set IsRunningInbound = false to inform the other
150 // threads that the socket is closed. 172 // threads that the socket is closed.
151 m_shutdownFlag = true; 173 IsRunningInbound = false;
152 m_udpSocket.Close(); 174 m_udpSocket.Close();
153 } 175 }
154 } 176 }
155 177
178 public void StopOutbound()
179 {
180 IsRunningOutbound = false;
181 }
182
156 private void AsyncBeginReceive() 183 private void AsyncBeginReceive()
157 { 184 {
158 // allocate a packet buffer 185 UDPPacketBuffer buf;
159 //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut(); 186
160 UDPPacketBuffer buf = new UDPPacketBuffer(); 187 if (UsePools)
188 buf = m_pool.GetObject();
189 else
190 buf = new UDPPacketBuffer();
161 191
162 if (!m_shutdownFlag) 192 if (IsRunningInbound)
163 { 193 {
164 try 194 try
165 { 195 {
@@ -212,7 +242,7 @@ namespace OpenMetaverse
212 { 242 {
213 // Asynchronous receive operations will complete here through the call 243 // Asynchronous receive operations will complete here through the call
214 // to AsyncBeginReceive 244 // to AsyncBeginReceive
215 if (!m_shutdownFlag) 245 if (IsRunningInbound)
216 { 246 {
217 // Asynchronous mode will start another receive before the 247 // Asynchronous mode will start another receive before the
218 // callback for this packet is even fired. Very parallel :-) 248 // callback for this packet is even fired. Very parallel :-)
@@ -221,8 +251,6 @@ namespace OpenMetaverse
221 251
222 // get the buffer that was created in AsyncBeginReceive 252 // get the buffer that was created in AsyncBeginReceive
223 // this is the received data 253 // this is the received data
224 //WrappedObject<UDPPacketBuffer> wrappedBuffer = (WrappedObject<UDPPacketBuffer>)iar.AsyncState;
225 //UDPPacketBuffer buffer = wrappedBuffer.Instance;
226 UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; 254 UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
227 255
228 try 256 try
@@ -239,7 +267,8 @@ namespace OpenMetaverse
239 catch (ObjectDisposedException) { } 267 catch (ObjectDisposedException) { }
240 finally 268 finally
241 { 269 {
242 //wrappedBuffer.Dispose(); 270 if (UsePools)
271 m_pool.ReturnObject(buffer);
243 272
244 // Synchronous mode waits until the packet callback completes 273 // Synchronous mode waits until the packet callback completes
245 // before starting the receive to fetch another packet 274 // before starting the receive to fetch another packet
@@ -252,7 +281,7 @@ namespace OpenMetaverse
252 281
253 public void AsyncBeginSend(UDPPacketBuffer buf) 282 public void AsyncBeginSend(UDPPacketBuffer buf)
254 { 283 {
255 if (!m_shutdownFlag) 284 if (IsRunningOutbound)
256 { 285 {
257 try 286 try
258 { 287 {
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index fc9406b..2a3d14f 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -31,6 +31,7 @@ using System.Reflection;
31using OpenMetaverse; 31using OpenMetaverse;
32using OpenMetaverse.Packets; 32using OpenMetaverse.Packets;
33using log4net; 33using log4net;
34using OpenSim.Framework.Monitoring;
34 35
35namespace OpenSim.Region.ClientStack.LindenUDP 36namespace OpenSim.Region.ClientStack.LindenUDP
36{ 37{
@@ -43,17 +44,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
43 private bool packetPoolEnabled = true; 44 private bool packetPoolEnabled = true;
44 private bool dataBlockPoolEnabled = true; 45 private bool dataBlockPoolEnabled = true;
45 46
47 private PercentageStat m_packetsReusedStat = new PercentageStat(
48 "PacketsReused",
49 "Packets reused",
50 "clientstack",
51 "packetpool",
52 StatVerbosity.Debug,
53 "Number of packets reused out of all requests to the packet pool");
54
55 private PercentageStat m_blocksReusedStat = new PercentageStat(
56 "BlocksReused",
57 "Blocks reused",
58 "clientstack",
59 "packetpool",
60 StatVerbosity.Debug,
61 "Number of data blocks reused out of all requests to the packet pool");
62
46 /// <summary> 63 /// <summary>
47 /// Pool of packets available for reuse. 64 /// Pool of packets available for reuse.
48 /// </summary> 65 /// </summary>
49 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>(); 66 private readonly Dictionary<PacketType, Stack<Packet>> pool = new Dictionary<PacketType, Stack<Packet>>();
50 67
51 private static Dictionary<Type, Stack<Object>> DataBlocks = 68 private static Dictionary<Type, Stack<Object>> DataBlocks = new Dictionary<Type, Stack<Object>>();
52 new Dictionary<Type, Stack<Object>>();
53
54 static PacketPool()
55 {
56 }
57 69
58 public static PacketPool Instance 70 public static PacketPool Instance
59 { 71 {
@@ -72,8 +84,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
72 get { return dataBlockPoolEnabled; } 84 get { return dataBlockPoolEnabled; }
73 } 85 }
74 86
87 private PacketPool()
88 {
89 StatsManager.RegisterStat(m_packetsReusedStat);
90 StatsManager.RegisterStat(m_blocksReusedStat);
91 }
92
93 /// <summary>
94 /// Gets a packet of the given type.
95 /// </summary>
96 /// <param name='type'></param>
97 /// <returns>Guaranteed to always return a packet, whether from the pool or newly constructed.</returns>
75 public Packet GetPacket(PacketType type) 98 public Packet GetPacket(PacketType type)
76 { 99 {
100 m_packetsReusedStat.Consequent++;
101
77 Packet packet; 102 Packet packet;
78 103
79 if (!packetPoolEnabled) 104 if (!packetPoolEnabled)
@@ -83,13 +108,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
83 { 108 {
84 if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0) 109 if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0)
85 { 110 {
111// m_log.DebugFormat("[PACKETPOOL]: Building {0} packet", type);
112
86 // Creating a new packet if we cannot reuse an old package 113 // Creating a new packet if we cannot reuse an old package
87 packet = Packet.BuildPacket(type); 114 packet = Packet.BuildPacket(type);
88 } 115 }
89 else 116 else
90 { 117 {
118// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
119
91 // Recycle old packages 120 // Recycle old packages
92 packet = (pool[type]).Pop(); 121 m_packetsReusedStat.Antecedent++;
122
123 packet = pool[type].Pop();
93 } 124 }
94 } 125 }
95 126
@@ -138,7 +169,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
138 { 169 {
139 PacketType type = GetType(bytes); 170 PacketType type = GetType(bytes);
140 171
141 Array.Clear(zeroBuffer, 0, zeroBuffer.Length); 172// Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
142 173
143 int i = 0; 174 int i = 0;
144 Packet packet = GetPacket(type); 175 Packet packet = GetPacket(type);
@@ -185,6 +216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
185 switch (packet.Type) 216 switch (packet.Type)
186 { 217 {
187 // List pooling packets here 218 // List pooling packets here
219 case PacketType.AgentUpdate:
188 case PacketType.PacketAck: 220 case PacketType.PacketAck:
189 case PacketType.ObjectUpdate: 221 case PacketType.ObjectUpdate:
190 case PacketType.ImprovedTerseObjectUpdate: 222 case PacketType.ImprovedTerseObjectUpdate:
@@ -199,7 +231,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
199 231
200 if ((pool[type]).Count < 50) 232 if ((pool[type]).Count < 50)
201 { 233 {
202 (pool[type]).Push(packet); 234// m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);
235
236 pool[type].Push(packet);
203 } 237 }
204 } 238 }
205 break; 239 break;
@@ -211,16 +245,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
211 } 245 }
212 } 246 }
213 247
214 public static T GetDataBlock<T>() where T: new() 248 public T GetDataBlock<T>() where T: new()
215 { 249 {
216 lock (DataBlocks) 250 lock (DataBlocks)
217 { 251 {
252 m_blocksReusedStat.Consequent++;
253
218 Stack<Object> s; 254 Stack<Object> s;
219 255
220 if (DataBlocks.TryGetValue(typeof(T), out s)) 256 if (DataBlocks.TryGetValue(typeof(T), out s))
221 { 257 {
222 if (s.Count > 0) 258 if (s.Count > 0)
259 {
260 m_blocksReusedStat.Antecedent++;
223 return (T)s.Pop(); 261 return (T)s.Pop();
262 }
224 } 263 }
225 else 264 else
226 { 265 {
@@ -231,7 +270,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
231 } 270 }
232 } 271 }
233 272
234 public static void ReturnDataBlock<T>(T block) where T: new() 273 public void ReturnDataBlock<T>(T block) where T: new()
235 { 274 {
236 if (block == null) 275 if (block == null)
237 return; 276 return;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index 109a8e1..556df30 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
43 /// This will contain basic tests for the LindenUDP client stack 43 /// This will contain basic tests for the LindenUDP client stack
44 /// </summary> 44 /// </summary>
45 [TestFixture] 45 [TestFixture]
46 public class BasicCircuitTests 46 public class BasicCircuitTests : OpenSimTestCase
47 { 47 {
48 private Scene m_scene; 48 private Scene m_scene;
49 private TestLLUDPServer m_udpServer; 49 private TestLLUDPServer m_udpServer;
@@ -65,8 +65,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
65 } 65 }
66 66
67 [SetUp] 67 [SetUp]
68 public void SetUp() 68 public override void SetUp()
69 { 69 {
70 base.SetUp();
70 m_scene = new SceneHelpers().SetupScene(); 71 m_scene = new SceneHelpers().SetupScene();
71 } 72 }
72 73
@@ -143,7 +144,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
143 public void TestAddClient() 144 public void TestAddClient()
144 { 145 {
145 TestHelpers.InMethod(); 146 TestHelpers.InMethod();
146// XmlConfigurator.Configure(); 147// TestHelpers.EnableLogging();
147 148
148 AddUdpServer(); 149 AddUdpServer();
149 150