aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs227
1 files changed, 188 insertions, 39 deletions
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 {