aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMelanie Thielker2008-08-07 14:48:45 +0000
committerMelanie Thielker2008-08-07 14:48:45 +0000
commit51f90af4b735efbe0c6bdccd93c887b266f91488 (patch)
tree9bf4a3463da24290eac50b1c1aa375a5a5790d30
parentMinor formatting cleanup. (diff)
downloadopensim-SC-51f90af4b735efbe0c6bdccd93c887b266f91488.zip
opensim-SC-51f90af4b735efbe0c6bdccd93c887b266f91488.tar.gz
opensim-SC-51f90af4b735efbe0c6bdccd93c887b266f91488.tar.bz2
opensim-SC-51f90af4b735efbe0c6bdccd93c887b266f91488.tar.xz
Patch #9158
Refactor packet sending into LLPacketHandler. Change packet sequencing and ack lists to ensure packet sequences conform to wire order.
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs52
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs85
2 files changed, 80 insertions, 57 deletions
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
392 // in it to process. It's an on-purpose threadlock though because 392 // in it to process. It's an on-purpose threadlock though because
393 // without it, the clientloop will suck up all sim resources. 393 // without it, the clientloop will suck up all sim resources.
394 394
395 m_PacketHandler = new LLPacketHandler(this); 395 m_PacketHandler = new LLPacketHandler(this, m_networkServer);
396 m_PacketHandler.SynchronizeClient = SynchronizeClient; 396 m_PacketHandler.SynchronizeClient = SynchronizeClient;
397 397
398 RegisterLocalPacketHandlers(); 398 RegisterLocalPacketHandlers();
@@ -616,12 +616,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
616 if (nextPacket.Incoming) 616 if (nextPacket.Incoming)
617 { 617 {
618 DebugPacket("IN", nextPacket.Packet); 618 DebugPacket("IN", nextPacket.Packet);
619 m_PacketHandler.ProcessInPacket(nextPacket.Packet); 619 m_PacketHandler.ProcessInPacket(nextPacket);
620 } 620 }
621 else 621 else
622 { 622 {
623 DebugPacket("OUT", nextPacket.Packet); 623 DebugPacket("OUT", nextPacket.Packet);
624 ProcessOutPacket(nextPacket.Packet); 624 m_PacketHandler.ProcessOutPacket(nextPacket);
625 } 625 }
626 } 626 }
627 } 627 }
@@ -745,7 +745,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
745 + "Any further actions taken will not be processed.\n" 745 + "Any further actions taken will not be processed.\n"
746 + "Please relog", true); 746 + "Please relog", true);
747 747
748 ProcessOutPacket(packet); 748 LLQueItem item = new LLQueItem();
749 item.Packet = packet;
750
751 m_PacketHandler.ProcessOutPacket(item);
749 752
750 // There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to 753 // There may be a better way to do this. Perhaps kick? Not sure this propogates notifications to
751 // listeners yet, though. 754 // listeners yet, though.
@@ -3685,47 +3688,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3685 m_PacketHandler.PacketQueue.SetThrottleFromClient(throttles); 3688 m_PacketHandler.PacketQueue.SetThrottleFromClient(throttles);
3686 } 3689 }
3687 3690
3688 // Previously ClientView.m_packetQueue
3689
3690 /// <summary>
3691 /// Helper routine to prepare the packet for sending to UDP client
3692 /// This converts it to bytes and puts it on the outgoing buffer
3693 /// </summary>
3694 /// <param name="Pack"></param>
3695 protected virtual void ProcessOutPacket(Packet Pack)
3696 {
3697 // Keep track of when this packet was sent out
3698 Pack.TickCount = System.Environment.TickCount;
3699
3700 // Actually make the byte array and send it
3701 try
3702 {
3703 byte[] sendbuffer = Pack.ToBytes();
3704 PacketPool.Instance.ReturnPacket(Pack);
3705
3706 if (Pack.Header.Zerocoded)
3707 {
3708 int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
3709 m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, m_circuitCode);
3710 }
3711 else
3712 {
3713 //Need some extra space in case we need to add proxy information to the message later
3714 Buffer.BlockCopy(sendbuffer, 0, ZeroOutBuffer, 0, sendbuffer.Length);
3715 m_networkServer.SendPacketTo(ZeroOutBuffer, sendbuffer.Length, SocketFlags.None, m_circuitCode);
3716 }
3717 }
3718 catch (Exception e)
3719 {
3720 m_log.Warn("[client]: " +
3721 "ClientView.m_packetQueue.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " +
3722 m_userEndPoint.ToString() + " - killing thread");
3723 m_log.Error(e.ToString());
3724 Close(true);
3725 }
3726 }
3727
3728 /// <summary>
3729 /// method gets called when a new packet has arrived from the UDP server. This happens after it's been decoded into a libsl object 3691 /// method gets called when a new packet has arrived from the UDP server. This happens after it's been decoded into a libsl object
3730 /// </summary> 3692 /// </summary>
3731 /// <param name="NewPack"></param> 3693 /// <param name="NewPack"></param>
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;
31using System.Net; 31using System.Net;
32using System.Net.Sockets; 32using System.Net.Sockets;
33using System.Timers; 33using System.Timers;
34using System.Reflection;
34using libsecondlife; 35using libsecondlife;
35using libsecondlife.Packets; 36using libsecondlife.Packets;
36using Timer = System.Timers.Timer; 37using Timer = System.Timers.Timer;
37using OpenSim.Framework; 38using OpenSim.Framework;
39using OpenSim.Region.ClientStack.LindenUDP;
40using log4net;
38 41
39namespace OpenSim.Region.ClientStack.LindenUDP 42namespace OpenSim.Region.ClientStack.LindenUDP
40{ 43{
@@ -55,7 +58,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
55 uint ResendTimeout { get; set; } 58 uint ResendTimeout { get; set; }
56 59
57 void InPacket(Packet packet); 60 void InPacket(Packet packet);
58 void ProcessInPacket(Packet packet); 61 void ProcessInPacket(LLQueItem item);
62 void ProcessOutPacket(LLQueItem item);
59 void OutPacket(Packet NewPack, 63 void OutPacket(Packet NewPack,
60 ThrottleOutPacketType throttlePacketType); 64 ThrottleOutPacketType throttlePacketType);
61 void OutPacket(Packet NewPack, 65 void OutPacket(Packet NewPack,
@@ -72,6 +76,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
72 76
73 public class LLPacketHandler : IPacketHandler 77 public class LLPacketHandler : IPacketHandler
74 { 78 {
79 private static readonly ILog m_log =
80 LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
81
75 // Packet queues 82 // Packet queues
76 // 83 //
77 LLPacketQueue m_PacketQueue; 84 LLPacketQueue m_PacketQueue;
@@ -181,13 +188,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
181 188
182 List<PacketType> m_ImportantPackets = new List<PacketType>(); 189 List<PacketType> m_ImportantPackets = new List<PacketType>();
183 190
191 LLPacketServer m_PacketServer;
192 private byte[] m_ZeroOutBuffer = new byte[4096];
193
184 //////////////////////////////////////////////////////////////////// 194 ////////////////////////////////////////////////////////////////////
185 195
186 // Constructors 196 // Constructors
187 // 197 //
188 public LLPacketHandler(IClientAPI client) 198 public LLPacketHandler(IClientAPI client, LLPacketServer server)
189 { 199 {
190 m_Client = client; 200 m_Client = client;
201 m_PacketServer = server;
191 202
192 m_PacketQueue = new LLPacketQueue(client.AgentId); 203 m_PacketQueue = new LLPacketQueue(client.AgentId);
193 204
@@ -228,21 +239,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
228 return; 239 return;
229 } 240 }
230 241
231 packet.Header.Sequence = NextPacketSequenceNumber();
232
233 lock (m_NeedAck) 242 lock (m_NeedAck)
234 { 243 {
235 DropResend(id); 244 DropResend(id);
236 245
237 AddAcks(ref packet); 246 AddAcks(ref packet);
238 QueuePacket(packet, throttlePacketType, id); 247 QueuePacket(packet, throttlePacketType, id);
239
240 // We want to see that packet arrive if it's reliable
241 if (packet.Header.Reliable)
242 {
243 m_UnackedBytes += packet.ToBytes().Length;
244 m_NeedAck[packet.Header.Sequence] = new AckData(packet, id);
245 }
246 } 248 }
247 } 249 }
248 250
@@ -531,8 +533,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
531 } 533 }
532 } 534 }
533 535
534 public void ProcessInPacket(Packet packet) 536 public void ProcessInPacket(LLQueItem item)
535 { 537 {
538 Packet packet = item.Packet;
539
536 // Always ack the packet! 540 // Always ack the packet!
537 // 541 //
538 if (packet.Header.Reliable) 542 if (packet.Header.Reliable)
@@ -698,5 +702,62 @@ namespace OpenSim.Region.ClientStack.LindenUDP
698 702
699 handlerPacketDrop(packet, id); 703 handlerPacketDrop(packet, id);
700 } 704 }
705
706 // Convert the packet to bytes and stuff it onto the send queue
707 //
708 public void ProcessOutPacket(LLQueItem item)
709 {
710 Packet packet = item.Packet;
711
712 // Keep track of when this packet was sent out
713 packet.TickCount = System.Environment.TickCount;
714
715 // Assign sequence number here to prevent out of order packets
716 packet.Header.Sequence = NextPacketSequenceNumber();
717
718 lock(m_NeedAck)
719 {
720 // We want to see that packet arrive if it's reliable
721 if (packet.Header.Reliable)
722 {
723 m_UnackedBytes += packet.ToBytes().Length;
724 m_NeedAck[packet.Header.Sequence] = new AckData(packet,
725 item.Identifier);
726 }
727 }
728
729 // Actually make the byte array and send it
730 try
731 {
732 byte[] sendbuffer = packet.ToBytes();
733
734 if (packet.Header.Zerocoded)
735 {
736 int packetsize = Helpers.ZeroEncode(sendbuffer,
737 sendbuffer.Length, m_ZeroOutBuffer);
738 m_PacketServer.SendPacketTo(m_ZeroOutBuffer, packetsize,
739 SocketFlags.None, m_Client.CircuitCode);
740 }
741 else
742 {
743 // Need some extra space in case we need to add proxy
744 // information to the message later
745 Buffer.BlockCopy(sendbuffer, 0, m_ZeroOutBuffer, 0,
746 sendbuffer.Length);
747 m_PacketServer.SendPacketTo(m_ZeroOutBuffer,
748 sendbuffer.Length, SocketFlags.None, m_Client.CircuitCode);
749 }
750
751 PacketPool.Instance.ReturnPacket(packet);
752 }
753 catch (Exception e)
754 {
755 m_log.Warn("[client]: " +
756 "PacketHandler:ProcessOutPacket() - WARNING: Socket "+
757 "exception occurred - killing thread");
758 m_log.Error(e.ToString());
759 m_Client.Close(true);
760 }
761 }
701 } 762 }
702} 763}