示例#1
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="agent">Reference to the client this packet is destined for</param>
 /// <param name="buffer">Serialized packet data. If the flags or sequence number
 /// need to be updated, they will be injected directly into this binary buffer</param>
 /// <param name="category">Throttling category for this packet</param>
 /// <param name="type">Packet type</param>
 public OutgoingPacket(LLAgent agent, UDPPacketBuffer buffer, ThrottleCategory category, PacketType type)
 {
     Agent    = agent;
     Buffer   = buffer;
     Category = category;
     Type     = type;
 }
示例#2
0
        /// <summary>
        /// Converts a <seealso cref="ThrottleCategory"/> integer to a
        /// flag value
        /// </summary>
        /// <param name="i">Throttle category to convert</param>
        /// <returns>Flag representation of the throttle category</returns>
        private static ThrottleCategoryFlags CategoryToFlag(int i)
        {
            ThrottleCategory category = (ThrottleCategory)i;

            switch (category)
            {
            case ThrottleCategory.Land:
                return(ThrottleCategoryFlags.Land);

            case ThrottleCategory.Wind:
                return(ThrottleCategoryFlags.Wind);

            case ThrottleCategory.Cloud:
                return(ThrottleCategoryFlags.Cloud);

            case ThrottleCategory.Task:
                return(ThrottleCategoryFlags.Task);

            case ThrottleCategory.Texture:
                return(ThrottleCategoryFlags.Texture);

            case ThrottleCategory.Asset:
                return(ThrottleCategoryFlags.Asset);

            default:
                return(0);
            }
        }
示例#3
0
        public void BroadcastMessage(OSD message, ThrottleCategory category)
        {
            byte[] messageData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(message));
            byte[] data        = BuildMessageBuffer_00(messageData, true);

            m_clients.ForEach(delegate(WSAgent agent) { SendMessageData(agent, data, category); });
        }
示例#4
0
        /// <summary>
        /// Default constructor
        /// </summary>
        public WSAgent(WebSockets server, TokenBucket parentThrottle, ThrottleRates rates,
                       UUID agentID, UUID sessionID, Socket socket, bool isChildAgent)
        {
            m_id           = agentID;
            m_server       = server;
            m_interestList = new InterestList(this, 200);

            IsChildPresence = isChildAgent;

            m_localID = m_server.Scene.CreateLocalID();

            //TextureEntry = new Primitive.TextureEntry(DEFAULT_AVATAR_TEXTURE);

            SessionID = sessionID;
            Socket    = socket;

            // Create a token bucket throttle for this client that has the scene token bucket as a parent
            m_throttle = new TokenBucket(parentThrottle, rates.ClientTotalLimit, rates.ClientTotal);
            // 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++)
            {
                ThrottleCategory type = (ThrottleCategory)i;

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

            // Initialize this to a sane value to prevent early disconnects
            TickLastMessageReceived = Util.TickCount();
        }
示例#5
0
        public void SendMessage(WSAgent agent, OSD message, ThrottleCategory category)
        {
            byte[] messageData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(message));
            byte[] data        = BuildMessageBuffer_00(messageData, true);

            SendMessageData(agent, data, category);
        }
示例#6
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="agent">Reference to the client this packet is destined for</param>
 /// <param name="buffer">Serialized packet data. If the flags or sequence number
 /// need to be updated, they will be injected directly into this binary buffer</param>
 /// <param name="category">Throttling category for this packet</param>
 /// <param name="type">Packet type</param>
 public OutgoingPacket(LLAgent agent, UDPPacketBuffer buffer, ThrottleCategory category, PacketType type)
 {
     Agent = agent;
     Buffer = buffer;
     Category = category;
     Type = type;
 }
示例#7
0
        public void BroadcastPacket(Packet packet, ThrottleCategory category, bool sendToPausedAgents, bool allowSplitting)
        {
            // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
            if ((packet.Type == PacketType.CoarseLocationUpdate || packet.Type == PacketType.AvatarGroupsReply) && allowSplitting)
            {
                allowSplitting = false;
            }

            if (allowSplitting && packet.HasVariableBlocks)
            {
                byte[][] datas       = packet.ToBytesMultiple();
                int      packetCount = datas.Length;

                if (packetCount < 1)
                {
                    m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);
                }

                for (int i = 0; i < packetCount; i++)
                {
                    byte[] data = datas[i];
                    m_clients.ForEach(delegate(LLAgent agent) { SendPacketData(agent, data, packet.Type, category); });
                }
            }
            else
            {
                byte[] data = packet.ToBytes();
                m_clients.ForEach(delegate(LLAgent agent) { SendPacketData(agent, data, packet.Type, category); });
            }
        }
