/// <summary>
 ///     Default constructor
 /// </summary>
 /// <param name="parent">
 ///     Parent bucket if this is a child bucket, or
 ///     null if this is a root bucket
 /// </param>
 /// <param name="maxBurst">
 ///     Maximum size of the bucket in bytes, or
 ///     zero if this bucket has no maximum capacity
 /// </param>
 /// <param name="dripRate">
 ///     Rate that the bucket fills, in bytes per
 ///     second. If zero, the bucket always remains full
 /// </param>
 public TokenBucket(TokenBucket parent, int maxBurst, int dripRate)
 {
     this.parent = parent;
     MaxBurst    = maxBurst;
     DripRate    = dripRate;
     lastDrip    = Environment.TickCount & Int32.MaxValue;
 }
Example #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>
        /// <param name="defaultRTO"></param>
        /// <param name="maxRTO"></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, 0);

            // remember the rates the client requested
            Rates = new int[(int)ThrottleOutPacketType.Count];

            for (int i = 0; i < (int)ThrottleOutPacketType.Count; i++)
            {
                PacketsCounts[i] = 0;
            }

            //Set the priorities for the different packet types
            //Higher is more important
            MapCatsToPriority[(int)ThrottleOutPacketType.Resend]     = 7;
            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;

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

            // Initialize this to a sane value to prevent early disconnects
            TickLastPacketReceived = Environment.TickCount & int.MaxValue;
        }
Example #3
0
        public void SetThrottles(byte[] throttleData)
        {
            byte[] adjData;
            int    pos = 0;

            if (!BitConverter.IsLittleEndian)
            {
                byte[] newData = new byte[7 * 4];
                Buffer.BlockCopy(throttleData, 0, newData, 0, 7 * 4);

                for (int i = 0; i < 7; i++)
                {
                    Array.Reverse(newData, i * 4, 4);
                }

                adjData = newData;
            }
            else
            {
                adjData = throttleData;
            }

            // 0.125f converts from bits to bytes
            int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);

            pos += 4;
            int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);

            pos += 4;
            int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);

            pos += 4;
            int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);

            pos += 4;
            int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);

            pos += 4;
            int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);

            pos += 4;
            int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);

            int total = resend + land + wind + cloud + task + texture + asset;

            // These are subcategories of task that we allocate a percentage to
            int state = (int)(task * STATE_TASK_PERCENTAGE);

            task -= state;

            int transfer = (int)(asset * TRANSFER_ASSET_PERCENTAGE);

            asset -= transfer;

            // avatar info comes out from state
            int avatarinfo = (int)(state * AVATAR_INFO_STATE_PERCENTAGE);

            state -= avatarinfo;

//            int total = resend + land + wind + cloud + task + texture + asset + state + avatarinfo;

            // Make sure none of the throttles are set below our packet MTU,
            // otherwise a throttle could become permanently clogged


            Rates[(int)ThrottleOutPacketType.Resend]  = resend;
            Rates[(int)ThrottleOutPacketType.Land]    = land;
            Rates[(int)ThrottleOutPacketType.Wind]    = wind;
            Rates[(int)ThrottleOutPacketType.Cloud]   = cloud;
            Rates[(int)ThrottleOutPacketType.Task]    = task + state + avatarinfo;
            Rates[(int)ThrottleOutPacketType.Texture] = texture;
            Rates[(int)ThrottleOutPacketType.Asset]   = asset + transfer;
            Rates[(int)ThrottleOutPacketType.State]   = state;

            TotalRateRequested = total;
            TotalRateMin       = (int)(total * 0.1);
            if (TotalRateMin < MINPERCLIENTRATE)
            {
                TotalRateMin = MINPERCLIENTRATE;
            }
            total = TotalRateMin; // let it grow slowly


            //MainConsole.Instance.WarnFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, State={8}, AvatarInfo={9}, Transfer={10}, TaskFull={11}, Total={12}",
            //    AgentID, resend, land, wind, cloud, task, texture, asset, state, avatarinfo, transfer, task + state + avatarinfo, total);

            // Update the token buckets with new throttle values

            TokenBucket bucket = m_throttle;

            bucket.DripRate = total;
            bucket.MaxBurst = total;
            // Reset the packed throttles cached data
            m_packedThrottles = null;
        }
 /// <summary>
 ///     Default constructor
 /// </summary>
 /// <param name="parent">
 ///     Parent bucket if this is a child bucket, or
 ///     null if this is a root bucket
 /// </param>
 /// <param name="maxBurst">
 ///     Maximum size of the bucket in bytes, or
 ///     zero if this bucket has no maximum capacity
 /// </param>
 /// <param name="dripRate">
 ///     Rate that the bucket fills, in bytes per
 ///     second. If zero, the bucket always remains full
 /// </param>
 public TokenBucket(TokenBucket parent, int maxBurst, int dripRate)
 {
     this.parent = parent;
     MaxBurst = maxBurst;
     DripRate = dripRate;
     lastDrip = Environment.TickCount & Int32.MaxValue;
 }