Exemple #1
0
        public bool EnqueueOutgoing(OutgoingPacket packet)
        {
            int category = (int)packet.Category;

            if (category >= 0 && category < m_packetOutboxes.Length)
            {
                OpenSim.Framework.LocklessQueue <OutgoingPacket> queue = m_packetOutboxes[category];
                TokenBucket bucket = m_throttleCategories[category];

                if (bucket.RemoveTokens(packet.Buffer.DataLength))
                {
                    // Enough tokens were removed from the bucket, the packet will not be queued
                    return(false);
                }
                else
                {
                    // Not enough tokens in the bucket, queue this packet
                    queue.Enqueue(packet);
                    return(true);
                }
            }
            else
            {
                // We don't have a token bucket for this category, so it will not be queued
                return(false);
            }
        }
Exemple #2
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="server">Reference to the UDP server this client is connected to</param>
        /// <param name="rates">Default throttling rates and maximum throttle limits</param>
        /// <param name="parentThrottle">Parent HTB (hierarchical token bucket)
        /// that the child throttles will be governed by</param>
        /// <param name="circuitCode">Circuit code for this connection</param>
        /// <param name="agentID">AgentID for the connected agent</param>
        /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
        public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
        {
            AgentID        = agentID;
            RemoteEndPoint = remoteEndPoint;
            CircuitCode    = circuitCode;
            m_udpServer    = server;
            if (defaultRTO != 0)
            {
                m_defaultRTO = defaultRTO;
            }
            if (maxRTO != 0)
            {
                m_maxRTO = maxRTO;
            }

            // Create a token bucket throttle for this client that has the scene token bucket as a parent
            m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total);
            // Create an array of token buckets for this clients different throttle categories
            m_throttleCategories = new TokenBucket[(int)ThrottleOutPacketType.Count];

            for (int i = 0; i < (int)ThrottleOutPacketType.Count; i++)
            {
                ThrottleOutPacketType type = (ThrottleOutPacketType)i;

                // Initialize the packet outboxes, where packets sit while they are waiting for tokens
                m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue <OutgoingPacket>();
                // Initialize the token buckets that control the throttling for each category
                m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type));
            }

            TotalRateRequested = STARTPERCLIENTRATE;
            TotalRateMin       = MINPERCLIENTRATE;

            m_throttle.MaxBurst = STARTPERCLIENTRATE;
            m_throttle.DripRate = STARTPERCLIENTRATE;

            MapCatsToPriority[(int)ThrottleOutPacketType.Resend]     = 2;
            MapCatsToPriority[(int)ThrottleOutPacketType.Land]       = 1;
            MapCatsToPriority[(int)ThrottleOutPacketType.Wind]       = 0;
            MapCatsToPriority[(int)ThrottleOutPacketType.Cloud]      = 0;
            MapCatsToPriority[(int)ThrottleOutPacketType.Task]       = 4;
            MapCatsToPriority[(int)ThrottleOutPacketType.Texture]    = 2;
            MapCatsToPriority[(int)ThrottleOutPacketType.Asset]      = 3;
            MapCatsToPriority[(int)ThrottleOutPacketType.Transfer]   = 5;
            MapCatsToPriority[(int)ThrottleOutPacketType.State]      = 5;
            MapCatsToPriority[(int)ThrottleOutPacketType.AvatarInfo] = 6;
            MapCatsToPriority[(int)ThrottleOutPacketType.OutBand]    = 7;

//            m_lastthrottleCategoryChecked = 0;

            // Default the retransmission timeout to three seconds
            RTO = m_defaultRTO;

            // Initialize this to a sane value to prevent early disconnects
            TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
        }