示例#8
0
        public int GetLimit(ThrottleCategory type)
        {
            switch (type)
            {
            case ThrottleCategory.Resend:
                return(ResendLimit);

            case ThrottleCategory.Land:
                return(LandLimit);

            case ThrottleCategory.Wind:
                return(WindLimit);

            case ThrottleCategory.Cloud:
                return(CloudLimit);

            case ThrottleCategory.Task:
                return(TaskLimit);

            case ThrottleCategory.Texture:
                return(TextureLimit);

            case ThrottleCategory.Asset:
                return(AssetLimit);

            case ThrottleCategory.Unknown:
            default:
                return(0);
            }
        }
示例#9
0
        public void SendPacket(LLAgent agent, Packet packet, ThrottleCategory category, bool allowSplitting)
        {
            // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
            if ((packet.Type == PacketType.CoarseLocationUpdate || packet.Type == PacketType.AvatarGroupsReply) && allowSplitting)
            {
                allowSplitting = false;
            }

            try
            {
                if (allowSplitting && packet.HasVariableBlocks)
                {
                    byte[][] datas       = packet.ToBytesMultiple();
                    int      packetCount = datas.Length;

                    if (packetCount < 1)
                    {
                        m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);
                    }

                    for (int i = 0; i < packetCount; i++)
                    {
                        byte[] data = datas[i];
                        SendPacketData(agent, data, packet.Type, category);
                    }
                }
                else
                {
                    byte[] data = packet.ToBytes();
                    SendPacketData(agent, data, packet.Type, category);
                }
            }
            catch (NullReferenceException)
            {
                System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(1, true);
                m_log.Error("An invalid " + packet.Type + " packet was built in:" + Environment.NewLine + trace.ToString());
            }
        }
示例#10
0
        public void BroadcastPacket(Packet packet, ThrottleCategory category, bool sendToPausedAgents, bool allowSplitting)
        {
            // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
            if ((packet.Type == PacketType.CoarseLocationUpdate || packet.Type == PacketType.AvatarGroupsReply) && allowSplitting)
                allowSplitting = false;

            if (allowSplitting && packet.HasVariableBlocks)
            {
                byte[][] datas = packet.ToBytesMultiple();
                int packetCount = datas.Length;

                if (packetCount < 1)
                    m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);

                for (int i = 0; i < packetCount; i++)
                {
                    byte[] data = datas[i];
                    m_clients.ForEach(delegate(LLAgent agent) { SendPacketData(agent, data, packet.Type, category); });
                }
            }
            else
            {
                byte[] data = packet.ToBytes();
                m_clients.ForEach(delegate(LLAgent agent) { SendPacketData(agent, data, packet.Type, category); });
            }
        }
示例#11
0
 public void SendPacketData(LLAgent agent, byte[] data, PacketType type, ThrottleCategory category)
 {
     m_udpServer.SendPacketData(agent, data, type, category);
 }
示例#12
0
 public void SendPacket(LLAgent agent, Packet packet, ThrottleCategory category, bool allowSplitting)
 {
     m_udpServer.SendPacket(agent, packet, category, allowSplitting);
 }
示例#13
0
 public void BroadcastPacket(Packet packet, ThrottleCategory category, bool sendToPausedAgents, bool allowSplitting)
 {
     m_udpServer.BroadcastPacket(packet, category, sendToPausedAgents, allowSplitting);
 }
示例#14
0
 public void SendMessage(WSAgent agent, OSDMap message, ThrottleCategory category)
 {
     Server.SendMessage(agent, message, category);
 }
示例#15
0
 public void SendPacketData(LLAgent agent, byte[] data, PacketType type, ThrottleCategory category)
 {
     m_udpServer.SendPacketData(agent, data, type, category);
 }
示例#16
0
        public void SendMessage(WSAgent agent, OSDMap message, ThrottleCategory category)
        {
            byte[] messageData = Encoding.UTF8.GetBytes(OSDParser.SerializeJsonString(message));
            byte[] data = new byte[messageData.Length + 2];

            // Start with 0x00
            data[0] = 0x00;
            // Then the string
            Buffer.BlockCopy(messageData, 0, data, 1, messageData.Length);
            // End with 0xFF
            data[data.Length - 1] = 0xFF;

            SendMessageData(agent, data, category);
        }
