Patch #9158
Refactor packet sending into LLPacketHandler. Change packet sequencing and ack lists to ensure packet sequences conform to wire order.0.6.0-stable
parent
0718aa0b7f
commit
51f90af4b7
|
@ -392,7 +392,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// in it to process. It's an on-purpose threadlock though because
|
// in it to process. It's an on-purpose threadlock though because
|
||||||
// without it, the clientloop will suck up all sim resources.
|
// 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;
|
m_PacketHandler.SynchronizeClient = SynchronizeClient;
|
||||||
|
|
||||||
RegisterLocalPacketHandlers();
|
RegisterLocalPacketHandlers();
|
||||||
|
@ -616,12 +616,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (nextPacket.Incoming)
|
if (nextPacket.Incoming)
|
||||||
{
|
{
|
||||||
DebugPacket("IN", nextPacket.Packet);
|
DebugPacket("IN", nextPacket.Packet);
|
||||||
m_PacketHandler.ProcessInPacket(nextPacket.Packet);
|
m_PacketHandler.ProcessInPacket(nextPacket);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DebugPacket("OUT", nextPacket.Packet);
|
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"
|
+ "Any further actions taken will not be processed.\n"
|
||||||
+ "Please relog", true);
|
+ "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
|
// There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to
|
||||||
// listeners yet, though.
|
// listeners yet, though.
|
||||||
|
@ -3685,47 +3688,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_PacketHandler.PacketQueue.SetThrottleFromClient(throttles);
|
m_PacketHandler.PacketQueue.SetThrottleFromClient(throttles);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Previously ClientView.m_packetQueue
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Helper routine to prepare the packet for sending to UDP client
|
|
||||||
/// This converts it to bytes and puts it on the outgoing buffer
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="Pack"></param>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// method gets called when a new packet has arrived from the UDP server. This happens after it's been decoded into a libsl object
|
/// method gets called when a new packet has arrived from the UDP server. This happens after it's been decoded into a libsl object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="NewPack"></param>
|
/// <param name="NewPack"></param>
|
||||||
|
|
|
@ -31,10 +31,13 @@ using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
|
using System.Reflection;
|
||||||
using libsecondlife;
|
using libsecondlife;
|
||||||
using libsecondlife.Packets;
|
using libsecondlife.Packets;
|
||||||
using Timer = System.Timers.Timer;
|
using Timer = System.Timers.Timer;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.ClientStack.LindenUDP;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
namespace OpenSim.Region.ClientStack.LindenUDP
|
namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
|
@ -55,7 +58,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
uint ResendTimeout { get; set; }
|
uint ResendTimeout { get; set; }
|
||||||
|
|
||||||
void InPacket(Packet packet);
|
void InPacket(Packet packet);
|
||||||
void ProcessInPacket(Packet packet);
|
void ProcessInPacket(LLQueItem item);
|
||||||
|
void ProcessOutPacket(LLQueItem item);
|
||||||
void OutPacket(Packet NewPack,
|
void OutPacket(Packet NewPack,
|
||||||
ThrottleOutPacketType throttlePacketType);
|
ThrottleOutPacketType throttlePacketType);
|
||||||
void OutPacket(Packet NewPack,
|
void OutPacket(Packet NewPack,
|
||||||
|
@ -72,6 +76,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public class LLPacketHandler : IPacketHandler
|
public class LLPacketHandler : IPacketHandler
|
||||||
{
|
{
|
||||||
|
private static readonly ILog m_log =
|
||||||
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
// Packet queues
|
// Packet queues
|
||||||
//
|
//
|
||||||
LLPacketQueue m_PacketQueue;
|
LLPacketQueue m_PacketQueue;
|
||||||
|
@ -181,13 +188,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
List<PacketType> m_ImportantPackets = new List<PacketType>();
|
List<PacketType> m_ImportantPackets = new List<PacketType>();
|
||||||
|
|
||||||
|
LLPacketServer m_PacketServer;
|
||||||
|
private byte[] m_ZeroOutBuffer = new byte[4096];
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
//
|
//
|
||||||
public LLPacketHandler(IClientAPI client)
|
public LLPacketHandler(IClientAPI client, LLPacketServer server)
|
||||||
{
|
{
|
||||||
m_Client = client;
|
m_Client = client;
|
||||||
|
m_PacketServer = server;
|
||||||
|
|
||||||
m_PacketQueue = new LLPacketQueue(client.AgentId);
|
m_PacketQueue = new LLPacketQueue(client.AgentId);
|
||||||
|
|
||||||
|
@ -228,21 +239,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet.Header.Sequence = NextPacketSequenceNumber();
|
|
||||||
|
|
||||||
lock (m_NeedAck)
|
lock (m_NeedAck)
|
||||||
{
|
{
|
||||||
DropResend(id);
|
DropResend(id);
|
||||||
|
|
||||||
AddAcks(ref packet);
|
AddAcks(ref packet);
|
||||||
QueuePacket(packet, throttlePacketType, id);
|
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!
|
// Always ack the packet!
|
||||||
//
|
//
|
||||||
if (packet.Header.Reliable)
|
if (packet.Header.Reliable)
|
||||||
|
@ -698,5 +702,62 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
handlerPacketDrop(packet, id);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue