diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 423 |
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 | } |