Exemple #3
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="server">Reference to the UDP server this client is connected to</param>
        /// <param name="rates">Default throttling rates and maximum throttle limits</param>
        /// <param name="parentThrottle">Parent HTB (hierarchical token bucket)
        /// that the child throttles will be governed by</param>
        /// <param name="circuitCode">Circuit code for this connection</param>
        /// <param name="agentID">AgentID for the connected agent</param>
        /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
        /// <param name="defaultRTO">
        /// Default retransmission timeout for unacked packets.  The RTO will never drop
        /// beyond this number.
        /// </param>
        /// <param name="maxRTO">
        /// The maximum retransmission timeout for unacked packets.  The RTO will never exceed this number.
        /// </param>
        public LLUDPClient(
            LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID,
            IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
        {
            AgentID        = agentID;
            RemoteEndPoint = remoteEndPoint;
            CircuitCode    = circuitCode;
            m_udpServer    = server;
            if (defaultRTO != 0)
            {
                m_defaultRTO = defaultRTO;
            }
            if (maxRTO != 0)
            {
                m_maxRTO = maxRTO;
            }

            ProcessUnackedSends = true;

            // Create a token bucket throttle for this client that has the scene token bucket as a parent
            m_throttleClient
                = new AdaptiveTokenBucket(
                      string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name),
                      parentThrottle, 0, rates.Total, rates.MinimumAdaptiveThrottleRate, rates.AdaptiveThrottlesEnabled);

            // Create an array of token buckets for this clients different throttle categories
            m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];

            m_cannibalrate = rates.CannibalizeTextureRate;

            for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
            {
                ThrottleOutPacketType type = (ThrottleOutPacketType)i;

                // Initialize the packet outboxes, where packets sit while they are waiting for tokens
                m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue <OutgoingPacket>();

                // Initialize the token buckets that control the throttling for each category
                m_throttleCategories[i]
                    = new TokenBucket(
                          string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name),
                          m_throttleClient, rates.GetRate(type), 0);
            }

            // Default the retransmission timeout to one second
            RTO = m_defaultRTO;

            // Initialize this to a sane value to prevent early disconnects
            TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;

            // Initialize the stopwatch for the first set of updates, afterwards
            // the SendPacketStats method will be responsible
            m_statsUpdateStopwatch.Start();
        }
 public UDPprioQueue(int NumberOfLevels, int PromRateMask)
 {
     // PromRatemask:  0x03 promotes on each 4 calls, 0x1 on each 2 calls etc
     nlevels = NumberOfLevels;
     queues = new OpenSim.Framework.LocklessQueue<object>[nlevels];
     promotioncntr = new int[nlevels];
     for (int i = 0; i < nlevels; i++)
     {
         queues[i] = new OpenSim.Framework.LocklessQueue<object>();
         promotioncntr[i] = 0;
     }
     promotionratemask = PromRateMask;
 }
