diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 3c23dcf..22cc194 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -555,12 +555,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
555 | if (udpClient.IsPaused) | 555 | if (udpClient.IsPaused) |
556 | timeoutTicks = m_pausedAckTimeout; | 556 | timeoutTicks = m_pausedAckTimeout; |
557 | 557 | ||
558 | if (!client.IsLoggingOut && | 558 | if (client.IsActive && |
559 | (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) | 559 | (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) |
560 | { | 560 | { |
561 | m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); | 561 | // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even |
562 | StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); | 562 | // though it's set later on by LLClientView.Close() |
563 | RemoveClient(client); | 563 | client.IsActive = false; |
564 | |||
565 | // Fire this out on a different thread so that we don't hold up outgoing packet processing for | ||
566 | // everybody else if this is being called due to an ack timeout. | ||
567 | // This is the same as processing as the async process of a logout request. | ||
568 | Util.FireAndForget(o => DeactivateClientDueToTimeout(client)); | ||
564 | 569 | ||
565 | return; | 570 | return; |
566 | } | 571 | } |
@@ -1110,9 +1115,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1110 | return client; | 1115 | return client; |
1111 | } | 1116 | } |
1112 | 1117 | ||
1113 | private void RemoveClient(IClientAPI client) | 1118 | /// <summary> |
1119 | /// Deactivates the client if we don't receive any packets within a certain amount of time (default 60 seconds). | ||
1120 | /// </summary> | ||
1121 | /// <remarks> | ||
1122 | /// If a connection is active then we will always receive packets even if nothing else is happening, due to | ||
1123 | /// regular client pings. | ||
1124 | /// </remarks> | ||
1125 | /// <param name='client'></param> | ||
1126 | private void DeactivateClientDueToTimeout(IClientAPI client) | ||
1114 | { | 1127 | { |
1115 | client.IsLoggingOut = true; | 1128 | // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even |
1129 | // though it's set later on by LLClientView.Close() | ||
1130 | client.IsActive = false; | ||
1131 | |||
1132 | m_log.WarnFormat( | ||
1133 | "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}", | ||
1134 | client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName); | ||
1135 | |||
1136 | StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); | ||
1137 | |||
1138 | if (!client.SceneAgent.IsChildAgent) | ||
1139 | client.Kick("Simulator logged you out due to connection timeout"); | ||
1140 | |||
1116 | Util.FireAndForget(o => client.Close()); | 1141 | Util.FireAndForget(o => client.Close()); |
1117 | } | 1142 | } |
1118 | 1143 | ||
@@ -1429,8 +1454,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1429 | protected void LogoutHandler(IClientAPI client) | 1454 | protected void LogoutHandler(IClientAPI client) |
1430 | { | 1455 | { |
1431 | client.SendLogoutPacket(); | 1456 | client.SendLogoutPacket(); |
1457 | |||
1432 | if (!client.IsLoggingOut) | 1458 | if (!client.IsLoggingOut) |
1433 | RemoveClient(client); | 1459 | { |
1460 | client.IsLoggingOut = true; | ||
1461 | client.Close(); | ||
1462 | } | ||
1434 | } | 1463 | } |
1435 | } | 1464 | } |
1436 | } | 1465 | } |