From 7ca688f5c5e283a6854ddd14911cb1ea83323e76 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Thu, 8 Dec 2011 21:45:02 +0000 Subject: [PATCH] Extend TestAddClient() to check that the first packet received is an ack packet --- .../ClientStack/Linden/UDP/LLUDPServer.cs | 16 +- .../Linden/UDP/Tests/BasicCircuitTests.cs | 16 +- .../Linden/UDP/Tests/TestLLUDPServer.cs | 181 +++++++++--------- 3 files changed, 118 insertions(+), 95 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index ac21805c54..cef5f74257 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs @@ -328,7 +328,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP /// The method to call if the packet is not acked by the client. If null, then a standard /// resend of the packet is done. /// - public void SendPacket( + public virtual void SendPacket( LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method) { // CoarseLocationUpdate packets cannot be split in an automated way @@ -928,6 +928,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); } + /// + /// Send an ack immediately to the given endpoint. + /// + /// + /// FIXME: Might be possible to use SendPacketData() like everything else, but this will require refactoring so + /// that we can obtain the UDPClient easily at this point. + /// + /// + /// private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber) { PacketAckPacket ack = new PacketAckPacket(); @@ -936,6 +945,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP ack.Packets[0] = new PacketAckPacket.PacketsBlock(); ack.Packets[0].ID = sequenceNumber; + SendAckImmediate(remoteEndpoint, ack); + } + + public virtual void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack) + { byte[] packetData = ack.ToBytes(); int length = packetData.Length; diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs index c6a5b9859c..1457194eed 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs @@ -37,7 +37,7 @@ using OpenSim.Region.Framework.Scenes; using OpenSim.Tests.Common; using OpenSim.Tests.Common.Mock; -namespace OpenSim.Region.ClientStack.LindenUDP +namespace OpenSim.Region.ClientStack.LindenUDP.Tests { /// /// This will contain basic tests for the LindenUDP client stack @@ -167,8 +167,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP uint port = 0; AgentCircuitManager acm = scene.AuthenticateHandler; - LLUDPServer llUdpServer - = new LLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm); + TestLLUDPServer llUdpServer + = new TestLLUDPServer(IPAddress.Any, ref port, 0, false, new IniConfigSource(), acm); llUdpServer.AddScene(scene); UseCircuitCodePacket uccp = new UseCircuitCodePacket(); @@ -201,6 +201,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Should succeed now ScenePresence sp = scene.GetScenePresence(myAgentUuid); Assert.That(sp.UUID, Is.EqualTo(myAgentUuid)); + + // FIXME: We're still replying to an ack when the client is not authorized, which is not correct behaviour. + Assert.That(llUdpServer.PacketsSent.Count, Is.EqualTo(2)); + + Packet packet = llUdpServer.PacketsSent[1]; + Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket))); + + PacketAckPacket ackPacket = packet as PacketAckPacket; + Assert.That(ackPacket.Packets.Length, Is.EqualTo(1)); + Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0)); } // /// diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs index dd7999aa91..0302385ad2 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/TestLLUDPServer.cs @@ -36,107 +36,106 @@ using OpenSim.Framework; namespace OpenSim.Region.ClientStack.LindenUDP.Tests { /// - /// This class enables synchronous testing of the LLUDPServer by allowing us to load our own data into the end - /// receive event + /// This class enables regression testing of the LLUDPServer by allowing us to intercept outgoing data. /// public class TestLLUDPServer : LLUDPServer { + public List PacketsSent { get; private set; } + public TestLLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) : base(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager) - {} + { + PacketsSent = new List(); + } - /// - /// The chunks of data to pass to the LLUDPServer when it calls EndReceive - /// - protected Queue m_chunksToLoad = new Queue(); - -// protected override void BeginReceive() -// { -// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException) -// { -// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue(); -// reusedEpSender = tuple.Sender; -// throw new SocketException(); -// } -// } - -// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender) -// { -// numBytes = 0; -// -// //m_log.Debug("Queue size " + m_chunksToLoad.Count); -// -// if (m_chunksToLoad.Count <= 0) -// return false; -// -// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue(); -// RecvBuffer = tuple.Data; -// numBytes = tuple.Data.Length; -// epSender = tuple.Sender; -// -// return true; -// } - -// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode) -// { -// // Don't do anything just yet -// } - - /// - /// Signal that this chunk should throw an exception on Socket.BeginReceive() - /// - /// - public void LoadReceiveWithBeginException(EndPoint epSender) + public override void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack) { - ChunkSenderTuple tuple = new ChunkSenderTuple(epSender); - tuple.BeginReceiveException = true; - m_chunksToLoad.Enqueue(tuple); + PacketsSent.Add(ack); } - - /// - /// Load some data to be received by the LLUDPServer on the next receive call - /// - /// - /// - public void LoadReceive(byte[] data, EndPoint epSender) - { - m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender)); - } - - /// - /// Load a packet to be received by the LLUDPServer on the next receive call - /// - /// - public void LoadReceive(Packet packet, EndPoint epSender) - { - LoadReceive(packet.ToBytes(), epSender); - } - - /// - /// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send - /// - /// - public void ReceiveData(IAsyncResult result) - { - // Doesn't work the same way anymore -// while (m_chunksToLoad.Count > 0) -// OnReceivedData(result); - } - - /// - /// Has a circuit with the given code been established? - /// - /// - /// - public bool HasCircuit(uint circuitCode) - { -// lock (clientCircuits_reverse) -// { -// return clientCircuits_reverse.ContainsKey(circuitCode); -// } - return true; + public override void SendPacket( + LLUDPClient udpClient, Packet packet, ThrottleOutPacketType category, bool allowSplitting, UnackedPacketMethod method) + { + PacketsSent.Add(packet); } + +//// /// +//// /// The chunks of data to pass to the LLUDPServer when it calls EndReceive +//// /// +//// protected Queue m_chunksToLoad = new Queue(); +// +//// protected override void BeginReceive() +//// { +//// if (m_chunksToLoad.Count > 0 && m_chunksToLoad.Peek().BeginReceiveException) +//// { +//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue(); +//// reusedEpSender = tuple.Sender; +//// throw new SocketException(); +//// } +//// } +// +//// protected override bool EndReceive(out int numBytes, IAsyncResult result, ref EndPoint epSender) +//// { +//// numBytes = 0; +//// +//// //m_log.Debug("Queue size " + m_chunksToLoad.Count); +//// +//// if (m_chunksToLoad.Count <= 0) +//// return false; +//// +//// ChunkSenderTuple tuple = m_chunksToLoad.Dequeue(); +//// RecvBuffer = tuple.Data; +//// numBytes = tuple.Data.Length; +//// epSender = tuple.Sender; +//// +//// return true; +//// } +// +//// public override void SendPacketTo(byte[] buffer, int size, SocketFlags flags, uint circuitcode) +//// { +//// // Don't do anything just yet +//// } +// +// /// +// /// Signal that this chunk should throw an exception on Socket.BeginReceive() +// /// +// /// +// public void LoadReceiveWithBeginException(EndPoint epSender) +// { +// ChunkSenderTuple tuple = new ChunkSenderTuple(epSender); +// tuple.BeginReceiveException = true; +// m_chunksToLoad.Enqueue(tuple); +// } +// +// /// +// /// Load some data to be received by the LLUDPServer on the next receive call +// /// +// /// +// /// +// public void LoadReceive(byte[] data, EndPoint epSender) +// { +// m_chunksToLoad.Enqueue(new ChunkSenderTuple(data, epSender)); +// } +// +// /// +// /// Load a packet to be received by the LLUDPServer on the next receive call +// /// +// /// +// public void LoadReceive(Packet packet, EndPoint epSender) +// { +// LoadReceive(packet.ToBytes(), epSender); +// } +// +// /// +// /// Calls the protected asynchronous result method. This fires out all data chunks currently queued for send +// /// +// /// +// public void ReceiveData(IAsyncResult result) +// { +// // Doesn't work the same way anymore +//// while (m_chunksToLoad.Count > 0) +//// OnReceivedData(result); +// } } ///