Exemple #5
0
 public UDPprioQueue(int NumberOfLevels,int PromRateMask)
     {
     // PromRatemask:  0x03 promotes on each 4 calls, 0x1 on each 2 calls etc
     nlevels = NumberOfLevels;
     queues = new OpenSim.Framework.LocklessQueue<object>[nlevels];
     promotioncntr = new int[nlevels];
     for (int i = 0; i < nlevels; i++)
         {
         queues[i] = new OpenSim.Framework.LocklessQueue<object>();
         promotioncntr[i] = 0;
         }
     promotionratemask = PromRateMask;
     }
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="server">Reference to the UDP server this client is connected to</param>
        /// <param name="rates">Default throttling rates and maximum throttle limits</param>
        /// <param name="parentThrottle">Parent HTB (hierarchical token bucket)
        /// that the child throttles will be governed by</param>
        /// <param name="circuitCode">Circuit code for this connection</param>
        /// <param name="agentID">AgentID for the connected agent</param>
        /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
        /// <param name="defaultRTO">
        /// Default retransmission timeout for unacked packets.  The RTO will never drop
        /// beyond this number.
        /// </param>
        /// <param name="maxRTO">
        /// The maximum retransmission timeout for unacked packets.  The RTO will never exceed this number.
        /// </param>
        public LLUDPClient(
            LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID,
            IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
        {
            AgentID        = agentID;
            RemoteEndPoint = remoteEndPoint;
            CircuitCode    = circuitCode;
            m_udpServer    = server;
            if (defaultRTO != 0)
            {
                m_defaultRTO = defaultRTO;
            }
            if (maxRTO != 0)
            {
                m_maxRTO = maxRTO;
            }

            // Create a token bucket throttle for this client that has the scene token bucket as a parent
            m_throttleClient = new AdaptiveTokenBucket(parentThrottle, rates.Total, rates.AdaptiveThrottlesEnabled);
            // Create a token bucket throttle for the total categary with the client bucket as a throttle
            m_throttleCategory = new TokenBucket(m_throttleClient, 0);
            // Create an array of token buckets for this clients different throttle categories
            m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];

            m_cannibalrate = rates.CannibalizeTextureRate;

            for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
            {
                ThrottleOutPacketType type = (ThrottleOutPacketType)i;

                // Initialize the packet outboxes, where packets sit while they are waiting for tokens
                m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue <OutgoingPacket>();
                // Initialize the token buckets that control the throttling for each category
                m_throttleCategories[i] = new TokenBucket(m_throttleCategory, rates.GetRate(type));
            }

            // Default the retransmission timeout to one second
            RTO = m_defaultRTO;

            // Initialize this to a sane value to prevent early disconnects
            TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
        }
Exemple #7
0
        /// <summary>
        /// Queue an outgoing packet if appropriate.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="forceQueue">Always queue the packet if at all possible.</param>
        /// <returns>
        /// true if the packet has been queued,
        /// false if the packet has not been queued and should be sent immediately.
        /// </returns>
        public bool EnqueueOutgoing(OutgoingPacket packet, bool forceQueue)
        {
            int category = (int)packet.Category;

            if (category >= 0 && category < m_packetOutboxes.Length)
            {
                OpenSim.Framework.LocklessQueue <OutgoingPacket> queue = m_packetOutboxes[category];
                TokenBucket bucket = m_throttleCategories[category];

                // Don't send this packet if there is already a packet waiting in the queue
                // even if we have the tokens to send it, tokens should go to the already
                // queued packets
                if (queue.Count > 0)
                {
                    queue.Enqueue(packet);
                    return(true);
                }


                if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength))
                {
                    // Enough tokens were removed from the bucket, the packet will not be queued
                    return(false);
                }
                else
                {
                    // Force queue specified or not enough tokens in the bucket, queue this packet
                    queue.Enqueue(packet);
                    return(true);
                }
            }
            else
            {
                // We don't have a token bucket for this category, so it will not be queued
                return(false);
            }
        }
Exemple #8
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="server">Reference to the UDP server this client is connected to</param>
        /// <param name="rates">Default throttling rates and maximum throttle limits</param>
        /// <param name="parentThrottle">Parent HTB (hierarchical token bucket)
        /// that the child throttles will be governed by</param>
        /// <param name="circuitCode">Circuit code for this connection</param>
        /// <param name="agentID">AgentID for the connected agent</param>
        /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
        public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
        {
            AgentID = agentID;
            RemoteEndPoint = remoteEndPoint;
            CircuitCode = circuitCode;
            m_udpServer = server;
            if (defaultRTO != 0)
                m_defaultRTO = defaultRTO;
            if (maxRTO != 0)
                m_maxRTO = maxRTO;

            // Create a token bucket throttle for this client that has the scene token bucket as a parent
            m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total);
            // Create an array of token buckets for this clients different throttle categories
            m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];

            for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
            {
                ThrottleOutPacketType type = (ThrottleOutPacketType)i;

                // Initialize the packet outboxes, where packets sit while they are waiting for tokens
                m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
                // Initialize the token buckets that control the throttling for each category
                m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type));
            }

            // Default the retransmission timeout to three seconds
            RTO = m_defaultRTO;

            // Initialize this to a sane value to prevent early disconnects
            TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;

            NeedAcks = new UnackedPacketCollection(server.ByteBufferPool);
        }