示例#17
0
        public void SendPacketData(LLAgent agent, byte[] data, PacketType type, ThrottleCategory category)
        {
            int  dataLength = data.Length;
            bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
            bool doCopy     = true;

            // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum.
            // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
            // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
            // to accomodate for both common scenarios and provide ample room for ACK appending in both
            int bufferSize = (dataLength > 180)
                ? LLUDPServer.MTU
                : 200;

            UDPPacketBuffer buffer = new UDPPacketBuffer(agent.RemoteEndPoint, bufferSize);

            // Zerocode if needed
            if (doZerocode)
            {
                try
                {
                    dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data);
                    doCopy     = false;
                }
                catch (IndexOutOfRangeException)
                {
                    // The packet grew larger than the bufferSize while zerocoding.
                    // Remove the MSG_ZEROCODED flag and send the unencoded data
                    // instead
                    m_log.Debug("Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength +
                                " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag");
                    data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED);
                }
            }

            // If the packet data wasn't already copied during zerocoding, copy it now
            if (doCopy)
            {
                if (dataLength > buffer.Data.Length)
                {
                    m_log.Error("Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
                                type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length);
                    buffer.Data = new byte[dataLength];
                }

                Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
            }

            buffer.DataLength = dataLength;

            #region Queue or Send

            OutgoingPacket outgoingPacket = new OutgoingPacket(agent, buffer, category, type);

            if (!agent.EnqueueOutgoing(outgoingPacket))
            {
                SendPacketFinal(outgoingPacket);
            }

            #endregion Queue or Send
        }
示例#18
0
 public void BroadcastPacket(Packet packet, ThrottleCategory category, bool sendToPausedAgents, bool allowSplitting)
 {
     m_udpServer.BroadcastPacket(packet, category, sendToPausedAgents, allowSplitting);
 }
示例#19
0
        public void SendPacket(LLAgent agent, Packet packet, ThrottleCategory category, bool allowSplitting)
        {
            // CoarseLocationUpdate and AvatarGroupsReply packets cannot be split in an automated way
            if ((packet.Type == PacketType.CoarseLocationUpdate || packet.Type == PacketType.AvatarGroupsReply) && allowSplitting)
                allowSplitting = false;

            try
            {
                if (allowSplitting && packet.HasVariableBlocks)
                {
                    byte[][] datas = packet.ToBytesMultiple();
                    int packetCount = datas.Length;

                    if (packetCount < 1)
                        m_log.Error("[LLUDPSERVER]: Failed to split " + packet.Type + " with estimated length " + packet.Length);

                    for (int i = 0; i < packetCount; i++)
                    {
                        byte[] data = datas[i];
                        SendPacketData(agent, data, packet.Type, category);
                    }
                }
                else
                {
                    byte[] data = packet.ToBytes();
                    SendPacketData(agent, data, packet.Type, category);
                }
            }
            catch (NullReferenceException)
            {
                System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace(1, true);
                m_log.Error("An invalid " + packet.Type + " packet was built in:" + Environment.NewLine + trace.ToString());
            }
        }
示例#20
0
 private void SendMessageData(WSAgent agent, byte[] data, ThrottleCategory category)
 {
     // TODO: Throttling
     SendMessageFinal(agent.Socket, data);
 }
示例#21
0
        public void SendPacketData(LLAgent agent, byte[] data, PacketType type, ThrottleCategory category)
        {
            int dataLength = data.Length;
            bool doZerocode = (data[0] & Helpers.MSG_ZEROCODED) != 0;
            bool doCopy = true;

            // Frequency analysis of outgoing packet sizes shows a large clump of packets at each end of the spectrum.
            // The vast majority of packets are less than 200 bytes, although due to asset transfers and packet splitting
            // there are a decent number of packets in the 1000-1140 byte range. We allocate one of two sizes of data here
            // to accomodate for both common scenarios and provide ample room for ACK appending in both
            int bufferSize = (dataLength > 180)
                ? LLUDPServer.MTU
                : 200;

            UDPPacketBuffer buffer = new UDPPacketBuffer(agent.RemoteEndPoint, bufferSize);

            // Zerocode if needed
            if (doZerocode)
            {
                try
                {
                    dataLength = Helpers.ZeroEncode(data, dataLength, buffer.Data);
                    doCopy = false;
                }
                catch (IndexOutOfRangeException)
                {
                    // The packet grew larger than the bufferSize while zerocoding.
                    // Remove the MSG_ZEROCODED flag and send the unencoded data
                    // instead
                    m_log.Debug("Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength +
                        " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag");
                    data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED);
                }
            }

            // If the packet data wasn't already copied during zerocoding, copy it now
            if (doCopy)
            {
                if (dataLength > buffer.Data.Length)
                {
                    m_log.Error("Packet exceeded buffer size! This could be an indication of packet assembly not obeying the MTU. Type=" +
                        type + ", DataLength=" + dataLength + ", BufferLength=" + buffer.Data.Length);
                    buffer.Data = new byte[dataLength];
                }

                Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength);
            }

            buffer.DataLength = dataLength;

            #region Queue or Send

            OutgoingPacket outgoingPacket = new OutgoingPacket(agent, buffer, category, type);

            if (!agent.EnqueueOutgoing(outgoingPacket))
                SendPacketFinal(outgoingPacket);

            #endregion Queue or Send
        }
