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.cs423
1 files changed, 383 insertions, 40 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 76be91a..41e19fd 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -241,7 +241,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
241 /// <summary>Handlers for incoming packets</summary> 241 /// <summary>Handlers for incoming packets</summary>
242 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 242 //PacketEventDictionary packetEvents = new PacketEventDictionary();
243 /// <summary>Incoming packets that are awaiting handling</summary> 243 /// <summary>Incoming packets that are awaiting handling</summary>
244 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 244 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
245
246 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
245 247
246 /// <summary>Bandwidth throttle for this UDP server</summary> 248 /// <summary>Bandwidth throttle for this UDP server</summary>
247 public TokenBucket Throttle { get; private set; } 249 public TokenBucket Throttle { get; private set; }
@@ -299,14 +301,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
299 /// <summary>Flag to signal when clients should send pings</summary> 301 /// <summary>Flag to signal when clients should send pings</summary>
300 protected bool m_sendPing; 302 protected bool m_sendPing;
301 303
304 private int m_animationSequenceNumber;
305
306 public int NextAnimationSequenceNumber
307 {
308 get
309 {
310 m_animationSequenceNumber++;
311 if (m_animationSequenceNumber > 2147482624)
312 m_animationSequenceNumber = 1;
313 return m_animationSequenceNumber;
314 }
315 }
316
317
318
319 private ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>> m_pendingCache = new ExpiringCache<IPEndPoint, Queue<UDPPacketBuffer>>();
320
302 /// <summary> 321 /// <summary>
303 /// Event used to signal when queued packets are available for sending. 322 /// Event used to signal when queued packets are available for sending.
304 /// </summary> 323 /// </summary>
305 /// <remarks> 324 /// <remarks>
306 /// This allows the outbound loop to only operate when there is data to send rather than continuously polling. 325 /// This allows the outbound loop to only operate when there is data to send rather than continuously polling.
307 /// Some data is sent immediately and not queued. That data would not trigger this event. 326 /// Some data is sent immediately and not queued. That data would not trigger this event.
327 /// WRONG use. May be usefull in future revision
308 /// </remarks> 328 /// </remarks>
309 private AutoResetEvent m_dataPresentEvent = new AutoResetEvent(false); 329// private AutoResetEvent m_dataPresentEvent = new AutoResetEvent(false);
310 330
311 private Pool<IncomingPacket> m_incomingPacketPool; 331 private Pool<IncomingPacket> m_incomingPacketPool;
312 332
@@ -388,16 +408,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
388 408
389 // Measure the resolution of Environment.TickCount 409 // Measure the resolution of Environment.TickCount
390 TickCountResolution = 0f; 410 TickCountResolution = 0f;
391 for (int i = 0; i < 5; i++) 411 for (int i = 0; i < 10; i++)
392 { 412 {
393 int start = Environment.TickCount; 413 int start = Environment.TickCount;
394 int now = start; 414 int now = start;
395 while (now == start) 415 while (now == start)
396 now = Environment.TickCount; 416 now = Environment.TickCount;
397 TickCountResolution += (float)(now - start) * 0.2f; 417 TickCountResolution += (float)(now - start) * 0.1f;
398 } 418 }
399 m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms");
400 TickCountResolution = (float)Math.Ceiling(TickCountResolution); 419 TickCountResolution = (float)Math.Ceiling(TickCountResolution);
420 m_log.Info("[LLUDPSERVER]: Average Environment.TickCount resolution: " + TickCountResolution + "ms");
401 421
402 #endregion Environment.TickCount Measurement 422 #endregion Environment.TickCount Measurement
403 423
@@ -405,6 +425,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
405 int sceneThrottleBps = 0; 425 int sceneThrottleBps = 0;
406 bool usePools = false; 426 bool usePools = false;
407 427
428
429
408 IConfig config = configSource.Configs["ClientStack.LindenUDP"]; 430 IConfig config = configSource.Configs["ClientStack.LindenUDP"];
409 if (config != null) 431 if (config != null)
410 { 432 {
@@ -451,6 +473,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
451 } 473 }
452 #endregion BinaryStats 474 #endregion BinaryStats
453 475
476<<<<<<< HEAD
454 // FIXME: Can't add info here because don't know scene yet. 477 // FIXME: Can't add info here because don't know scene yet.
455// m_throttle 478// m_throttle
456// = new TokenBucket( 479// = new TokenBucket(
@@ -458,8 +481,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
458 481
459 Throttle = new TokenBucket("server throttle bucket", null, 0, sceneThrottleBps); 482 Throttle = new TokenBucket("server throttle bucket", null, 0, sceneThrottleBps);
460 483
484=======
485 m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps * 10e-3f);
486>>>>>>> avn/ubitvar
461 ThrottleRates = new ThrottleRates(configSource); 487 ThrottleRates = new ThrottleRates(configSource);
462 488
489 Random rnd = new Random(Util.EnvironmentTickCount());
490 m_animationSequenceNumber = rnd.Next(11474826);
491
463 if (usePools) 492 if (usePools)
464 EnablePools(); 493 EnablePools();
465 } 494 }
@@ -755,8 +784,151 @@ namespace OpenSim.Region.ClientStack.LindenUDP
755 if (UsePools) 784 if (UsePools)
756 EnablePoolStats(); 785 EnablePoolStats();
757 786
787<<<<<<< HEAD
758 LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this); 788 LLUDPServerCommands commands = new LLUDPServerCommands(MainConsole.Instance, this);
759 commands.Register(); 789 commands.Register();
790=======
791 MainConsole.Instance.Commands.AddCommand(
792 "Debug", false, "debug lludp packet",
793 "debug lludp packet [--default] <level> [<avatar-first-name> <avatar-last-name>]",
794 "Turn on packet debugging",
795 "If level > 255 then all incoming and outgoing packets are logged.\n"
796 + "If level <= 255 then incoming AgentUpdate and outgoing SimStats and SimulatorViewerTimeMessage packets are not logged.\n"
797 + "If level <= 200 then incoming RequestImage and outgoing ImagePacket, ImageData, LayerData and CoarseLocationUpdate packets are not logged.\n"
798 + "If level <= 100 then incoming ViewerEffect and AgentAnimation and outgoing ViewerEffect and AvatarAnimation packets are not logged.\n"
799 + "If level <= 50 then outgoing ImprovedTerseObjectUpdate packets are not logged.\n"
800 + "If level <= 0 then no packets are logged.\n"
801 + "If --default is specified then the level becomes the default logging level for all subsequent agents.\n"
802 + "In this case, you cannot also specify an avatar name.\n"
803 + "If an avatar name is given then only packets from that avatar are logged.",
804 HandlePacketCommand);
805
806 MainConsole.Instance.Commands.AddCommand(
807 "Debug",
808 false,
809 "debug lludp start",
810 "debug lludp start <in|out|all>",
811 "Control LLUDP packet processing.",
812 "No effect if packet processing has already started.\n"
813 + "in - start inbound processing.\n"
814 + "out - start outbound processing.\n"
815 + "all - start in and outbound processing.\n",
816 HandleStartCommand);
817
818 MainConsole.Instance.Commands.AddCommand(
819 "Debug",
820 false,
821 "debug lludp stop",
822 "debug lludp stop <in|out|all>",
823 "Stop LLUDP packet processing.",
824 "No effect if packet processing has already stopped.\n"
825 + "in - stop inbound processing.\n"
826 + "out - stop outbound processing.\n"
827 + "all - stop in and outbound processing.\n",
828 HandleStopCommand);
829
830 MainConsole.Instance.Commands.AddCommand(
831 "Debug",
832 false,
833 "debug lludp pool",
834 "debug lludp pool <on|off>",
835 "Turn object pooling within the lludp component on or off.",
836 HandlePoolCommand);
837
838 MainConsole.Instance.Commands.AddCommand(
839 "Debug",
840 false,
841 "debug lludp status",
842 "debug lludp status",
843 "Return status of LLUDP packet processing.",
844 HandleStatusCommand);
845/* disabled
846 MainConsole.Instance.Commands.AddCommand(
847 "Debug",
848 false,
849 "debug lludp toggle agentupdate",
850 "debug lludp toggle agentupdate",
851 "Toggle whether agentupdate packets are processed or simply discarded.",
852 HandleAgentUpdateCommand);
853 */
854 }
855
856 private void HandlePacketCommand(string module, string[] args)
857 {
858 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
859 return;
860
861 bool setAsDefaultLevel = false;
862 OptionSet optionSet = new OptionSet().Add("default", o => setAsDefaultLevel = o != null);
863 List<string> filteredArgs = optionSet.Parse(args);
864
865 string name = null;
866
867 if (filteredArgs.Count == 6)
868 {
869 if (!setAsDefaultLevel)
870 {
871 name = string.Format("{0} {1}", filteredArgs[4], filteredArgs[5]);
872 }
873 else
874 {
875 MainConsole.Instance.OutputFormat("ERROR: Cannot specify a user name when setting default logging level");
876 return;
877 }
878 }
879
880 if (filteredArgs.Count > 3)
881 {
882 int newDebug;
883 if (int.TryParse(filteredArgs[3], out newDebug))
884 {
885 if (setAsDefaultLevel)
886 {
887 DefaultClientPacketDebugLevel = newDebug;
888 MainConsole.Instance.OutputFormat(
889 "Debug packet debug for new clients set to {0} in {1}", DefaultClientPacketDebugLevel, m_scene.Name);
890 }
891 else
892 {
893 m_scene.ForEachScenePresence(sp =>
894 {
895 if (name == null || sp.Name == name)
896 {
897 MainConsole.Instance.OutputFormat(
898 "Packet debug for {0} ({1}) set to {2} in {3}",
899 sp.Name, sp.IsChildAgent ? "child" : "root", newDebug, m_scene.Name);
900
901 sp.ControllingClient.DebugPacketLevel = newDebug;
902 }
903 });
904 }
905 }
906 else
907 {
908 MainConsole.Instance.Output("Usage: debug lludp packet [--default] 0..255 [<first-name> <last-name>]");
909 }
910 }
911 }
912
913 private void HandleStartCommand(string module, string[] args)
914 {
915 if (SceneManager.Instance.CurrentScene != null && SceneManager.Instance.CurrentScene != m_scene)
916 return;
917
918 if (args.Length != 4)
919 {
920 MainConsole.Instance.Output("Usage: debug lludp start <in|out|all>");
921 return;
922 }
923
924 string subCommand = args[3];
925
926 if (subCommand == "in" || subCommand == "all")
927 StartInbound();
928
929 if (subCommand == "out" || subCommand == "all")
930 StartOutbound();
931>>>>>>> avn/ubitvar
760 } 932 }
761 933
762 public bool HandlesRegion(Location x) 934 public bool HandlesRegion(Location x)
@@ -864,8 +1036,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
864 1036
865 PacketPool.Instance.ReturnPacket(packet); 1037 PacketPool.Instance.ReturnPacket(packet);
866 1038
867 if (packetQueued) 1039 /// WRONG use. May be usefull in future revision
868 m_dataPresentEvent.Set(); 1040// if (packetQueued)
1041// m_dataPresentEvent.Set();
869 } 1042 }
870 1043
871 /// <summary> 1044 /// <summary>
@@ -936,6 +1109,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
936 1109
937 #region Queue or Send 1110 #region Queue or Send
938 1111
1112 bool highPriority = false;
1113
1114 if (category != ThrottleOutPacketType.Unknown && (category & ThrottleOutPacketType.HighPriority) != 0)
1115 {
1116 category = (ThrottleOutPacketType)((int)category & 127);
1117 highPriority = true;
1118 }
1119
939 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null); 1120 OutgoingPacket outgoingPacket = new OutgoingPacket(udpClient, buffer, category, null);
940 1121
941 // If we were not provided a method for handling unacked, use the UDPServer default method 1122 // If we were not provided a method for handling unacked, use the UDPServer default method
@@ -945,6 +1126,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
945 // If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will 1126 // If a Linden Lab 1.23.5 client receives an update packet after a kill packet for an object, it will
946 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object 1127 // continue to display the deleted object until relog. Therefore, we need to always queue a kill object
947 // packet so that it isn't sent before a queued update packet. 1128 // packet so that it isn't sent before a queued update packet.
1129<<<<<<< HEAD
948 bool forceQueue = (type == PacketType.KillObject); 1130 bool forceQueue = (type == PacketType.KillObject);
949 1131
950// if (type == PacketType.ImprovedTerseObjectUpdate) 1132// if (type == PacketType.ImprovedTerseObjectUpdate)
@@ -956,15 +1138,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
956// else 1138// else
957// { 1139// {
958 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue)) 1140 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, forceQueue))
1141=======
1142 bool requestQueue = type == PacketType.KillObject;
1143 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, requestQueue, highPriority))
1144>>>>>>> avn/ubitvar
959 { 1145 {
960 SendPacketFinal(outgoingPacket); 1146 SendPacketFinal(outgoingPacket);
961 return true; 1147 return true;
962 } 1148 }
1149<<<<<<< HEAD
963 else 1150 else
964 { 1151 {
965 return false; 1152 return false;
966 } 1153 }
967// } 1154// }
1155=======
1156
1157 return false;
1158>>>>>>> avn/ubitvar
968 1159
969 #endregion Queue or Send 1160 #endregion Queue or Send
970 } 1161 }
@@ -1005,6 +1196,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1005 pc.PingID.OldestUnacked = 0; 1196 pc.PingID.OldestUnacked = 0;
1006 1197
1007 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null); 1198 SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false, null);
1199 udpClient.m_lastStartpingTimeMS = Util.EnvironmentTickCount();
1008 } 1200 }
1009 1201
1010 public void CompletePing(LLUDPClient udpClient, byte pingID) 1202 public void CompletePing(LLUDPClient udpClient, byte pingID)
@@ -1102,7 +1294,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1102 int dataLength = buffer.DataLength; 1294 int dataLength = buffer.DataLength;
1103 1295
1104 // NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here 1296 // NOTE: I'm seeing problems with some viewers when ACKs are appended to zerocoded packets so I've disabled that here
1105 if (!isZerocoded) 1297 if (!isZerocoded && !isResend && outgoingPacket.UnackedMethod == null)
1106 { 1298 {
1107 // Keep appending ACKs until there is no room left in the buffer or there are 1299 // Keep appending ACKs until there is no room left in the buffer or there are
1108 // no more ACKs to append 1300 // no more ACKs to append
@@ -1268,35 +1460,76 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1268 1460
1269 #region Packet to Client Mapping 1461 #region Packet to Client Mapping
1270 1462
1271 // UseCircuitCode handling 1463 // If there is already a client for this endpoint, don't process UseCircuitCode
1272 if (packet.Type == PacketType.UseCircuitCode) 1464 IClientAPI client = null;
1465 if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1273 { 1466 {
1274 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1467 // UseCircuitCode handling
1275 // buffer. 1468 if (packet.Type == PacketType.UseCircuitCode)
1276 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1469 {
1470 // And if there is a UseCircuitCode pending, also drop it
1471 lock (m_pendingCache)
1472 {
1473 if (m_pendingCache.Contains(endPoint))
1474 return;
1277 1475
1476<<<<<<< HEAD
1278 Util.FireAndForget(HandleUseCircuitCode, array, "LLUDPServer.HandleUseCircuitCode"); 1477 Util.FireAndForget(HandleUseCircuitCode, array, "LLUDPServer.HandleUseCircuitCode");
1478=======
1479 m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60);
1480 }
1481>>>>>>> avn/ubitvar
1279 1482
1280 return; 1483 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1484 // buffer.
1485 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1486
1487 Util.FireAndForget(HandleUseCircuitCode, array);
1488
1489 return;
1490 }
1281 } 1491 }
1282 else if (packet.Type == PacketType.CompleteAgentMovement) 1492
1493 // If this is a pending connection, enqueue, don't process yet
1494 lock (m_pendingCache)
1283 { 1495 {
1284 // Send ack straight away to let the viewer know that we got it. 1496 Queue<UDPPacketBuffer> queue;
1285 SendAckImmediate(endPoint, packet.Header.Sequence); 1497 if (m_pendingCache.TryGetValue(endPoint, out queue))
1498 {
1499 //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
1500 queue.Enqueue(buffer);
1501 return;
1502 }
1286 1503
1287 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the 1504/*
1288 // buffer. 1505 else if (packet.Type == PacketType.CompleteAgentMovement)
1289 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; 1506 {
1507 // Send ack straight away to let the viewer know that we got it.
1508 SendAckImmediate(endPoint, packet.Header.Sequence);
1290 1509
1510<<<<<<< HEAD
1291 Util.FireAndForget( 1511 Util.FireAndForget(
1292 HandleCompleteMovementIntoRegion, array, "LLUDPServer.HandleCompleteMovementIntoRegion"); 1512 HandleCompleteMovementIntoRegion, array, "LLUDPServer.HandleCompleteMovementIntoRegion");
1513=======
1514 // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
1515 // buffer.
1516 object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
1517>>>>>>> avn/ubitvar
1293 1518
1294 return; 1519 Util.FireAndForget(HandleCompleteMovementIntoRegion, array);
1520
1521 return;
1522 }
1523 */
1295 } 1524 }
1296 1525
1297 // Determine which agent this packet came from 1526 // Determine which agent this packet came from
1527<<<<<<< HEAD
1298 IClientAPI client; 1528 IClientAPI client;
1299 if (!Scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) 1529 if (!Scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
1530=======
1531 if (client == null || !(client is LLClientView))
1532>>>>>>> avn/ubitvar
1300 { 1533 {
1301 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName); 1534 //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
1302 1535
@@ -1313,7 +1546,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1313 udpClient = ((LLClientView)client).UDPClient; 1546 udpClient = ((LLClientView)client).UDPClient;
1314 1547
1315 if (!udpClient.IsConnected) 1548 if (!udpClient.IsConnected)
1549 {
1550 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet for a unConnected client in " + m_scene.RegionInfo.RegionName);
1316 return; 1551 return;
1552 }
1317 1553
1318 #endregion Packet to Client Mapping 1554 #endregion Packet to Client Mapping
1319 1555
@@ -1416,6 +1652,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1416 LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length); 1652 LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
1417 #endregion BinaryStats 1653 #endregion BinaryStats
1418 1654
1655<<<<<<< HEAD
1419 if (packet.Type == PacketType.AgentUpdate) 1656 if (packet.Type == PacketType.AgentUpdate)
1420 { 1657 {
1421 if (DiscardInboundAgentUpdates) 1658 if (DiscardInboundAgentUpdates)
@@ -1434,6 +1671,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1434 return; 1671 return;
1435 } 1672 }
1436 } 1673 }
1674=======
1675// AgentUpdate mess removed from here
1676>>>>>>> avn/ubitvar
1437 1677
1438 #region Ping Check Handling 1678 #region Ping Check Handling
1439 1679
@@ -1444,7 +1684,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1444 // We don't need to do anything else with ping checks 1684 // We don't need to do anything else with ping checks
1445 StartPingCheckPacket startPing = (StartPingCheckPacket)packet; 1685 StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
1446 CompletePing(udpClient, startPing.PingID.PingID); 1686 CompletePing(udpClient, startPing.PingID.PingID);
1447 1687
1448 if ((Environment.TickCount - m_elapsedMSSinceLastStatReport) >= 3000) 1688 if ((Environment.TickCount - m_elapsedMSSinceLastStatReport) >= 3000)
1449 { 1689 {
1450 udpClient.SendPacketStats(); 1690 udpClient.SendPacketStats();
@@ -1454,7 +1694,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1454 } 1694 }
1455 else if (packet.Type == PacketType.CompletePingCheck) 1695 else if (packet.Type == PacketType.CompletePingCheck)
1456 { 1696 {
1457 // We don't currently track client ping times 1697 int t = Util.EnvironmentTickCountSubtract(udpClient.m_lastStartpingTimeMS);
1698 int c = udpClient.m_pingMS;
1699 c = 800 * c + 200 * t;
1700 c /= 1000;
1701 udpClient.m_pingMS = c;
1458 return; 1702 return;
1459 } 1703 }
1460 1704
@@ -1474,7 +1718,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1474 incomingPacket = new IncomingPacket((LLClientView)client, packet); 1718 incomingPacket = new IncomingPacket((LLClientView)client, packet);
1475 } 1719 }
1476 1720
1477 packetInbox.Enqueue(incomingPacket); 1721// if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
1722// incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1723 if (incomingPacket.Packet.Type == PacketType.ChatFromViewer)
1724 packetInbox.EnqueueHigh(incomingPacket);
1725 else
1726 packetInbox.EnqueueLow(incomingPacket);
1727
1478 } 1728 }
1479 1729
1480 #region BinaryStats 1730 #region BinaryStats
@@ -1591,7 +1841,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1591 1841
1592 try 1842 try
1593 { 1843 {
1594 // DateTime startTime = DateTime.Now; 1844// DateTime startTime = DateTime.Now;
1595 object[] array = (object[])o; 1845 object[] array = (object[])o;
1596 endPoint = (IPEndPoint)array[0]; 1846 endPoint = (IPEndPoint)array[0];
1597 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; 1847 UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
@@ -1603,6 +1853,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1603 AuthenticateResponse sessionInfo; 1853 AuthenticateResponse sessionInfo;
1604 if (IsClientAuthorized(uccp, out sessionInfo)) 1854 if (IsClientAuthorized(uccp, out sessionInfo))
1605 { 1855 {
1856 AgentCircuitData aCircuit = m_scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
1857
1606 // Begin the process of adding the client to the simulator 1858 // Begin the process of adding the client to the simulator
1607 client 1859 client
1608 = AddClient( 1860 = AddClient(
@@ -1611,16 +1863,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1611 uccp.CircuitCode.SessionID, 1863 uccp.CircuitCode.SessionID,
1612 endPoint, 1864 endPoint,
1613 sessionInfo); 1865 sessionInfo);
1614 1866
1867 // This will be true if the client is new, e.g. not
1868 // an existing child agent, and there is no circuit data
1869 if (client != null && aCircuit == null)
1870 {
1871 m_scene.CloseAgent(client.AgentId, true);
1872 return;
1873 }
1874
1875 // Now we know we can handle more data
1876 Thread.Sleep(200);
1877
1878 // Obtain the pending queue and remove it from the cache
1879 Queue<UDPPacketBuffer> queue = null;
1880
1881 lock (m_pendingCache)
1882 {
1883 if (!m_pendingCache.TryGetValue(endPoint, out queue))
1884 {
1885 m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
1886 return;
1887
1888 }
1889 m_pendingCache.Remove(endPoint);
1890 }
1891
1892 m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
1893
1894 // Reinject queued packets
1895 while (queue.Count > 0)
1896 {
1897 UDPPacketBuffer buf = queue.Dequeue();
1898 PacketReceived(buf);
1899 }
1900
1901 queue = null;
1902
1615 // Send ack straight away to let the viewer know that the connection is active. 1903 // Send ack straight away to let the viewer know that the connection is active.
1616 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use 1904 // The client will be null if it already exists (e.g. if on a region crossing the client sends a use
1617 // circuit code to the existing child agent. This is not particularly obvious. 1905 // circuit code to the existing child agent. This is not particularly obvious.
1618 SendAckImmediate(endPoint, uccp.Header.Sequence); 1906 SendAckImmediate(endPoint, uccp.Header.Sequence);
1619 1907
1620 // We only want to send initial data to new clients, not ones which are being converted from child to root. 1908 // We only want to send initial data to new clients, not ones which are being converted from child to root.
1621 if (client != null) 1909 if (client != null)
1622 { 1910 {
1911<<<<<<< HEAD
1623 AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code); 1912 AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(uccp.CircuitCode.Code);
1913=======
1914>>>>>>> avn/ubitvar
1624 bool tp = (aCircuit.teleportFlags > 0); 1915 bool tp = (aCircuit.teleportFlags > 0);
1625 // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from 1916 // Let's delay this for TP agents, otherwise the viewer doesn't know where to get resources from
1626 if (!tp && !client.SceneAgent.SentInitialDataToClient) 1917 if (!tp && !client.SceneAgent.SentInitialDataToClient)
@@ -1632,9 +1923,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1632 // Don't create clients for unauthorized requesters. 1923 // Don't create clients for unauthorized requesters.
1633 m_log.WarnFormat( 1924 m_log.WarnFormat(
1634 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", 1925 "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
1926<<<<<<< HEAD
1635 uccp.CircuitCode.ID, Scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); 1927 uccp.CircuitCode.ID, Scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1636 } 1928 }
1637 1929
1930=======
1931 uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
1932
1933 lock (m_pendingCache)
1934 m_pendingCache.Remove(endPoint);
1935 }
1936>>>>>>> avn/ubitvar
1638 // m_log.DebugFormat( 1937 // m_log.DebugFormat(
1639 // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", 1938 // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
1640 // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); 1939 // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
@@ -1651,8 +1950,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1651 e.StackTrace); 1950 e.StackTrace);
1652 } 1951 }
1653 } 1952 }
1654 1953/*
1655 private void HandleCompleteMovementIntoRegion(object o) 1954 private void HandleCompleteMovementIntoRegion(object o)
1656 { 1955 {
1657 IPEndPoint endPoint = null; 1956 IPEndPoint endPoint = null;
1658 IClientAPI client = null; 1957 IClientAPI client = null;
@@ -1761,6 +2060,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1761 e.StackTrace); 2060 e.StackTrace);
1762 } 2061 }
1763 } 2062 }
2063*/
1764 2064
1765 /// <summary> 2065 /// <summary>
1766 /// Send an ack immediately to the given endpoint. 2066 /// Send an ack immediately to the given endpoint.
@@ -1818,6 +2118,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1818 uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) 2118 uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
1819 { 2119 {
1820 IClientAPI client = null; 2120 IClientAPI client = null;
2121 bool createNew = false;
1821 2122
1822 // We currently synchronize this code across the whole scene to avoid issues such as 2123 // We currently synchronize this code across the whole scene to avoid issues such as
1823 // http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done 2124 // http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done
@@ -1826,7 +2127,24 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1826 { 2127 {
1827 if (!Scene.TryGetClient(agentID, out client)) 2128 if (!Scene.TryGetClient(agentID, out client))
1828 { 2129 {
2130<<<<<<< HEAD
1829 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, Throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); 2131 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, Throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
2132=======
2133 createNew = true;
2134 }
2135 else
2136 {
2137 if (client.SceneAgent == null)
2138 {
2139 m_scene.CloseAgent(agentID, true);
2140 createNew = true;
2141 }
2142 }
2143
2144 if (createNew)
2145 {
2146 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
2147>>>>>>> avn/ubitvar
1830 2148
1831 client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); 2149 client = new LLClientView(Scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
1832 client.OnLogout += LogoutHandler; 2150 client.OnLogout += LogoutHandler;
@@ -1856,15 +2174,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1856 { 2174 {
1857 ClientLogoutsDueToNoReceives++; 2175 ClientLogoutsDueToNoReceives++;
1858 2176
2177<<<<<<< HEAD
1859 m_log.WarnFormat( 2178 m_log.WarnFormat(
1860 "[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.", 2179 "[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.",
1861 client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, Scene.Name); 2180 client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, Scene.Name);
2181=======
2182 if (client.SceneAgent != null)
2183 {
2184 m_log.WarnFormat(
2185 "[LLUDPSERVER]: No packets received from {0} agent of {1} for {2}ms in {3}. Disconnecting.",
2186 client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, timeoutTicks, m_scene.Name);
2187>>>>>>> avn/ubitvar
1862 2188
1863 if (!client.SceneAgent.IsChildAgent) 2189 if (!client.SceneAgent.IsChildAgent)
1864 client.Kick("Simulator logged you out due to connection timeout."); 2190 client.Kick("Simulator logged you out due to connection timeout.");
2191 }
1865 } 2192 }
1866 2193
2194<<<<<<< HEAD
1867 Scene.CloseAgent(client.AgentId, true); 2195 Scene.CloseAgent(client.AgentId, true);
2196=======
2197 if (!m_scene.CloseAgent(client.AgentId, true))
2198 client.Close(true,true);
2199>>>>>>> avn/ubitvar
1868 } 2200 }
1869 2201
1870 private void IncomingPacketHandler() 2202 private void IncomingPacketHandler()
@@ -1877,6 +2209,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1877 2209
1878 while (IsRunningInbound) 2210 while (IsRunningInbound)
1879 { 2211 {
2212 m_scene.ThreadAlive(1);
1880 try 2213 try
1881 { 2214 {
1882 IncomingPacket incomingPacket = null; 2215 IncomingPacket incomingPacket = null;
@@ -1899,7 +2232,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1899 m_incomingPacketPool.ReturnObject(incomingPacket); 2232 m_incomingPacketPool.ReturnObject(incomingPacket);
1900 } 2233 }
1901 } 2234 }
1902 catch (Exception ex) 2235 catch(Exception ex)
1903 { 2236 {
1904 m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex); 2237 m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex);
1905 } 2238 }
@@ -1928,6 +2261,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1928 2261
1929 while (base.IsRunningOutbound) 2262 while (base.IsRunningOutbound)
1930 { 2263 {
2264 m_scene.ThreadAlive(2);
1931 try 2265 try
1932 { 2266 {
1933 m_packetSent = false; 2267 m_packetSent = false;
@@ -1986,13 +2320,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1986 2320
1987 // If nothing was sent, sleep for the minimum amount of time before a 2321 // If nothing was sent, sleep for the minimum amount of time before a
1988 // token bucket could get more tokens 2322 // token bucket could get more tokens
1989 //if (!m_packetSent) 2323
1990 // Thread.Sleep((int)TickCountResolution);
1991 //
1992 // Instead, now wait for data present to be explicitly signalled. Evidence so far is that with
1993 // modern mono it reduces CPU base load since there is no more continuous polling.
1994 if (!m_packetSent) 2324 if (!m_packetSent)
1995 m_dataPresentEvent.WaitOne(100); 2325 Thread.Sleep((int)TickCountResolution);
2326
2327 // .... wrong core code removed
2328
1996 2329
1997 Watchdog.UpdateThread(); 2330 Watchdog.UpdateThread();
1998 } 2331 }
@@ -2163,8 +2496,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2163 Packet packet = incomingPacket.Packet; 2496 Packet packet = incomingPacket.Packet;
2164 LLClientView client = incomingPacket.Client; 2497 LLClientView client = incomingPacket.Client;
2165 2498
2166 if (client.IsActive) 2499// if (client.IsActive)
2167 { 2500// {
2168 m_currentIncomingClient = client; 2501 m_currentIncomingClient = client;
2169 2502
2170 try 2503 try
@@ -2191,6 +2524,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2191 { 2524 {
2192 m_currentIncomingClient = null; 2525 m_currentIncomingClient = null;
2193 } 2526 }
2527<<<<<<< HEAD
2194 } 2528 }
2195 else 2529 else
2196 { 2530 {
@@ -2198,6 +2532,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2198 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", 2532 "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2199 packet.Type, client.Name, Scene.RegionInfo.RegionName); 2533 packet.Type, client.Name, Scene.RegionInfo.RegionName);
2200 } 2534 }
2535=======
2536// }
2537// else
2538// {
2539// m_log.DebugFormat(
2540// "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}",
2541// packet.Type, client.Name, m_scene.RegionInfo.RegionName);
2542// }
2543>>>>>>> avn/ubitvar
2201 2544
2202 IncomingPacketsProcessed++; 2545 IncomingPacketsProcessed++;
2203 } 2546 }