Exemple #9
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="server">Reference to the UDP server this client is connected to</param>
        /// <param name="rates">Default throttling rates and maximum throttle limits</param>
        /// <param name="parentThrottle">Parent HTB (hierarchical token bucket)
        /// that the child throttles will be governed by</param>
        /// <param name="circuitCode">Circuit code for this connection</param>
        /// <param name="agentID">AgentID for the connected agent</param>
        /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
        /// <param name="defaultRTO">
        /// Default retransmission timeout for unacked packets.  The RTO will never drop
        /// beyond this number.
        /// </param>
        /// <param name="maxRTO">
        /// The maximum retransmission timeout for unacked packets.  The RTO will never exceed this number.
        /// </param>
        public LLUDPClient(
            LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID,
            IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
        {
            AgentID = agentID;
            RemoteEndPoint = remoteEndPoint;
            CircuitCode = circuitCode;
            m_udpServer = server;
            if (defaultRTO != 0)
                m_defaultRTO = defaultRTO;
            if (maxRTO != 0)
                m_maxRTO = maxRTO;

            ProcessUnackedSends = true;

            // Create a token bucket throttle for this client that has the scene token bucket as a parent
            m_throttleClient 
                = new AdaptiveTokenBucket(
                    string.Format("adaptive throttle for {0} in {1}", AgentID, server.Scene.Name), 
                    parentThrottle, 0, rates.Total, rates.MinimumAdaptiveThrottleRate, rates.AdaptiveThrottlesEnabled);

            // Create an array of token buckets for this clients different throttle categories
            m_throttleCategories = new TokenBucket[THROTTLE_CATEGORY_COUNT];

            m_cannibalrate = rates.CannibalizeTextureRate;
            
            for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
            {
                ThrottleOutPacketType type = (ThrottleOutPacketType)i;

                // Initialize the packet outboxes, where packets sit while they are waiting for tokens
                m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();

                // Initialize the token buckets that control the throttling for each category
                m_throttleCategories[i]
                    = new TokenBucket(
                        string.Format("{0} throttle for {1} in {2}", type, AgentID, server.Scene.Name), 
                    m_throttleClient, rates.GetRate(type), 0);
            }

            // Default the retransmission timeout to one second
            RTO = m_defaultRTO;

            // Initialize this to a sane value to prevent early disconnects
            TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
            
            // Initialize the stopwatch for the first set of updates, afterwards
            // the SendPacketStats method will be responsible
            m_statsUpdateStopwatch.Start();
        }
Exemple #10
0
        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="server">Reference to the UDP server this client is connected to</param>
        /// <param name="rates">Default throttling rates and maximum throttle limits</param>
        /// <param name="parentThrottle">Parent HTB (hierarchical token bucket)
        /// that the child throttles will be governed by</param>
        /// <param name="circuitCode">Circuit code for this connection</param>
        /// <param name="agentID">AgentID for the connected agent</param>
        /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
        public LLUDPClient(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle, uint circuitCode, UUID agentID, IPEndPoint remoteEndPoint, int defaultRTO, int maxRTO)
        {
            AgentID = agentID;
            RemoteEndPoint = remoteEndPoint;
            CircuitCode = circuitCode;
            m_udpServer = server;
            if (defaultRTO != 0)
                m_defaultRTO = defaultRTO;
            if (maxRTO != 0)
                m_maxRTO = maxRTO;

            // Create a token bucket throttle for this client that has the scene token bucket as a parent
            m_throttle = new TokenBucket(parentThrottle, rates.TotalLimit, rates.Total);
            // Create an array of token buckets for this clients different throttle categories
            m_throttleCategories = new TokenBucket[(int)ThrottleOutPacketType.Count];

            for (int i = 0; i < (int)ThrottleOutPacketType.Count; i++)
            {
                ThrottleOutPacketType type = (ThrottleOutPacketType)i;

                // Initialize the packet outboxes, where packets sit while they are waiting for tokens
                m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>();
                // Initialize the token buckets that control the throttling for each category
                m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type));
            }

            TotalRateRequested = STARTPERCLIENTRATE;
            TotalRateMin = MINPERCLIENTRATE;

            m_throttle.MaxBurst = STARTPERCLIENTRATE;
            m_throttle.DripRate = STARTPERCLIENTRATE;

            MapCatsToPriority[(int)ThrottleOutPacketType.Resend] = 2;
            MapCatsToPriority[(int)ThrottleOutPacketType.Land] = 1;
            MapCatsToPriority[(int)ThrottleOutPacketType.Wind] = 0;
            MapCatsToPriority[(int)ThrottleOutPacketType.Cloud] = 0;
            MapCatsToPriority[(int)ThrottleOutPacketType.Task] = 4;
            MapCatsToPriority[(int)ThrottleOutPacketType.Texture] = 2;
            MapCatsToPriority[(int)ThrottleOutPacketType.Asset] = 3;
            MapCatsToPriority[(int)ThrottleOutPacketType.State] = 5;
            MapCatsToPriority[(int)ThrottleOutPacketType.AvatarInfo] = 6;
            MapCatsToPriority[(int)ThrottleOutPacketType.OutBand] = 7;

