* Fixed a major memory leak in packet processing - PacketQueue.Close is never called, causing the PacketQueue for dead clients to be preserved (including it's contents).
* This patch is highly experimental and may cause clients to not be able to connect, if this is the case, it will be rolled back in approximately 5 minutes.0.6.1-post-fixes
							parent
							
								
									cbda728183
								
							
						
					
					
						commit
						fb2a1a6b7c
					
				| 
						 | 
					@ -111,5 +111,14 @@ namespace OpenSim.Framework
 | 
				
			||||||
                return m_queue.ToArray();
 | 
					                return m_queue.ToArray();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void Clear()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            lock(m_queueSync)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                m_pqueue.Clear();
 | 
				
			||||||
 | 
					                m_queue.Clear();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,8 +98,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // A list of the packets we haven't acked yet
 | 
					        // A list of the packets we haven't acked yet
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        private Dictionary<uint,uint> m_PendingAcks = new Dictionary<uint,uint>();
 | 
					        private Dictionary<uint, uint> m_PendingAcks = new Dictionary<uint, uint>();
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        // Dictionary of the packets that need acks from the client.
 | 
					        // Dictionary of the packets that need acks from the client.
 | 
				
			||||||
        //
 | 
					        //
 | 
				
			||||||
        private class AckData
 | 
					        private class AckData
 | 
				
			||||||
| 
						 | 
					@ -117,7 +117,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
				
			||||||
            public int TickCount;
 | 
					            public int TickCount;
 | 
				
			||||||
            public int Resends;
 | 
					            public int Resends;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					
 | 
				
			||||||
        private Dictionary<uint, AckData> m_NeedAck =
 | 
					        private Dictionary<uint, AckData> m_NeedAck =
 | 
				
			||||||
                new Dictionary<uint, AckData>();
 | 
					                new Dictionary<uint, AckData>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -234,6 +234,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
				
			||||||
            m_AckTimer.Stop();
 | 
					            m_AckTimer.Stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            m_PacketQueue.Enqueue(null);
 | 
					            m_PacketQueue.Enqueue(null);
 | 
				
			||||||
 | 
					            m_PacketQueue.Close();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Send one packet. This actually doesn't send anything, it queues
 | 
					        // Send one packet. This actually doesn't send anything, it queues
 | 
				
			||||||
| 
						 | 
					@ -362,7 +363,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
				
			||||||
                    if ((now - data.TickCount) > m_ResendTimeout)
 | 
					                    if ((now - data.TickCount) > m_ResendTimeout)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        m_NeedAck[packet.Header.Sequence].Resends++;
 | 
					                        m_NeedAck[packet.Header.Sequence].Resends++;
 | 
				
			||||||
                        
 | 
					
 | 
				
			||||||
                        // The client needs to be told that a packet is being resent, otherwise it appears to believe
 | 
					                        // The client needs to be told that a packet is being resent, otherwise it appears to believe
 | 
				
			||||||
                        // that it should reset its sequence to that packet number.
 | 
					                        // that it should reset its sequence to that packet number.
 | 
				
			||||||
                        packet.Header.Resent = true;
 | 
					                        packet.Header.Resent = true;
 | 
				
			||||||
| 
						 | 
					@ -767,33 +768,41 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // If we sent a killpacket
 | 
					            // If we sent a killpacket
 | 
				
			||||||
            if (packet is KillPacket)
 | 
					            if (packet is KillPacket)
 | 
				
			||||||
                Thread.CurrentThread.Abort();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Actually make the byte array and send it
 | 
					 | 
				
			||||||
            byte[] sendbuffer = packet.ToBytes();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            //m_log.DebugFormat(
 | 
					 | 
				
			||||||
            //    "[CLIENT]: In {0} sending packet {1}",
 | 
					 | 
				
			||||||
            //    m_Client.Scene.RegionInfo.ExternalEndPoint.Port, packet.Header.Sequence);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (packet.Header.Zerocoded)
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                int packetsize = Helpers.ZeroEncode(sendbuffer,
 | 
					                Abort();
 | 
				
			||||||
                        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);
 | 
					                // Actually make the byte array and send it
 | 
				
			||||||
 | 
					                byte[] sendbuffer = packet.ToBytes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                //m_log.DebugFormat(
 | 
				
			||||||
 | 
					                //    "[CLIENT]: In {0} sending packet {1}",
 | 
				
			||||||
 | 
					                //    m_Client.Scene.RegionInfo.ExternalEndPoint.Port, packet.Header.Sequence);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                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);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void Abort()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            m_PacketQueue.Close();
 | 
				
			||||||
 | 
					            Thread.CurrentThread.Abort();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,7 +131,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
				
			||||||
                    userSettings.ClientThrottleMultipler);
 | 
					                    userSettings.ClientThrottleMultipler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            throttleTimer = new Timer((int) (throttletimems/throttleTimeDivisor));
 | 
					            throttleTimer = new Timer((int) (throttletimems/throttleTimeDivisor));
 | 
				
			||||||
            throttleTimer.Elapsed += new ElapsedEventHandler(ThrottleTimerElapsed);
 | 
					            throttleTimer.Elapsed += ThrottleTimerElapsed;
 | 
				
			||||||
            throttleTimer.Start();
 | 
					            throttleTimer.Start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // TIMERS needed for this
 | 
					            // TIMERS needed for this
 | 
				
			||||||
| 
						 | 
					@ -256,9 +256,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void WipeClean()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            m_log.Info("[PACKETQUEUE] Wiping Packet Queues Clean");
 | 
				
			||||||
 | 
					            lock(this)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                ResendOutgoingPacketQueue.Clear();
 | 
				
			||||||
 | 
					                LandOutgoingPacketQueue.Clear();
 | 
				
			||||||
 | 
					                WindOutgoingPacketQueue.Clear();
 | 
				
			||||||
 | 
					                CloudOutgoingPacketQueue.Clear();
 | 
				
			||||||
 | 
					                TaskOutgoingPacketQueue.Clear();
 | 
				
			||||||
 | 
					                TaskLowpriorityPacketQueue.Clear();
 | 
				
			||||||
 | 
					                TextureOutgoingPacketQueue.Clear();
 | 
				
			||||||
 | 
					                AssetOutgoingPacketQueue.Clear();
 | 
				
			||||||
 | 
					                SendQueue.Clear();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void Close()
 | 
					        public void Close()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 | 
					            m_log.Info("[PACKETQUEUE] Close called");
 | 
				
			||||||
            Flush();
 | 
					            Flush();
 | 
				
			||||||
 | 
					            WipeClean(); // I'm sure there's a dirty joke in here somewhere. -AFrisby
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            m_enabled = false;
 | 
					            m_enabled = false;
 | 
				
			||||||
            throttleTimer.Stop();
 | 
					            throttleTimer.Stop();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue