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.cs43
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}