diff options
author | Teravus Ovares | 2008-05-28 08:40:22 +0000 |
---|---|---|
committer | Teravus Ovares | 2008-05-28 08:40:22 +0000 |
commit | 715fbecd79377a04bb0617e02cb00675fdc755c9 (patch) | |
tree | af75c3a5e75974e8923d749d339ef933f6013e42 /OpenSim/Region/ClientStack/LindenUDP | |
parent | Formatting cleanup. (diff) | |
download | opensim-SC-715fbecd79377a04bb0617e02cb00675fdc755c9.zip opensim-SC-715fbecd79377a04bb0617e02cb00675fdc755c9.tar.gz opensim-SC-715fbecd79377a04bb0617e02cb00675fdc755c9.tar.bz2 opensim-SC-715fbecd79377a04bb0617e02cb00675fdc755c9.tar.xz |
* Implements duplicate packet tracking. This virtually eliminates object duplication causing 2-3 duplicates depending on the UDP connection quality. This also eliminates duplicated chat, etc.
* It's verbose currently since this is new. You'll see: [CLIENT]: Warning Duplicate packet detected X Dropping. After this is sufficiently tested we'll remove that m_log.info line.
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index c9a6b84..853d550 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -47,6 +47,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
47 | { | 47 | { |
48 | public delegate bool PacketMethod(IClientAPI simClient, Packet packet); | 48 | public delegate bool PacketMethod(IClientAPI simClient, Packet packet); |
49 | 49 | ||
50 | public class PacketDupeLimiter | ||
51 | { | ||
52 | public PacketType pktype; | ||
53 | public int timeIn; | ||
54 | public uint packetId; | ||
55 | public PacketDupeLimiter() | ||
56 | { | ||
57 | } | ||
58 | } | ||
59 | |||
50 | /// <summary> | 60 | /// <summary> |
51 | /// Handles new client connections | 61 | /// Handles new client connections |
52 | /// Constructor takes a single Packet and authenticates everything | 62 | /// Constructor takes a single Packet and authenticates everything |
@@ -83,6 +93,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
83 | 93 | ||
84 | private int m_packetsSent = 0; | 94 | private int m_packetsSent = 0; |
85 | private int m_lastPacketsSentSentToScene = 0; | 95 | private int m_lastPacketsSentSentToScene = 0; |
96 | private int m_clearDuplicatePacketTrackingOlderThenXSeconds = 30; | ||
86 | 97 | ||
87 | private int m_probesWithNoIngressPackets = 0; | 98 | private int m_probesWithNoIngressPackets = 0; |
88 | private int m_lastPacketsReceived = 0; | 99 | private int m_lastPacketsReceived = 0; |
@@ -92,6 +103,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
92 | private readonly uint m_circuitCode; | 103 | private readonly uint m_circuitCode; |
93 | private int m_moneyBalance; | 104 | private int m_moneyBalance; |
94 | 105 | ||
106 | private Dictionary<uint, PacketDupeLimiter> m_dupeLimiter = new Dictionary<uint, PacketDupeLimiter>(); | ||
107 | |||
95 | private int m_animationSequenceNumber = 1; | 108 | private int m_animationSequenceNumber = 1; |
96 | 109 | ||
97 | private byte[] m_channelVersion = Helpers.StringToField("OpenSimulator 0.5"); // Dummy value needed by libSL | 110 | private byte[] m_channelVersion = Helpers.StringToField("OpenSimulator 0.5"); // Dummy value needed by libSL |
@@ -3837,6 +3850,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3837 | m_lastPacketsSentSentToScene = m_packetsSent; | 3850 | m_lastPacketsSentSentToScene = m_packetsSent; |
3838 | } | 3851 | } |
3839 | } | 3852 | } |
3853 | protected void ClearOldPacketDupeTracking() | ||
3854 | { | ||
3855 | lock (m_dupeLimiter) | ||
3856 | { | ||
3857 | List<uint> toEliminate = new List<uint>(); | ||
3858 | try | ||
3859 | { | ||
3860 | |||
3861 | foreach (uint seq in m_dupeLimiter.Keys) | ||
3862 | { | ||
3863 | PacketDupeLimiter pkdata = null; | ||
3864 | m_dupeLimiter.TryGetValue(seq, out pkdata); | ||
3865 | if (pkdata != null) | ||
3866 | { | ||
3867 | // doing a foreach loop, so we don't want to modify the dictionary while we're searching it | ||
3868 | if (Util.UnixTimeSinceEpoch() - pkdata.timeIn > m_clearDuplicatePacketTrackingOlderThenXSeconds) | ||
3869 | toEliminate.Add(seq); | ||
3870 | } | ||
3871 | } | ||
3872 | } | ||
3873 | catch (InvalidOperationException) | ||
3874 | { | ||
3875 | m_log.Info("[PACKET]: Unable to clear dupe check packet data"); | ||
3876 | } | ||
3877 | |||
3878 | // remove the dupe packets that we detected in the loop above. | ||
3879 | uint[] seqsToRemove = toEliminate.ToArray(); | ||
3880 | for (int i = 0; i<seqsToRemove.Length; i++) | ||
3881 | { | ||
3882 | if (m_dupeLimiter.ContainsKey(seqsToRemove[i])) | ||
3883 | m_dupeLimiter.Remove(seqsToRemove[i]); | ||
3884 | } | ||
3885 | } | ||
3886 | } | ||
3840 | 3887 | ||
3841 | #endregion | 3888 | #endregion |
3842 | 3889 | ||
@@ -3866,7 +3913,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3866 | protected void ProcessInPacket(Packet Pack) | 3913 | protected void ProcessInPacket(Packet Pack) |
3867 | { | 3914 | { |
3868 | ack_pack(Pack); | 3915 | ack_pack(Pack); |
3869 | 3916 | lock (m_dupeLimiter) | |
3917 | { | ||
3918 | if (m_dupeLimiter.ContainsKey(Pack.Header.Sequence)) | ||
3919 | { | ||
3920 | m_log.Info("[CLIENT]: Warning Duplicate packet detected" + Pack.Type.ToString() + " Dropping."); | ||
3921 | return; | ||
3922 | } | ||
3923 | else | ||
3924 | { | ||
3925 | PacketDupeLimiter pkdedupe = new PacketDupeLimiter(); | ||
3926 | pkdedupe.packetId = Pack.Header.ID; | ||
3927 | pkdedupe.pktype = Pack.Type; | ||
3928 | pkdedupe.timeIn = Util.UnixTimeSinceEpoch(); | ||
3929 | m_dupeLimiter.Add(Pack.Header.Sequence, pkdedupe); | ||
3930 | } | ||
3931 | } | ||
3932 | //m_log.Info("Sequence" | ||
3870 | if (ProcessPacketMethod(Pack)) | 3933 | if (ProcessPacketMethod(Pack)) |
3871 | { | 3934 | { |
3872 | //there is a handler registered that handled this packet type | 3935 | //there is a handler registered that handled this packet type |