示例#22
0
 public void SendMessage(WSAgent agent, OSDMap message, ThrottleCategory category)
 {
     Server.SendMessage(agent, message, category);
 }
示例#23
0
 private void SendMessageData(WSAgent agent, byte[] data, ThrottleCategory category)
 {
     // TODO: Throttling
     SendMessageFinal(agent.Socket, data);
 }
示例#24
0
 public void SendPacket(LLAgent agent, Packet packet, ThrottleCategory category, bool allowSplitting)
 {
     m_udpServer.SendPacket(agent, packet, category, allowSplitting);
 }
示例#25
0
 public int GetRate(ThrottleCategory type)
 {
     switch (type)
     {
         case ThrottleCategory.Resend:
             return Resend;
         case ThrottleCategory.Land:
             return Land;
         case ThrottleCategory.Wind:
             return Wind;
         case ThrottleCategory.Cloud:
             return Cloud;
         case ThrottleCategory.Task:
             return Task;
         case ThrottleCategory.Texture:
             return Texture;
         case ThrottleCategory.Asset:
             return Asset;
         case ThrottleCategory.Unknown:
         default:
             return 0;
     }
 }
示例#26
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="data">Serialized message to send</param>
 /// <param name="category">Throttling category for this packet</param>
 public OutgoingMessage(string data, ThrottleCategory category)
 {
     Data     = data;
     Category = category;
 }
示例#27
0
 public void BroadcastMessage(OSDMap message, ThrottleCategory category)
 {
     Server.BroadcastMessage(message, category);
 }
示例#28
0
 public void BroadcastMessage(OSDMap message, ThrottleCategory category)
 {
     Server.BroadcastMessage(message, category);
 }
示例#29
0
 /// <summary>
 /// Default constructor
 /// </summary>
 /// <param name="data">Serialized message to send</param>
 /// <param name="category">Throttling category for this packet</param>
 public OutgoingMessage(string data, ThrottleCategory category)
 {
     Data = data;
     Category = category;
 }
示例#30
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="sessionID">SessionID for the connected agent</param>
        /// <param name="secureSessionID">SecureSessionID for the connected agent</param>
        /// <param name="defaultRTO">Default retransmission timeout, in milliseconds</param>
        /// <param name="maxRTO">Maximum retransmission timeout, in milliseconds</param>
        /// <param name="remoteEndPoint">Remote endpoint for this connection</param>
        /// <param name="isChildAgent">True if this agent is currently simulated by
        /// another simulator, otherwise false</param>
        public LLAgent(LLUDPServer server, ThrottleRates rates, TokenBucket parentThrottle,
                       uint circuitCode, UUID agentID, UUID sessionID, UUID secureSessionID, IPEndPoint remoteEndPoint,
                       int defaultRTO, int maxRTO, bool isChildAgent)
        {
            m_id        = agentID;
            m_udpServer = server;
            m_scene     = m_udpServer.Scene;

            PacketArchive = new IncomingPacketHistoryCollection(200);
            NeedAcks      = new UnackedPacketCollection();
            PendingAcks   = new LocklessQueue <uint>();
            EventQueue    = new LLEventQueue();

            m_nextOnQueueEmpty = 1;
            m_defaultRTO       = 1000 * 3;
            m_maxRTO           = 1000 * 60;

            m_packetOutboxes = new LocklessQueue <OutgoingPacket> [THROTTLE_CATEGORY_COUNT];
            m_nextPackets    = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
            m_interestList   = new InterestList(this, 200);

            IsChildPresence = isChildAgent;

            m_localID = m_scene.CreateLocalID();

            TextureEntry = new Primitive.TextureEntry(DEFAULT_AVATAR_TEXTURE);

            SessionID       = sessionID;
            SecureSessionID = secureSessionID;
            RemoteEndPoint  = remoteEndPoint;
            CircuitCode     = circuitCode;

            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.ClientTotalLimit, rates.ClientTotal);
            // 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++)
            {
                ThrottleCategory type = (ThrottleCategory)i;

                // Initialize the packet outboxes, where packets sit while they are waiting for tokens
                m_packetOutboxes[i] = new 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 = Util.TickCount();

            IsConnected = true;
        }