//            m_lastthrottleCategoryChecked = 0;

            // Default the retransmission timeout to three seconds
            RTO = m_defaultRTO;

            // Initialize this to a sane value to prevent early disconnects
            TickLastPacketReceived = Environment.TickCount & Int32.MaxValue;
        }
Exemple #11
0
        public bool EnqueueOutgoing(OutgoingPacket packet)
        {
            int category = (int)packet.Category;

            if (category >= 0 && category < m_packetOutboxes.Length)
            {
                OpenSim.Framework.LocklessQueue <OutgoingPacket> queue = m_packetOutboxes[category];

                // Not enough tokens in the bucket, queue this packet

                //check the queue
                //Dont drop resends this can mess up the buffer pool as well as make the connection situation much worse
                if (_currentOutboundQueueSize > MAX_TOTAL_QUEUE_SIZE && (packet.Buffer[0] & Helpers.MSG_RESENT) == 0)
                {
                    //queue already has too much data in it..
                    //can we drop this packet?
                    byte flags      = packet.Buffer[0];
                    bool isReliable = (flags & Helpers.MSG_RELIABLE) != 0;

                    if (!isReliable &&
                        packet.Type != PacketType.PacketAck &&
                        packet.Type != PacketType.CompletePingCheck)
                    {
                        //packet is unreliable and will be dropped
                        this.TestReportPacketDrop(packet);
                        packet.DecRef(m_udpServer.ByteBufferPool);
                    }
                    else
                    {
                        if (_currentOutboundQueueSize < MAX_TOTAL_QUEUE_SIZE * 1.5)
                        {
                            this.TestReportPacketShouldDrop(packet);
                            Interlocked.Add(ref _currentOutboundQueueSize, packet.DataSize);
                            packet.AddRef();
                            queue.Enqueue(packet);
                        }
                        else
                        {
                            //this connection is in a pretty critical state and probably will never catch up.
                            //drop all packets until we start to catch up. This includes acks which will disconnect
                            //the client eventually anyways

                            this.TestReportCriticalPacketDrop(packet);
                            packet.DecRef(m_udpServer.ByteBufferPool);
                        }
                    }
                }
                else
                {
                    Interlocked.Add(ref _currentOutboundQueueSize, packet.DataSize);

                    packet.AddRef();
                    queue.Enqueue(packet);
                }

                return(true);
            }
            else
            {
                // We don't have a token bucket for this category, so it will not be queued
                return(false);
            }
        }