diff --git a/OpenSim/Framework/Statistics/StatsManager.cs b/OpenSim/Framework/Statistics/StatsManager.cs index 43159ef235..436ce2fa04 100644 --- a/OpenSim/Framework/Statistics/StatsManager.cs +++ b/OpenSim/Framework/Statistics/StatsManager.cs @@ -34,14 +34,12 @@ namespace OpenSim.Framework.Statistics { private static AssetStatsCollector assetStats; private static UserStatsCollector userStats; - private static SimExtraStatsCollector simExtraStats; + private static SimExtraStatsCollector simExtraStats = new SimExtraStatsCollector(); public static AssetStatsCollector AssetStats { get { return assetStats; } } public static UserStatsCollector UserStats { get { return userStats; } } public static SimExtraStatsCollector SimExtraStats { get { return simExtraStats; } } - private StatsManager() {} - /// /// Start collecting statistics related to assets. /// Should only be called once. @@ -63,16 +61,5 @@ namespace OpenSim.Framework.Statistics return userStats; } - - /// - /// Start collecting extra sim statistics apart from those collected for the client. - /// Should only be called once. - /// - public static SimExtraStatsCollector StartCollectingSimExtraStats() - { - simExtraStats = new SimExtraStatsCollector(); - - return simExtraStats; - } } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Application/OpenSimBase.cs b/OpenSim/Region/Application/OpenSimBase.cs index 0adb69368b..76ac246caa 100644 --- a/OpenSim/Region/Application/OpenSimBase.cs +++ b/OpenSim/Region/Application/OpenSimBase.cs @@ -232,7 +232,7 @@ namespace OpenSim base.StartupSpecific(); - m_stats = StatsManager.StartCollectingSimExtraStats(); + m_stats = StatsManager.SimExtraStats; // Create a ModuleLoader instance m_moduleLoader = new ModuleLoader(m_config.Source); diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs index 90b3ede57c..1b8535cacb 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs @@ -39,7 +39,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP public sealed class IncomingPacket { /// Client this packet came from - public LLUDPClient Client; + public LLClientView Client; + /// Packet data that has been received public Packet Packet; @@ -48,7 +49,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// /// Reference to the client this packet came from /// Packet data - public IncomingPacket(LLUDPClient client, Packet packet) + public IncomingPacket(LLClientView client, Packet packet) { Client = client; Packet = packet; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 3bdde3b45e..3c23dcff8d 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -147,11 +147,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int m_elapsed500MSOutgoingPacketHandler; /// Flag to signal when clients should check for resends - private bool m_resendUnacked; + protected bool m_resendUnacked; + /// Flag to signal when clients should send ACKs - private bool m_sendAcks; + protected bool m_sendAcks; + /// Flag to signal when clients should send pings - private bool m_sendPing; + protected bool m_sendPing; private int m_defaultRTO = 0; private int m_maxRTO = 0; @@ -537,8 +539,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null); } - public void HandleUnacked(LLUDPClient udpClient) + public void HandleUnacked(LLClientView client) { + LLUDPClient udpClient = client.UDPClient; + if (!udpClient.IsConnected) return; @@ -551,12 +555,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (udpClient.IsPaused) timeoutTicks = m_pausedAckTimeout; - if ((Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) + if (!client.IsLoggingOut && + (Environment.TickCount & Int32.MaxValue) - udpClient.TickLastPacketReceived > timeoutTicks) { m_log.Warn("[LLUDPSERVER]: Ack timeout, disconnecting " + udpClient.AgentID); StatsManager.SimExtraStats.AddAbnormalClientThreadTermination(); + RemoveClient(client); - RemoveClient(udpClient); return; } @@ -879,7 +884,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion Ping Check Handling // Inbox insertion - packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); + packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet)); } #region BinaryStats @@ -1105,21 +1110,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP return client; } - private void RemoveClient(LLUDPClient udpClient) + private void RemoveClient(IClientAPI client) { - // Remove this client from the scene - IClientAPI client; - if (m_scene.TryGetClient(udpClient.AgentID, out client)) - { - client.IsLoggingOut = true; - client.Close(false); - } - else - { - m_log.WarnFormat( - "[LLUDPSERVER]: Tried to remove client with id {0} but not such client in {1}", - udpClient.AgentID, m_scene.RegionInfo.RegionName); - } + client.IsLoggingOut = true; + Util.FireAndForget(o => client.Close()); } private void IncomingPacketHandler() @@ -1246,7 +1240,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP Watchdog.RemoveThread(); } - private void ClientOutgoingPacketHandler(IClientAPI client) + protected void ClientOutgoingPacketHandler(IClientAPI client) { m_currentOutgoingClient = client; @@ -1254,12 +1248,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (client is LLClientView) { - LLUDPClient udpClient = ((LLClientView)client).UDPClient; + LLClientView llClient = (LLClientView)client; + LLUDPClient udpClient = llClient.UDPClient; if (udpClient.IsConnected) { if (m_resendUnacked) - HandleUnacked(udpClient); + HandleUnacked(llClient); if (m_sendAcks) SendAcks(udpClient); @@ -1308,7 +1303,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP { if (client is LLClientView) { - LLUDPClient udpClient = ((LLClientView)client).UDPClient; + LLClientView llClient = (LLClientView)client; + LLUDPClient udpClient = llClient.UDPClient; if (udpClient.IsConnected) { @@ -1317,7 +1313,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP nticksUnack++; watch2.Start(); - HandleUnacked(udpClient); + HandleUnacked(llClient); watch2.Stop(); avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack); @@ -1388,22 +1384,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP #endregion - private void ProcessInPacket(object state) + private void ProcessInPacket(IncomingPacket incomingPacket) { - IncomingPacket incomingPacket = (IncomingPacket)state; Packet packet = incomingPacket.Packet; - LLUDPClient udpClient = incomingPacket.Client; - IClientAPI client; + LLClientView client = incomingPacket.Client; - // Sanity check - if (packet == null || udpClient == null) - { - m_log.WarnFormat("[LLUDPSERVER]: Processing a packet with incomplete state. Packet=\"{0}\", UDPClient=\"{1}\"", - packet, udpClient); - } - - // Make sure this client is still alive - if (m_scene.TryGetClient(udpClient.AgentID, out client)) + if (client.IsActive) { m_currentIncomingClient = client; @@ -1421,8 +1407,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP catch (Exception e) { // Don't let a failure in an individual client thread crash the whole sim. - m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type); - m_log.Error(e.Message, e); + m_log.Error( + string.Format( + "[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw ", + client.Name, packet.Type), + e); } finally { @@ -1433,15 +1422,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP { m_log.DebugFormat( "[LLUDPSERVER]: Dropped incoming {0} for dead client {1} in {2}", - packet.Type, udpClient.AgentID, m_scene.RegionInfo.RegionName); + packet.Type, client.Name, m_scene.RegionInfo.RegionName); } } protected void LogoutHandler(IClientAPI client) { client.SendLogoutPacket(); - if (client.IsActive) - RemoveClient(((LLClientView)client).UDPClient); + if (!client.IsLoggingOut) + RemoveClient(client); } } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index 1321470c28..109a8e1914 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -45,6 +45,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests [TestFixture] public class BasicCircuitTests { + private Scene m_scene; + private TestLLUDPServer m_udpServer; + [TestFixtureSetUp] public void FixtureInit() { @@ -61,83 +64,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests Util.FireAndForgetMethod = Util.DefaultFireAndForgetMethod; } -// /// -// /// Add a client for testing -// /// -// /// -// /// -// /// -// /// Agent circuit manager used in setting up the stack -// protected void SetupStack( -// IScene scene, out TestLLUDPServer testLLUDPServer, out TestLLPacketServer testPacketServer, -// out AgentCircuitManager acm) -// { -// IConfigSource configSource = new IniConfigSource(); -// ClientStackUserSettings userSettings = new ClientStackUserSettings(); -// testLLUDPServer = new TestLLUDPServer(); -// acm = new AgentCircuitManager(); -// -// uint port = 666; -// testLLUDPServer.Initialise(null, ref port, 0, false, configSource, acm); -// testPacketServer = new TestLLPacketServer(testLLUDPServer, userSettings); -// testLLUDPServer.LocalScene = scene; -// } - -// /// -// /// Set up a client for tests which aren't concerned with this process itself and where only one client is being -// /// tested -// /// -// /// -// /// -// /// -// /// -// protected void AddClient( -// uint circuitCode, EndPoint epSender, TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) -// { -// UUID myAgentUuid = UUID.Parse("00000000-0000-0000-0000-000000000001"); -// UUID mySessionUuid = UUID.Parse("00000000-0000-0000-0000-000000000002"); -// -// AddClient(circuitCode, epSender, myAgentUuid, mySessionUuid, testLLUDPServer, acm); -// } - -// /// -// /// Set up a client for tests which aren't concerned with this process itself -// /// -// /// -// /// -// /// -// /// -// /// -// /// -// protected void AddClient( -// uint circuitCode, EndPoint epSender, UUID agentId, UUID sessionId, -// TestLLUDPServer testLLUDPServer, AgentCircuitManager acm) -// { -// AgentCircuitData acd = new AgentCircuitData(); -// acd.AgentID = agentId; -// acd.SessionID = sessionId; -// -// UseCircuitCodePacket uccp = new UseCircuitCodePacket(); -// -// UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock -// = new UseCircuitCodePacket.CircuitCodeBlock(); -// uccpCcBlock.Code = circuitCode; -// uccpCcBlock.ID = agentId; -// uccpCcBlock.SessionID = sessionId; -// uccp.CircuitCode = uccpCcBlock; -// -// acm.AddNewCircuit(circuitCode, acd); -// -// testLLUDPServer.LoadReceive(uccp, epSender); -// testLLUDPServer.ReceiveData(null); -// } + [SetUp] + public void SetUp() + { + m_scene = new SceneHelpers().SetupScene(); + } /// /// Build an object name packet for test purposes /// /// /// - protected ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) + private ObjectNamePacket BuildTestObjectNamePacket(uint objectLocalId, string objectName) { ObjectNamePacket onp = new ObjectNamePacket(); ObjectNamePacket.ObjectDataBlock odb = new ObjectNamePacket.ObjectDataBlock(); @@ -148,29 +86,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests return onp; } - - /// - /// Test adding a client to the stack - /// - [Test] - public void TestAddClient() - { - TestHelpers.InMethod(); -// XmlConfigurator.Configure(); - TestScene scene = new SceneHelpers().SetupScene(); - uint myCircuitCode = 123456; + private void AddUdpServer() + { + AddUdpServer(new IniConfigSource()); + } + + private void AddUdpServer(IniConfigSource configSource) + { + uint port = 0; + AgentCircuitManager acm = m_scene.AuthenticateHandler; + + m_udpServer = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, configSource, acm); + m_udpServer.AddScene(m_scene); + } + + /// + /// Used by tests that aren't testing this stage. + /// + private ScenePresence AddClient() + { UUID myAgentUuid = TestHelpers.ParseTail(0x1); UUID mySessionUuid = TestHelpers.ParseTail(0x2); + uint myCircuitCode = 123456; IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); - uint port = 0; - AgentCircuitManager acm = scene.AuthenticateHandler; - - TestLLUDPServer llUdpServer - = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm); - llUdpServer.AddScene(scene); - UseCircuitCodePacket uccp = new UseCircuitCodePacket(); UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock @@ -185,26 +125,67 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); - llUdpServer.PacketReceived(upb); + AgentCircuitData acd = new AgentCircuitData(); + acd.AgentID = myAgentUuid; + acd.SessionID = mySessionUuid; + + m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); + + m_udpServer.PacketReceived(upb); + + return m_scene.GetScenePresence(myAgentUuid); + } + + /// + /// Test adding a client to the stack + /// + [Test] + public void TestAddClient() + { + TestHelpers.InMethod(); +// XmlConfigurator.Configure(); + + AddUdpServer(); + + UUID myAgentUuid = TestHelpers.ParseTail(0x1); + UUID mySessionUuid = TestHelpers.ParseTail(0x2); + uint myCircuitCode = 123456; + IPEndPoint testEp = new IPEndPoint(IPAddress.Loopback, 999); + + UseCircuitCodePacket uccp = new UseCircuitCodePacket(); + + UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock + = new UseCircuitCodePacket.CircuitCodeBlock(); + uccpCcBlock.Code = myCircuitCode; + uccpCcBlock.ID = myAgentUuid; + uccpCcBlock.SessionID = mySessionUuid; + uccp.CircuitCode = uccpCcBlock; + + byte[] uccpBytes = uccp.ToBytes(); + UDPPacketBuffer upb = new UDPPacketBuffer(testEp, uccpBytes.Length); + upb.DataLength = uccpBytes.Length; // God knows why this isn't set by the constructor. + Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length); + + m_udpServer.PacketReceived(upb); // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet - Assert.That(scene.GetScenePresence(myAgentUuid), Is.Null); + Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null); AgentCircuitData acd = new AgentCircuitData(); acd.AgentID = myAgentUuid; acd.SessionID = mySessionUuid; - acm.AddNewCircuit(myCircuitCode, acd); + m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd); - llUdpServer.PacketReceived(upb); + m_udpServer.PacketReceived(upb); // Should succeed now - ScenePresence sp = scene.GetScenePresence(myAgentUuid); + ScenePresence sp = m_scene.GetScenePresence(myAgentUuid); Assert.That(sp.UUID, Is.EqualTo(myAgentUuid)); - Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(1)); + Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1)); - Packet packet = llUdpServer.PacketsSent[0]; + Packet packet = m_udpServer.PacketsSent[0]; Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket))); PacketAckPacket ackPacket = packet as PacketAckPacket; @@ -212,6 +193,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0)); } + [Test] + public void TestLogoutClientDueToAck() + { + TestHelpers.InMethod(); +// TestHelpers.EnableLogging(); + + IniConfigSource ics = new IniConfigSource(); + IConfig config = ics.AddConfig("ClientStack.LindenUDP"); + config.Set("AckTimeout", -1); + AddUdpServer(ics); + + ScenePresence sp = AddClient(); + m_udpServer.ClientOutgoingPacketHandler(sp.ControllingClient, true, false, false); + + ScenePresence spAfterAckTimeout = m_scene.GetScenePresence(sp.UUID); + Assert.That(spAfterAckTimeout, Is.Null); + +// TestHelpers.DisableLogging(); + } + // /// // /// Test removing a client from the stack // /// diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs index 0302385ad2..27b9e5b3f3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs @@ -59,6 +59,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests PacketsSent.Add(packet); } + public void ClientOutgoingPacketHandler(IClientAPI client, bool resendUnacked, bool sendAcks, bool sendPing) + { + m_resendUnacked = resendUnacked; + m_sendAcks = sendAcks; + m_sendPing = sendPing; + + ClientOutgoingPacketHandler(client); + } + //// /// //// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive //// /// diff --git a/OpenSim/Tools/pCampBot/Bot.cs b/OpenSim/Tools/pCampBot/Bot.cs index b6cd287202..daaa3c0070 100644 --- a/OpenSim/Tools/pCampBot/Bot.cs +++ b/OpenSim/Tools/pCampBot/Bot.cs @@ -480,6 +480,9 @@ namespace pCampBot public void Objects_NewPrim(object sender, PrimEventArgs args) { +// if (Name.EndsWith("4")) +// throw new Exception("Aaargh"); + Primitive prim = args.Prim; if (prim != null) diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 9afac3fe6a..58e9b105ee 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini @@ -1153,6 +1153,8 @@ ; currently unused ; AllowosConsoleCommand=false + ; Are god functions such as llSetObjectPermMask() allowed? If true then gods and only gods have access to these functions. + ; If false then gods cannot execute these functions either. AllowGodFunctions = false ; Maximum number of llListen events we allow over the entire region. diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 1c04ab5c12..f70d13bd96 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -166,7 +166,7 @@ ServiceConnectors = "8003/OpenSim.Server.Handlers.dll:AssetServiceConnector,8003 ;; This switch creates the minimum set of body parts and avatar entries for a viewer 2 ;; to show a default "Ruth" avatar rather than a cloud for a newly created user. ;; Default is false - ; CreateDefaultAvatarEntries = false + CreateDefaultAvatarEntries = true ;; Allow the service to process HTTP createuser calls. ;; Default is false.