From 51f90af4b735efbe0c6bdccd93c887b266f91488 Mon Sep 17 00:00:00 2001
From: Melanie Thielker
Date: Thu, 7 Aug 2008 14:48:45 +0000
Subject: Patch #9158 Refactor packet sending into LLPacketHandler. Change
packet sequencing and ack lists to ensure packet sequences conform to wire
order.
---
.../Region/ClientStack/LindenUDP/LLClientView.cs | 52 ++-----------
.../ClientStack/LindenUDP/LLPacketHandler.cs | 85 +++++++++++++++++++---
2 files changed, 80 insertions(+), 57 deletions(-)
(limited to 'OpenSim/Region/ClientStack')
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index ec945cd..a1e270b 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -392,7 +392,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// in it to process. It's an on-purpose threadlock though because
// without it, the clientloop will suck up all sim resources.
- m_PacketHandler = new LLPacketHandler(this);
+ m_PacketHandler = new LLPacketHandler(this, m_networkServer);
m_PacketHandler.SynchronizeClient = SynchronizeClient;
RegisterLocalPacketHandlers();
@@ -616,12 +616,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (nextPacket.Incoming)
{
DebugPacket("IN", nextPacket.Packet);
- m_PacketHandler.ProcessInPacket(nextPacket.Packet);
+ m_PacketHandler.ProcessInPacket(nextPacket);
}
else
{
DebugPacket("OUT", nextPacket.Packet);
- ProcessOutPacket(nextPacket.Packet);
+ m_PacketHandler.ProcessOutPacket(nextPacket);
}
}
}
@@ -745,7 +745,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
+ "Any further actions taken will not be processed.\n"
+ "Please relog", true);
- ProcessOutPacket(packet);
+ LLQueItem item = new LLQueItem();
+ item.Packet = packet;
+
+ m_PacketHandler.ProcessOutPacket(item);
// There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to
// listeners yet, though.
@@ -3685,47 +3688,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_PacketHandler.PacketQueue.SetThrottleFromClient(throttles);
}
- // Previously ClientView.m_packetQueue
-
- ///
- /// Helper routine to prepare the packet for sending to UDP client
- /// This converts it to bytes and puts it on the outgoing buffer
- ///
- ///
- protected virtual void ProcessOutPacket(Packet Pack)
- {
- // Keep track of when this packet was sent out
- Pack.TickCount = System.Environment.TickCount;
-
- // Actually make the byte array and send it
- try
- {
- byte[] sendbuffer = Pack.ToBytes();
- PacketPool.Instance.ReturnPacket(Pack);
-
- if (Pack.Header.Zerocoded)
- {
- int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
- m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode);
- }
- else
- {
- //Need some extra space in case we need to add proxy information to the message later
- Buffer.BlockCopy(sendbuffer, 0, ZeroOutBuffer, 0, sendbuffer.Length);
- m_networkServer.SendPacketTo(ZeroOutBuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
- }
- }
- catch (Exception e)
- {
- m_log.Warn("[client]: " +
- "ClientView.m_packetQueue.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " +
- m_userEndPoint.ToString() + " - killing thread");
- m_log.Error(e.ToString());
- Close(true);
- }
- }
-
- ///
/// method gets called when a new packet has arrived from the UDP server. This happens after it's been decoded into a libsl object
///
///
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
index b035150..51448f2 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs
@@ -31,10 +31,13 @@ using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Timers;
+using System.Reflection;
using libsecondlife;
using libsecondlife.Packets;
using Timer = System.Timers.Timer;
using OpenSim.Framework;
+using OpenSim.Region.ClientStack.LindenUDP;
+using log4net;
namespace OpenSim.Region.ClientStack.LindenUDP
{
@@ -55,7 +58,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uint ResendTimeout { get; set; }
void InPacket(Packet packet);
- void ProcessInPacket(Packet packet);
+ void ProcessInPacket(LLQueItem item);
+ void ProcessOutPacket(LLQueItem item);
void OutPacket(Packet NewPack,
ThrottleOutPacketType throttlePacketType);
void OutPacket(Packet NewPack,
@@ -72,6 +76,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public class LLPacketHandler : IPacketHandler
{
+ private static readonly ILog m_log =
+ LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
// Packet queues
//
LLPacketQueue m_PacketQueue;
@@ -181,13 +188,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
List m_ImportantPackets = new List();
+ LLPacketServer m_PacketServer;
+ private byte[] m_ZeroOutBuffer = new byte[4096];
+
////////////////////////////////////////////////////////////////////
// Constructors
//
- public LLPacketHandler(IClientAPI client)
+ public LLPacketHandler(IClientAPI client, LLPacketServer server)
{
m_Client = client;
+ m_PacketServer = server;
m_PacketQueue = new LLPacketQueue(client.AgentId);
@@ -228,21 +239,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return;
}
- packet.Header.Sequence = NextPacketSequenceNumber();
-
lock (m_NeedAck)
{
DropResend(id);
AddAcks(ref packet);
QueuePacket(packet, throttlePacketType, id);
-
- // We want to see that packet arrive if it's reliable
- if (packet.Header.Reliable)
- {
- m_UnackedBytes += packet.ToBytes().Length;
- m_NeedAck[packet.Header.Sequence] = new AckData(packet, id);
- }
}
}
@@ -531,8 +533,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
- public void ProcessInPacket(Packet packet)
+ public void ProcessInPacket(LLQueItem item)
{
+ Packet packet = item.Packet;
+
// Always ack the packet!
//
if (packet.Header.Reliable)
@@ -698,5 +702,62 @@ namespace OpenSim.Region.ClientStack.LindenUDP
handlerPacketDrop(packet, id);
}
+
+ // Convert the packet to bytes and stuff it onto the send queue
+ //
+ public void ProcessOutPacket(LLQueItem item)
+ {
+ Packet packet = item.Packet;
+
+ // Keep track of when this packet was sent out
+ packet.TickCount = System.Environment.TickCount;
+
+ // Assign sequence number here to prevent out of order packets
+ packet.Header.Sequence = NextPacketSequenceNumber();
+
+ lock(m_NeedAck)
+ {
+ // We want to see that packet arrive if it's reliable
+ if (packet.Header.Reliable)
+ {
+ m_UnackedBytes += packet.ToBytes().Length;
+ m_NeedAck[packet.Header.Sequence] = new AckData(packet,
+ item.Identifier);
+ }
+ }
+
+ // Actually make the byte array and send it
+ try
+ {
+ byte[] sendbuffer = packet.ToBytes();
+
+ if (packet.Header.Zerocoded)
+ {
+ int packetsize = Helpers.ZeroEncode(sendbuffer,
+ sendbuffer.Length, m_ZeroOutBuffer);
+ m_PacketServer.SendPacketTo(m_ZeroOutBuffer, packetsize,
+ SocketFlags.None, m_Client.CircuitCode);
+ }
+ else
+ {
+ // Need some extra space in case we need to add proxy
+ // information to the message later
+ Buffer.BlockCopy(sendbuffer, 0, m_ZeroOutBuffer, 0,
+ sendbuffer.Length);
+ m_PacketServer.SendPacketTo(m_ZeroOutBuffer,
+ sendbuffer.Length, SocketFlags.None, m_Client.CircuitCode);
+ }
+
+ PacketPool.Instance.ReturnPacket(packet);
+ }
+ catch (Exception e)
+ {
+ m_log.Warn("[client]: " +
+ "PacketHandler:ProcessOutPacket() - WARNING: Socket "+
+ "exception occurred - killing thread");
+ m_log.Error(e.ToString());
+ m_Client.Close(true);
+ }
+ }
}
}
--
cgit v1.1