diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs index d7071da161..4b6e9a55c3 100644 --- a/OpenSim/Framework/IScene.cs +++ b/OpenSim/Framework/IScene.cs @@ -46,6 +46,7 @@ namespace OpenSim.Framework void AddNewClient(IClientAPI client, bool child); void RemoveClient(LLUUID agentID); + void CloseAllAgents(uint circuitcode); void Restart(int seconds); bool OtherRegionUp(RegionInfo thisRegion); diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 5e0ab6511e..df52745043 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -209,8 +209,8 @@ namespace OpenSim.Region.ClientStack m_scene.RemoveClient(AgentId); // Send the STOP packet - //libsecondlife.Packets.DisableSimulatorPacket disable = new libsecondlife.Packets.DisableSimulatorPacket(); - //OutPacket(disable, ThrottleOutPacketType.Task); + DisableSimulatorPacket disable = new DisableSimulatorPacket(); + OutPacket(disable, ThrottleOutPacketType.Task); // FLUSH Packets m_packetQueue.Close(); @@ -225,6 +225,10 @@ namespace OpenSim.Region.ClientStack // This is just to give the client a reasonable chance of // flushing out all it's packets. There should probably // be a better mechanism here + + // We can't reach into other scenes and close the connection + // We need to do this over grid communications + m_scene.CloseAllAgents(CircuitCode); m_clientThread.Abort(); } diff --git a/OpenSim/Region/ClientStack/PacketServer.cs b/OpenSim/Region/ClientStack/PacketServer.cs index 39c3d32f03..308728e1fa 100644 --- a/OpenSim/Region/ClientStack/PacketServer.cs +++ b/OpenSim/Region/ClientStack/PacketServer.cs @@ -123,13 +123,16 @@ namespace OpenSim.Region.ClientStack /// public virtual void CloseCircuit(uint circuitcode) { + OpenSim.Framework.Console.MainLog.Instance.Debug("PACKETSERVER", "Removing Circuit Code"); m_networkHandler.RemoveClientCircuit(circuitcode); - m_scene.ClientManager.CloseAllAgents(circuitcode); + OpenSim.Framework.Console.MainLog.Instance.Debug("PACKETSERVER", "Removed Circuit Code"); + //m_scene.ClientManager.CloseAllAgents(circuitcode); } public virtual void CloseClient(IClientAPI client) { CloseCircuit(client.CircuitCode); + client.Close(); } } } diff --git a/OpenSim/Region/ClientStack/UDPServer.cs b/OpenSim/Region/ClientStack/UDPServer.cs index 55ef4a4a20..2b2269e23a 100644 --- a/OpenSim/Region/ClientStack/UDPServer.cs +++ b/OpenSim/Region/ClientStack/UDPServer.cs @@ -119,16 +119,48 @@ namespace OpenSim.Region.ClientStack { case SocketError.AlreadyInProgress: case SocketError.NetworkReset: + case SocketError.ConnectionReset: + try + { + CloseEndPoint(epSender); + } + catch (System.Exception a) + { + MainLog.Instance.Verbose("UDPSERVER", a.ToString()); + } + try + { + Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); + + // Ter: For some stupid reason ConnectionReset basically kills our async event structure.. + // so therefore.. we've got to tell the server to BeginReceiveFrom again. + // This will happen over and over until we've gone through all packets + // sent to and from this particular user. + // Stupid I know.. + // but Flusing the buffer would be even more stupid... so, we're stuck with this ugly method. + + } + catch (SocketException) + { + + } + break; default: - Console.WriteLine("Remote host Closed connection"); - CloseEndPoint(epSender); + // Here's some reference code! :D + // Shutdown and restart the UDP listener! hehe + // Shiny + + //Server.Shutdown(SocketShutdown.Both); + //CloseEndPoint(epSender); + //ServerListener(); break; } return; } - catch (System.ObjectDisposedException) + catch (System.ObjectDisposedException e) { + MainLog.Instance.Debug("UDPSERVER", e.ToString()); return; } @@ -138,8 +170,9 @@ namespace OpenSim.Region.ClientStack { packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer); } - catch(Exception) + catch(Exception e) { + MainLog.Instance.Debug("UDPSERVER", e.ToString()); } // do we already have a circuit for this endpoint @@ -147,18 +180,21 @@ namespace OpenSim.Region.ClientStack if (clientCircuits.TryGetValue(epSender, out circuit)) { //if so then send packet to the packetserver + //MainLog.Instance.Warn("UDPSERVER", "ALREADY HAVE Circuit!"); m_packetServer.InPacket(circuit, packet); } else if (packet.Type == PacketType.UseCircuitCode) { // new client + MainLog.Instance.Debug("UDPSERVER", "Adding New Client"); AddNewClient(packet); } else { + // invalid client //CFK: This message seems to have served its usefullness as of 12-15 so I am commenting it out for now - //CFK: m_log.Warn("client", "Got a packet from an invalid client - " + epSender.ToString()); + //m_log.Warn("client", "Got a packet from an invalid client - " + epSender.ToString()); } Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null); @@ -169,7 +205,9 @@ namespace OpenSim.Region.ClientStack uint circuit; if (clientCircuits.TryGetValue(sender, out circuit)) { + MainLog.Instance.Debug("UDPSERVER", "CloseEndPoint:ClosingCircuit"); m_packetServer.CloseCircuit(circuit); + MainLog.Instance.Debug("UDPSERVER", "CloseEndPoint:ClosedCircuit"); } } @@ -222,8 +260,13 @@ namespace OpenSim.Region.ClientStack EndPoint sendto = null; if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto)) { + MainLog.Instance.Debug("UDPSERVER", "RemovingClientCircuit"); clientCircuits.Remove(sendto); + MainLog.Instance.Debug("UDPSERVER", "Removed Client Circuit"); + + MainLog.Instance.Debug("UDPSERVER", "Removing Reverse ClientCircuit"); clientCircuits_reverse.Remove(circuitcode); + MainLog.Instance.Debug("UDPSERVER", "Removed Reverse ClientCircuit"); } } } diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 1145b00ee9..bfdf51792c 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -1243,7 +1243,12 @@ namespace OpenSim.Region.Environment.Scenes // Remove client agent from profile, so new logins will work CommsManager.UserService.clearUserAgent(agentID); } + public override void CloseAllAgents(uint circuitcode) + { + // Called by ClientView to kill all circuit codes + ClientManager.CloseAllAgents(circuitcode); + } public void NotifyMyCoarseLocationChange() { ForEachScenePresence(delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); diff --git a/OpenSim/Region/Environment/Scenes/SceneBase.cs b/OpenSim/Region/Environment/Scenes/SceneBase.cs index 75118e211c..35d88ebc66 100644 --- a/OpenSim/Region/Environment/Scenes/SceneBase.cs +++ b/OpenSim/Region/Environment/Scenes/SceneBase.cs @@ -130,6 +130,8 @@ namespace OpenSim.Region.Environment.Scenes /// public abstract void RemoveClient(LLUUID agentID); + public abstract void CloseAllAgents(uint circuitcode); + #endregion ///