From c89db34fc4372be7ff94d92472131b2c33de8605 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 12 Jun 2012 02:03:31 +0100
Subject: If the simulator closes a root agent due to ack timeout, then send
the client a kick message with that reason, in case it is somehow still
listening.
---
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 7f86491..2036f61 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -558,9 +558,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!client.IsLoggingOut &&
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
{
- m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID);
+ m_log.WarnFormat(
+ "[LLUDPSERVER]: Ack timeout for {0} {1}, disconnecting",
+ client.Name, client.AgentId);
+
StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
- RemoveClient(client);
+ LogoutClientDueToTimeout(client);
return;
}
@@ -1121,6 +1124,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Util.FireAndForget(o => client.Close());
}
+ private void LogoutClientDueToTimeout(IClientAPI client)
+ {
+ // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method.
+ client.IsLoggingOut = true;
+
+ // Fire this out on a different thread so that we don't hold up outgoing packet processing for
+ // everybody else if this is being called due to an ack timeout.
+ // This is the same as processing as the async process of a logout request.
+ Util.FireAndForget(
+ o =>
+ { if (!client.SceneAgent.IsChildAgent)
+ client.Kick("Simulator logged you out due to connection timeout");
+ client.Close(); });
+ }
+
private void IncomingPacketHandler()
{
// Set this culture for the thread that incoming packets are received
--
cgit v1.1
From b099f26376a7d671eeb9113dd7611cfcb0e57de0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 12 Jun 2012 02:16:36 +0100
Subject: Set IClientAPI.IsActive = false early on client removal due to ack
timeout rather than using IsLoggingOut flag.
IsActive is more appropriate since unack timeout is not due to voluntary logout.
This is in line with operations such as manual kick that do not set the IsLoggingOut flag.
It's also slightly better race-wise since it reduces the chance of this operation clashing with another reason for client deactivation (e.g. manual kick).
---
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 64 ++++++++++++----------
1 file changed, 35 insertions(+), 29 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 2036f61..37d2943 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -555,15 +555,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (udpClient.IsPaused)
timeoutTicks = m_pausedAckTimeout;
- if (!client.IsLoggingOut &&
+ if (client.IsActive &&
(Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks)
{
- m_log.WarnFormat(
- "[LLUDPSERVER]: Ack timeout for {0} {1}, disconnecting",
- client.Name, client.AgentId);
+ // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
+ // though it's set later on by LLClientView.Close()
+ client.IsActive = false;
- StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
- LogoutClientDueToTimeout(client);
+ // Fire this out on a different thread so that we don't hold up outgoing packet processing for
+ // everybody else if this is being called due to an ack timeout.
+ // This is the same as processing as the async process of a logout request.
+ Util.FireAndForget(o => DeactivateClientDueToTimeout(client));
return;
}
@@ -792,7 +794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Interlocked.Increment(ref udpClient.PacketsReceived);
int now = Environment.TickCount & Int32.MaxValue;
- udpClient.TickLastPacketReceived = now;
+// udpClient.TickLastPacketReceived = now;
#region ACK Receiving
@@ -1113,30 +1115,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return client;
}
- private void RemoveClient(IClientAPI client)
+ ///
+ /// Deactivates the client if we don't receive any packets within a certain amount of time (default 60 seconds).
+ ///
+ ///
+ /// If a connection is active then we will always receive packets even if nothing else is happening, due to
+ /// regular client pings.
+ ///
+ ///
+ private void DeactivateClientDueToTimeout(IClientAPI client)
{
- // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method.
- client.IsLoggingOut = true;
+ // We must set IsActive synchronously so that we can stop the packet loop reinvoking this method, even
+ // though it's set later on by LLClientView.Close()
+ client.IsActive = false;
- // Fire this out on a different thread so that we don't hold up outgoing packet processing for
- // everybody else if this is being called due to an ack timeout.
- // This is the same as processing as the async process of a logout request.
- Util.FireAndForget(o => client.Close());
- }
+ m_log.WarnFormat(
+ "[LLUDPSERVER]: Ack timeout, disconnecting {0} agent for {1} in {2}",
+ client.SceneAgent.IsChildAgent ? "child" : "root", client.Name, m_scene.RegionInfo.RegionName);
- private void LogoutClientDueToTimeout(IClientAPI client)
- {
- // We must set IsLoggingOut synchronously so that we can stop the packet loop reinvoking this method.
- client.IsLoggingOut = true;
-
- // Fire this out on a different thread so that we don't hold up outgoing packet processing for
- // everybody else if this is being called due to an ack timeout.
- // This is the same as processing as the async process of a logout request.
- Util.FireAndForget(
- o =>
- { if (!client.SceneAgent.IsChildAgent)
- client.Kick("Simulator logged you out due to connection timeout");
- client.Close(); });
+ StatsManager.SimExtraStats.AddAbnormalClientThreadTermination();
+
+ if (!client.SceneAgent.IsChildAgent)
+ client.Kick("Simulator logged you out due to connection timeout");
+
+ client.Close();
}
private void IncomingPacketHandler()
@@ -1450,8 +1452,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected void LogoutHandler(IClientAPI client)
{
client.SendLogoutPacket();
+
if (!client.IsLoggingOut)
- RemoveClient(client);
+ {
+ client.IsLoggingOut = true;
+ client.Close();
+ }
}
}
}
\ No newline at end of file
--
cgit v1.1
From 2ca31a9841991f748e972c96a3eba96e611f1dea Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 12 Jun 2012 02:46:14 +0100
Subject: Remove accidental timeout left in during earlier debugging. Has been
in since two commits ago (b099f26)
---
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 37d2943..5126d84 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -794,7 +794,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Interlocked.Increment(ref udpClient.PacketsReceived);
int now = Environment.TickCount & Int32.MaxValue;
-// udpClient.TickLastPacketReceived = now;
+ udpClient.TickLastPacketReceived = now;
#region ACK Receiving
--
cgit v1.1