예제 #1
0
        public void SendAcks(UDPClient client)
        {
            PacketAckPacket acks = null;

            lock (client.PendingAcks)
            {
                int count = client.PendingAcks.Count;

                if (count > 250)
                {
                    Logger.Log("Too many ACKs queued up!", Helpers.LogLevel.Error);
                    return;
                }
                else if (count > 0)
                {
                    acks = new PacketAckPacket();
                    acks.Header.Reliable = false;
                    acks.Packets         = new PacketAckPacket.PacketsBlock[count];

                    for (int i = 0; i < count; i++)
                    {
                        acks.Packets[i]    = new PacketAckPacket.PacketsBlock();
                        acks.Packets[i].ID = client.PendingAcks.Values[i];
                    }

                    client.PendingAcks.Clear();
                }
            }

            if (acks != null)
            {
                SendPacket(client, acks, PacketCategory.Overhead, true);
            }
        }
예제 #2
0
        public void SendAcks(LLUDPClient udpClient)
        {
            uint ack;

            if (udpClient.PendingAcks.Dequeue(out ack))
            {
                List <PacketAckPacket.PacketsBlock> blocks = new List <PacketAckPacket.PacketsBlock>();
                PacketAckPacket.PacketsBlock        block  = new PacketAckPacket.PacketsBlock();
                block.ID = ack;
                blocks.Add(block);

                while (udpClient.PendingAcks.Dequeue(out ack))
                {
                    block    = new PacketAckPacket.PacketsBlock();
                    block.ID = ack;
                    blocks.Add(block);
                }

                PacketAckPacket packet = new PacketAckPacket();
                packet.Header.Reliable = false;
                packet.Packets         = blocks.ToArray();

                SendPacket(udpClient, packet, ThrottleOutPacketType.Unknown, true);
            }
        }
예제 #3
0
        public void SendAcks(LLAgent agent)
        {
            const int MAX_ACKS_PER_PACKET = Byte.MaxValue;

            uint ack;

            if (agent.PendingAcks.TryDequeue(out ack))
            {
                List <PacketAckPacket.PacketsBlock> blocks = new List <PacketAckPacket.PacketsBlock>(agent.PendingAcks.Count);
                PacketAckPacket.PacketsBlock        block  = new PacketAckPacket.PacketsBlock();
                block.ID = ack;
                blocks.Add(block);

                int count = 1;

                while (count < MAX_ACKS_PER_PACKET && agent.PendingAcks.TryDequeue(out ack))
                {
                    block    = new PacketAckPacket.PacketsBlock();
                    block.ID = ack;
                    blocks.Add(block);

                    ++count;
                }

                PacketAckPacket packet = new PacketAckPacket();
                packet.Header.Reliable = false;
                packet.Packets         = blocks.ToArray();

                SendPacket(agent, packet, ThrottleCategory.Unknown, false);
            }
        }
예제 #4
0
        private void SendAcks()
        {
            lock (PendingAcks)
            {
                if (PendingAcks.Count > 0)
                {
                    if (PendingAcks.Count > 250)
                    {
                        // FIXME: Handle the odd case where we have too many pending ACKs queued up
                        OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Too many ACKs queued up!");
                        return;
                    }

                    //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Sending PacketAck");


                    int             i    = 0;
                    PacketAckPacket acks = new PacketAckPacket();
                    acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];

                    foreach (uint ack in PendingAcks.Values)
                    {
                        acks.Packets[i]    = new PacketAckPacket.PacketsBlock();
                        acks.Packets[i].ID = ack;
                        i++;
                    }

                    acks.Header.Reliable = false;
                    OutPacket(acks);

                    PendingAcks.Clear();
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Sends out pending acknowledgements
        /// </summary>
        private void SendAcks()
        {
            lock (PendingAcks)
            {
                if (PendingAcks.Count > 0)
                {
                    if (PendingAcks.Count > 250)
                    {
                        Logger.Log("Too many ACKs queued up!", Helpers.LogLevel.Error, Client);
                        return;
                    }

                    PacketAckPacket acks = new PacketAckPacket();
                    acks.Header.Reliable = false;
                    acks.Packets         = new PacketAckPacket.PacketsBlock[PendingAcks.Count];

                    for (int i = 0; i < PendingAcks.Count; i++)
                    {
                        acks.Packets[i]    = new PacketAckPacket.PacketsBlock();
                        acks.Packets[i].ID = PendingAcks.Values[i];
                    }

                    SendPacket(acks, true);

                    PendingAcks.Clear();
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Sends out pending acknowledgements
        /// </summary>
        /// <returns>Number of ACKs sent</returns>
        private int SendAcks()
        {
            uint ack;
            int  ackCount = 0;

            if (PendingAcks.TryDequeue(out ack))
            {
                List <PacketAckPacket.PacketsBlock> blocks = new List <PacketAckPacket.PacketsBlock>();
                PacketAckPacket.PacketsBlock        block  = new PacketAckPacket.PacketsBlock();
                block.ID = ack;
                blocks.Add(block);

                while (PendingAcks.TryDequeue(out ack))
                {
                    block    = new PacketAckPacket.PacketsBlock();
                    block.ID = ack;
                    blocks.Add(block);
                }

                PacketAckPacket packet = new PacketAckPacket();
                packet.Header.Reliable = false;
                packet.Packets         = blocks.ToArray();

                ackCount = blocks.Count;
                SendPacket(packet);
            }

            return(ackCount);
        }
예제 #7
0
        // Send the pending packet acks to the client
        // Will send blocks of acks for up to 250 packets
        //
        private void SendAcks()
        {
            lock (m_NeedAck)
            {
                if (m_PendingAcks.Count == 0)
                {
                    return;
                }

                PacketAckPacket acks = (PacketAckPacket)PacketPool.Instance.GetPacket(PacketType.PacketAck);

                // The case of equality is more common than one might think,
                // because this function will be called unconditionally when
                // the counter reaches 250. So there is a good chance another
                // packet with 250 blocks exists.
                //
                if (acks.Packets == null ||
                    acks.Packets.Length != m_PendingAcks.Count)
                {
                    acks.Packets = new PacketAckPacket.PacketsBlock[m_PendingAcks.Count];
                }
                int i = 0;
                foreach (uint ack in new List <uint>(m_PendingAcks.Keys))
                {
                    acks.Packets[i]    = new PacketAckPacket.PacketsBlock();
                    acks.Packets[i].ID = ack;

                    m_PendingAcks.Remove(ack);
                    i++;
                }

                acks.Header.Reliable = false;
                OutPacket(acks, ThrottleOutPacketType.Unknown);
            }
        }
예제 #8
0
        public void InPacket(Packet packet)
        {
            if (packet == null)
            {
                return;
            }

            // When too many acks are needed to be sent, the client sends
            // a packet consisting of acks only
            //
            if (packet.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
                {
                    ProcessAck(block.ID);
                }

                PacketPool.Instance.ReturnPacket(packet);
                return;
            }

            // Any packet can have some packet acks in the header.
            // Process them here
            //
            if (packet.Header.AppendedAcks)
            {
                foreach (uint id in packet.Header.AckList)
                {
                    ProcessAck(id);
                }
            }

            // If this client is on another partial instance, no need
            // to handle packets
            //
            if (!m_Client.IsActive && packet.Type != PacketType.LogoutRequest)
            {
                PacketPool.Instance.ReturnPacket(packet);
                return;
            }

            if (packet.Type == PacketType.StartPingCheck)
            {
                StartPingCheckPacket    startPing = (StartPingCheckPacket)packet;
                CompletePingCheckPacket endPing
                    = (CompletePingCheckPacket)PacketPool.Instance.GetPacket(PacketType.CompletePingCheck);

                endPing.PingID.PingID = startPing.PingID.PingID;
                OutPacket(endPing, ThrottleOutPacketType.Task);
            }
            else
            {
                LLQueItem item = new LLQueItem();
                item.Packet   = packet;
                item.Incoming = true;
                m_PacketQueue.Enqueue(item);
            }
        }
예제 #9
0
        /// <summary>
        /// Sends out pending acknowledgements
        /// </summary>
        private void SendAcks(NetworkInfo User_info)
        {
            lock (User_info.PendingAcks)
            {
                if (connected && User_info.PendingAcks.Count > 0)
                {
                    if (User_info.PendingAcks.Count > 250)
                    {
                        // FIXME: Handle the odd case where we have too many pending ACKs queued up
                        //Client.Log("Too many ACKs queued up!", Helpers.LogLevel.Error);
                        return;
                    }

                    int             i    = 0;
                    PacketAckPacket acks = new PacketAckPacket();
                    acks.Packets = new PacketAckPacket.PacketsBlock[User_info.PendingAcks.Count];

                    foreach (uint ack in User_info.PendingAcks.Values)
                    {
                        acks.Packets[i]    = new PacketAckPacket.PacketsBlock();
                        acks.Packets[i].ID = ack;
                        i++;
                    }

                    acks.Header.Reliable = false;
                    SendPacket(acks, true, User_info);

                    User_info.PendingAcks.Clear();
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Return a packet to the packet pool
        /// </summary>
        /// <param name="packet"></param>
        public void ReturnPacket(Packet packet)
        {
            if (!RecyclePackets)
            {
                return;
            }

            bool       trypool = false;
            PacketType type    = packet.Type;

            switch (type)
            {
            case PacketType.ObjectUpdate:
                ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
                oup.ObjectData = null;
                trypool        = true;
                break;

            case PacketType.ImprovedTerseObjectUpdate:
                ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;
                itoup.ObjectData = null;
                trypool          = true;
                break;

            case PacketType.PacketAck:
                PacketAckPacket ackup = (PacketAckPacket)packet;
                ackup.Packets = null;
                trypool       = true;
                break;

            case PacketType.AgentUpdate:
                trypool = true;
                break;

            default:
                return;
            }

            if (!trypool)
            {
                return;
            }

            lock (pool)
            {
                if (!pool.ContainsKey(type))
                {
                    pool[type] = new Stack <Packet>();
                }

                if ((pool[type]).Count < 50)
                {
//                  m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);
                    pool[type].Push(packet);
                }
            }
        }
        public void TestAddClient()
        {
            TestHelpers.InMethod();
            //            TestHelpers.EnableLogging();

            AddUdpServer();

            UUID       myAgentUuid   = TestHelpers.ParseTail(0x1);
            UUID       mySessionUuid = TestHelpers.ParseTail(0x2);
            uint       myCircuitCode = 123456;
            IPEndPoint testEp        = new IPEndPoint(IPAddress.Loopback, 999);

            UseCircuitCodePacket uccp = new UseCircuitCodePacket();

            UseCircuitCodePacket.CircuitCodeBlock uccpCcBlock
                = new UseCircuitCodePacket.CircuitCodeBlock();
            uccpCcBlock.Code      = myCircuitCode;
            uccpCcBlock.ID        = myAgentUuid;
            uccpCcBlock.SessionID = mySessionUuid;
            uccp.CircuitCode      = uccpCcBlock;

            byte[]          uccpBytes = uccp.ToBytes();
            UDPPacketBuffer upb       = new UDPPacketBuffer(testEp, uccpBytes.Length);

            upb.DataLength = uccpBytes.Length;  // God knows why this isn't set by the constructor.
            Buffer.BlockCopy(uccpBytes, 0, upb.Data, 0, uccpBytes.Length);

            m_udpServer.PacketReceived(upb);

            // Presence shouldn't exist since the circuit manager doesn't know about this circuit for authentication yet
            Assert.That(m_scene.GetScenePresence(myAgentUuid), Is.Null);

            AgentCircuitData acd = new AgentCircuitData();

            acd.AgentID   = myAgentUuid;
            acd.SessionID = mySessionUuid;

            m_scene.AuthenticateHandler.AddNewCircuit(myCircuitCode, acd);

            m_udpServer.PacketReceived(upb);

            // Should succeed now
            ScenePresence sp = m_scene.GetScenePresence(myAgentUuid);

            Assert.That(sp.UUID, Is.EqualTo(myAgentUuid));

            Assert.That(m_udpServer.PacketsSent.Count, Is.EqualTo(1));

            Packet packet = m_udpServer.PacketsSent[0];

            Assert.That(packet, Is.InstanceOf(typeof(PacketAckPacket)));

            PacketAckPacket ackPacket = packet as PacketAckPacket;

            Assert.That(ackPacket.Packets.Length, Is.EqualTo(1));
            Assert.That(ackPacket.Packets[0].ID, Is.EqualTo(0));
        }
예제 #12
0
        void SendAck(UDPClient client, uint ack)
        {
            PacketAckPacket acks = new PacketAckPacket();

            acks.Header.Reliable = false;
            acks.Packets         = new PacketAckPacket.PacketsBlock[1];
            acks.Packets[0]      = new PacketAckPacket.PacketsBlock();
            acks.Packets[0].ID   = ack;

            SendPacket(client, acks, PacketCategory.Overhead, true);
        }
예제 #13
0
        public virtual void InPacket(Packet NewPack)
        {
            // Handle appended ACKs
            if (NewPack.Header.AppendedAcks)
            {
                lock (NeedAck)
                {
                    foreach (uint ack in NewPack.Header.AckList)
                    {
                        NeedAck.Remove(ack);
                    }
                }
            }

            // Handle PacketAck packets
            if (NewPack.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)NewPack;

                lock (NeedAck)
                {
                    foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
                    {
                        NeedAck.Remove(block.ID);
                    }
                }
            }
            else if ((NewPack.Type == PacketType.StartPingCheck))
            {
                //reply to pingcheck
                libsecondlife.Packets.StartPingCheckPacket    startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack;
                libsecondlife.Packets.CompletePingCheckPacket endPing   = new CompletePingCheckPacket();
                endPing.PingID.PingID = startPing.PingID.PingID;
                OutPacket(endPing);
            }
            else
            {
                QueItem item = new QueItem();
                item.Packet   = NewPack;
                item.Incoming = true;
                this.PacketQueue.Enqueue(item);
            }
        }
예제 #14
0
        private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
        {
            PacketAckPacket ack = new PacketAckPacket();

            ack.Header.Reliable = false;
            ack.Packets         = new PacketAckPacket.PacketsBlock[1];
            ack.Packets[0]      = new PacketAckPacket.PacketsBlock();
            ack.Packets[0].ID   = sequenceNumber;

            byte[] packetData = ack.ToBytes();
            int    length     = packetData.Length;

            UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length);

            buffer.DataLength = length;

            Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);

            AsyncBeginSend(buffer);
        }
예제 #15
0
        private void SendACK(uint id)
        {
            try
            {
                PacketAckPacket ack = new PacketAckPacket();
                ack.Packets       = new PacketAckPacket.PacketsBlock[1];
                ack.Packets[0].ID = id;

                ack.Header.Reliable = false;

                // Set the sequence number
                ack.Header.Sequence = ++Sequence;

                Listener.SendTo(ack.ToBytes(), RemoteEndpoint);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
예제 #16
0
        private void ack_pack(Packet Pack)
        {
            if (Pack.Header.Reliable)
            {
                libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
                ack_it.Packets         = new PacketAckPacket.PacketsBlock[1];
                ack_it.Packets[0]      = new PacketAckPacket.PacketsBlock();
                ack_it.Packets[0].ID   = Pack.Header.Sequence;
                ack_it.Header.Reliable = false;

                OutPacket(ack_it);
            }

            /*
             * if (Pack.Header.Reliable)
             * {
             *  lock (PendingAcks)
             *  {
             *      uint sequence = (uint)Pack.Header.Sequence;
             *      if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
             *  }
             * }*/
        }
예제 #17
0
        public void SendAcks(LLUDPClient udpClient)
        {
            uint ack;

            if (udpClient.PendingAcks.Dequeue(out ack))
            {
                List<PacketAckPacket.PacketsBlock> blocks = new List<PacketAckPacket.PacketsBlock>();
                PacketAckPacket.PacketsBlock block = new PacketAckPacket.PacketsBlock();
                block.ID = ack;
                blocks.Add(block);

                while (udpClient.PendingAcks.Dequeue(out ack))
                {
                    block = new PacketAckPacket.PacketsBlock();
                    block.ID = ack;
                    blocks.Add(block);
                }

                PacketAckPacket packet = new PacketAckPacket();
                packet.Header.Reliable = false;
                packet.Packets = blocks.ToArray();

                SendPacket(udpClient, packet, ThrottleOutPacketType.Unknown, true, null);
            }
        }
예제 #18
0
        public virtual void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
        {
            byte[] packetData = ack.ToBytes();
            int length = packetData.Length;

            UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length);
            buffer.DataLength = length;

            Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);

            AsyncBeginSend(buffer);
        }
예제 #19
0
        private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
        {
            PacketAckPacket ack = new PacketAckPacket();
            ack.Header.Reliable = false;
            ack.Packets = new PacketAckPacket.PacketsBlock[1];
            ack.Packets[0] = new PacketAckPacket.PacketsBlock();
            ack.Packets[0].ID = sequenceNumber;

            byte[] packetData = ack.ToBytes();
            int length = packetData.Length;

            UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length);
            buffer.DataLength = length;

            Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);

            //            AsyncBeginSend(buffer);
            SyncSend(buffer);

        }
예제 #20
0
        // SeparateAck: create a standalone PacketAck for packet's appended ACKs
        public Packet SeparateAck(Packet packet)
        {
            PacketAckPacket seperate = new PacketAckPacket();
            seperate.Packets = new PacketAckPacket.PacketsBlock[packet.Header.AckList.Length];

            for (int i = 0; i < packet.Header.AckList.Length; ++i)
            {
                seperate.Packets[i] = new PacketAckPacket.PacketsBlock();
                seperate.Packets[i].ID = packet.Header.AckList[i];
            }

            Packet ack = seperate;
            ack.Header.Sequence = packet.Header.Sequence;
            return ack;
        }
예제 #21
0
 // SpoofAck: create an ACK for the given packet
 public Packet SpoofAck(uint sequence)
 {
     PacketAckPacket spoof = new PacketAckPacket();
     spoof.Packets = new PacketAckPacket.PacketsBlock[1];
     spoof.Packets[0] = new PacketAckPacket.PacketsBlock();
     spoof.Packets[0].ID = sequence;
     return (Packet)spoof;
     //Legacy:
     ////Hashtable blocks = new Hashtable();
     ////Hashtable fields = new Hashtable();
     ////fields["ID"] = (uint)sequence;
     ////blocks[fields] = "Packets";
     ////return .BuildPacket("PacketAck", proxyConfig.protocol, blocks, Helpers.MSG_ZEROCODED);
 }
예제 #22
0
파일: Agent.cs 프로젝트: RavenB/gridsearch
        void SendAcks()
        {
            PacketAckPacket acks = null;

            lock (pendingAcks)
            {
                if (pendingAcks.Count > 0)
                {
                    if (pendingAcks.Count > 250)
                    {
                        Logger.Log("Too many ACKs queued up!", Helpers.LogLevel.Error);
                        return;
                    }

                    acks = new PacketAckPacket();
                    acks.Header.Reliable = false;
                    acks.Packets = new PacketAckPacket.PacketsBlock[pendingAcks.Count];

                    for (int i = 0; i < pendingAcks.Count; i++)
                    {
                        acks.Packets[i] = new PacketAckPacket.PacketsBlock();
                        acks.Packets[i].ID = pendingAcks.Values[i];
                    }

                    pendingAcks.Clear();
                }
            }

            if (acks != null)
                SendPacket(acks, true);
        }
        private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
        {
            PacketAckPacket ack = new PacketAckPacket
                                      {Header = {Reliable = false}, Packets = new PacketAckPacket.PacketsBlock[1]};
            ack.Packets[0] = new PacketAckPacket.PacketsBlock {ID = sequenceNumber};

            byte[] packetData = ack.ToBytes();
            int length = packetData.Length;

            UDPPacketBuffer buffer = new UDPPacketBuffer(remoteEndpoint, length) {DataLength = length};

            Buffer.BlockCopy(packetData, 0, buffer.Data, 0, length);

            SyncSend(buffer);
        }
예제 #24
0
파일: LLUDPServer.cs 프로젝트: thoys/simian
        public void SendAcks(LLAgent agent)
        {
            const int MAX_ACKS_PER_PACKET = Byte.MaxValue;

            uint ack;
            if (agent.PendingAcks.TryDequeue(out ack))
            {
                List<PacketAckPacket.PacketsBlock> blocks = new List<PacketAckPacket.PacketsBlock>(agent.PendingAcks.Count);
                PacketAckPacket.PacketsBlock block = new PacketAckPacket.PacketsBlock();
                block.ID = ack;
                blocks.Add(block);

                int count = 1;

                while (count < MAX_ACKS_PER_PACKET && agent.PendingAcks.TryDequeue(out ack))
                {
                    block = new PacketAckPacket.PacketsBlock();
                    block.ID = ack;
                    blocks.Add(block);

                    ++count;
                }

                PacketAckPacket packet = new PacketAckPacket();
                packet.Header.Reliable = false;
                packet.Packets = blocks.ToArray();

                SendPacket(agent, packet, ThrottleCategory.Unknown, false);
            }
        }
예제 #25
0
        // SeparateAck: create a standalone PacketAck for packet's appended ACKs
        public Packet SeparateAck(Packet packet)
        {
            PacketAckPacket seperate = new PacketAckPacket();
            int ackCount = ((packet.Header.Data[0] & Helpers.MSG_APPENDED_ACKS) == 0 ? 0 : (int)packet.Header.Data[packet.Header.Data.Length - 1]);
            seperate.Packets = new PacketAckPacket.PacketsBlock[ackCount];

            for (int i = 0; i < ackCount; ++i)
            {
                int offset = packet.Header.Data.Length - (ackCount - i) * 4 - 1;
                seperate.Packets[i].ID = (uint) ((packet.Header.Data[offset++] <<  0)
                                                + (packet.Header.Data[offset++] <<  8)
                                                + (packet.Header.Data[offset++] << 16)
                                                + (packet.Header.Data[offset++] << 24))
                                                ;
            }

            Packet ack = (Packet)seperate;
            ack.Header.Sequence = packet.Header.Sequence;
            return ack;
        }
예제 #26
0
        private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
        {
            PacketAckPacket ack = new PacketAckPacket();
            ack.Header.Reliable = false;
            ack.Packets = new PacketAckPacket.PacketsBlock[1];
            ack.Packets[0] = new PacketAckPacket.PacketsBlock();
            ack.Packets[0].ID = sequenceNumber;

            byte[] packetData = ack.ToBytes();
            int length = packetData.Length;

            OutgoingPacket outgoingPacket = new OutgoingPacket(null, packetData, 0, length, 
                remoteEndpoint, false, PacketType.PacketAck);

            AsyncBeginSend(outgoingPacket);
        }
예제 #27
0
        protected override void PacketReceived(UDPPacketBuffer buffer)
        {
            // Debugging/Profiling
            //try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
            //catch (Exception) { }

            LLUDPClient udpClient = null;
            Packet      packet    = null;
            int         packetEnd = buffer.DataLength - 1;
            IPEndPoint  address   = (IPEndPoint)buffer.RemoteEndPoint;

            #region Decoding

            try
            {
                packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
                                            // Only allocate a buffer for zerodecoding if the packet is zerocoded
                                            ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
            }
            catch (MalformedDataException)
            {
            }

            // Fail-safe check
            if (packet == null)
            {
                m_log.ErrorFormat("[LLUDPSERVER]: Malformed data, cannot parse {0} byte packet from {1}:",
                                  buffer.DataLength, buffer.RemoteEndPoint);
                m_log.Error(Utils.BytesToHexString(buffer.Data, buffer.DataLength, null));
                return;
            }

            #endregion Decoding

            #region Packet to Client Mapping

            // UseCircuitCode handling
            if (packet.Type == PacketType.UseCircuitCode)
            {
                object[] array = new object[] { buffer, packet };

                if (m_asyncPacketHandling)
                {
                    Util.FireAndForget(HandleUseCircuitCode, array);
                }
                else
                {
                    HandleUseCircuitCode(array);
                }

                return;
            }

            // Determine which agent this packet came from
            IClientAPI client;
            if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
            {
                //m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
                return;
            }

            udpClient = ((LLClientView)client).UDPClient;

            if (!udpClient.IsConnected)
            {
                return;
            }

            #endregion Packet to Client Mapping

            // Stats tracking
            Interlocked.Increment(ref udpClient.PacketsReceived);

            int now = Environment.TickCount & Int32.MaxValue;
            udpClient.TickLastPacketReceived = now;

            #region ACK Receiving

            // Handle appended ACKs
            if (packet.Header.AppendedAcks && packet.Header.AckList != null)
            {
                for (int i = 0; i < packet.Header.AckList.Length; i++)
                {
                    udpClient.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent);
                }
            }

            // Handle PacketAck packets
            if (packet.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                for (int i = 0; i < ackPacket.Packets.Length; i++)
                {
                    udpClient.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent);
                }

                // We don't need to do anything else with PacketAck packets
                return;
            }

            #endregion ACK Receiving

            #region ACK Sending

            if (packet.Header.Reliable)
            {
                udpClient.PendingAcks.Enqueue(packet.Header.Sequence);

                // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
                // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove
                // 2*MTU bytes from the value and send ACKs, and finally add the local value back to
                // client.BytesSinceLastACK. Lockless thread safety
                int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0);
                bytesSinceLastACK += buffer.DataLength;
                if (bytesSinceLastACK > LLUDPServer.MTU * 2)
                {
                    bytesSinceLastACK -= LLUDPServer.MTU * 2;
                    SendAcks(udpClient);
                }
                Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK);
            }

            #endregion ACK Sending

            #region Incoming Packet Accounting

            // Check the archive of received reliable packet IDs to see whether we already received this packet
            if (packet.Header.Reliable && !udpClient.PacketArchive.TryEnqueue(packet.Header.Sequence))
            {
                if (packet.Header.Resent)
                {
                    m_log.DebugFormat(
                        "[LLUDPSERVER]: Received a resend of already processed packet #{0}, type {1} from {2}",
                        packet.Header.Sequence, packet.Type, client.Name);
                }
                else
                {
                    m_log.WarnFormat(
                        "[LLUDPSERVER]: Received a duplicate (not marked as resend) of packet #{0}, type {1} from {2}",
                        packet.Header.Sequence, packet.Type, client.Name);
                }

                // Avoid firing a callback twice for the same packet
                return;
            }

            #endregion Incoming Packet Accounting

            #region BinaryStats
            LogPacketHeader(true, udpClient.CircuitCode, 0, packet.Type, (ushort)packet.Length);
            #endregion BinaryStats

            #region Ping Check Handling

            if (packet.Type == PacketType.StartPingCheck)
            {
                // We don't need to do anything else with ping checks
                StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
                CompletePing(udpClient, startPing.PingID.PingID);

                if ((Environment.TickCount - m_elapsedMSSinceLastStatReport) >= 3000)
                {
                    udpClient.SendPacketStats();
                    m_elapsedMSSinceLastStatReport = Environment.TickCount;
                }
                return;
            }
            else if (packet.Type == PacketType.CompletePingCheck)
            {
                // We don't currently track client ping times
                return;
            }

            #endregion Ping Check Handling

            // Inbox insertion
            packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
        }
예제 #28
0
        /// <summary>
        /// Sends out pending acknowledgements
        /// </summary>
        private void SendAcks(NetworkInfo User_info)
        {
            lock (User_info.PendingAcks)
             		{
             			if (connected && User_info.PendingAcks.Count > 0)
             			{
             				if (User_info.PendingAcks.Count > 250)
             				{
             					// FIXME: Handle the odd case where we have too many pending ACKs queued up
             					//Client.Log("Too many ACKs queued up!", Helpers.LogLevel.Error);
             					return;
             				}

             				int i = 0;
             				PacketAckPacket acks = new PacketAckPacket();
             				acks.Packets = new PacketAckPacket.PacketsBlock[User_info.PendingAcks.Count];

             				foreach (uint ack in User_info.PendingAcks.Values)
             				{
             					acks.Packets[i] = new PacketAckPacket.PacketsBlock();
             					acks.Packets[i].ID = ack;
             					i++;
             				}

             				acks.Header.Reliable = false;
             				SendPacket(acks, true,User_info);

             				User_info.PendingAcks.Clear();
             			}
             		}
        }
        private void SendACK(uint id)
        {
            try
            {
                PacketAckPacket ack = new PacketAckPacket();
                ack.Packets = new PacketAckPacket.PacketsBlock[1];
                ack.Packets[0].ID = id;

                ack.Header.Reliable = false;

                // Set the sequence number
                ack.Header.Sequence = ++Sequence;

                Listener.SendTo(ack.ToBytes(), RemoteEndpoint);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
예제 #30
0
 public override void SendAckImmediate(IPEndPoint remoteEndpoint, PacketAckPacket ack)
 {
     PacketsSent.Add(ack);
 }
예제 #31
0
        protected override void PacketReceived(UDPPacketBuffer buffer)
        {
            Packet packet = null;

            // Check if this packet came from the server we expected it to come from
            if (!remoteEndPoint.Address.Equals(((IPEndPoint)buffer.RemoteEndPoint).Address))
            {
                Logger.Log("Received " + buffer.DataLength + " bytes of data from unrecognized source " +
                           ((IPEndPoint)buffer.RemoteEndPoint).ToString(), Helpers.LogLevel.Warning, Client);
                return;
            }

            // Update the disconnect flag so this sim doesn't time out
            DisconnectCandidate = false;

            #region Packet Decoding

            int packetEnd = buffer.DataLength - 1;

            try
            {
                packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
                                            // Only allocate a buffer for zerodecoding if the packet is zerocoded
                                            ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[8192] : null);
            }
            catch (MalformedDataException)
            {
                Logger.Log(String.Format("Malformed data, cannot parse packet:\n{0}",
                                         Utils.BytesToHexString(buffer.Data, buffer.DataLength, null)), Helpers.LogLevel.Error);
            }

            // Fail-safe check
            if (packet == null)
            {
                Logger.Log("Couldn't build a message from the incoming data", Helpers.LogLevel.Warning, Client);
                return;
            }

            Interlocked.Add(ref Stats.RecvBytes, buffer.DataLength);
            Interlocked.Increment(ref Stats.RecvPackets);

            #endregion Packet Decoding

            if (packet.Header.Resent)
            {
                Interlocked.Increment(ref Stats.ReceivedResends);
            }

            #region ACK Receiving

            // Handle appended ACKs
            if (packet.Header.AppendedAcks && packet.Header.AckList != null)
            {
                lock (NeedAck)
                {
                    for (int i = 0; i < packet.Header.AckList.Length; i++)
                    {
                        NeedAck.Remove(packet.Header.AckList[i]);
                    }
                }
            }

            // Handle PacketAck packets
            if (packet.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                lock (NeedAck)
                {
                    for (int i = 0; i < ackPacket.Packets.Length; i++)
                    {
                        NeedAck.Remove(ackPacket.Packets[i].ID);
                    }
                }
            }

            #endregion ACK Receiving

            if (packet.Header.Reliable)
            {
                #region ACK Sending

                // Add this packet to the list of ACKs that need to be sent out
                uint sequence = (uint)packet.Header.Sequence;
                PendingAcks.Enqueue(sequence);

                // Send out ACKs if we have a lot of them
                if (PendingAcks.Count >= Client.Settings.MAX_PENDING_ACKS)
                {
                    SendAcks();
                }

                #endregion ACK Sending

                // Check the archive of received packet IDs to see whether we already received this packet
                if (!PacketArchive.TryEnqueue(packet.Header.Sequence))
                {
                    if (packet.Header.Resent)
                    {
                        Logger.DebugLog("Received a resend of already processed packet #" + packet.Header.Sequence + ", type: " + packet.Type);
                    }
                    else
                    {
                        Logger.Log("Received a duplicate (not marked as resend) of packet #" + packet.Header.Sequence + ", type: " + packet.Type,
                                   Helpers.LogLevel.Warning);
                    }

                    // Avoid firing a callback twice for the same packet
                    return;
                }
            }

            #region Inbox Insertion

            NetworkManager.IncomingPacket incomingPacket;
            incomingPacket.Simulator = this;
            incomingPacket.Packet    = packet;

            Network.PacketInbox.Enqueue(incomingPacket);

            #endregion Inbox Insertion

            #region Stats Tracking
            if (Client.Settings.TRACK_UTILIZATION)
            {
                Client.Stats.Update(packet.Type.ToString(), OpenMetaverse.Stats.Type.Packet, 0, packet.Length);
            }
            #endregion
        }
예제 #32
0
        protected override void PacketReceived(UDPPacketBuffer buffer)
        {
            // Debugging/Profiling
            //try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
            //catch (Exception) { }

            Packet     packet    = null;
            int        packetEnd = buffer.DataLength - 1;
            IPEndPoint address   = (IPEndPoint)buffer.RemoteEndPoint;

            int now = Util.TickCount();

            #region Decoding

            try
            {
                packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
                                            // Only allocate a buffer for zerodecoding if the packet is zerocoded
                                            ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
            }
            catch (MalformedDataException)
            {
                m_log.ErrorFormat("Malformed data, cannot parse packet from {0}:\n{1}",
                                  buffer.RemoteEndPoint, Utils.BytesToHexString(buffer.Data, buffer.DataLength, null));
            }

            // Fail-safe check
            if (packet == null)
            {
                m_log.Warn("Couldn't build a message from incoming data " + buffer.DataLength +
                           " bytes long from " + buffer.RemoteEndPoint);
                return;
            }

            #endregion Decoding

            #region Packet to Client Mapping

            // UseCircuitCode handling
            if (packet.Type == PacketType.UseCircuitCode)
            {
                m_log.Debug("Handling UseCircuitCode packet from " + buffer.RemoteEndPoint);
                HandleUseCircuitCode(buffer, (UseCircuitCodePacket)packet, now);
                return;
            }

            // Determine which agent this packet came from
            LLAgent agent;
            if (!m_clients.TryGetValue(address, out agent))
            {
                m_log.Debug("Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + Scene.Name);
                return;
            }

            if (!agent.IsConnected)
            {
                return;
            }

            #endregion Packet to Client Mapping

            #region Stats Tracking

            Interlocked.Increment(ref m_packetsReceived);
            Interlocked.Increment(ref agent.PacketsReceived);
            agent.TickLastPacketReceived = now;

            if (LoggingEnabled)
            {
                m_log.Debug("--> (" + buffer.RemoteEndPoint + ") " + packet.Type);
            }

            #endregion Stats Tracking

            #region ACK Receiving

            // Handle appended ACKs
            if (packet.Header.AppendedAcks && packet.Header.AckList != null)
            {
                for (int i = 0; i < packet.Header.AckList.Length; i++)
                {
                    agent.NeedAcks.Remove(packet.Header.AckList[i], now, packet.Header.Resent);
                }
            }

            // Handle PacketAck packets
            if (packet.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                for (int i = 0; i < ackPacket.Packets.Length; i++)
                {
                    agent.NeedAcks.Remove(ackPacket.Packets[i].ID, now, packet.Header.Resent);
                }

                // We don't need to do anything else with PacketAck packets
                return;
            }

            #endregion ACK Receiving

            #region Incoming Packet Accounting

            // Check the archive of received reliable packet IDs to see whether we already received this packet
            if (packet.Header.Reliable && !agent.PacketArchive.TryEnqueue(packet.Header.Sequence))
            {
                if (packet.Header.Resent)
                {
                    m_log.Debug("Received a resend of already processed packet #" + packet.Header.Sequence + ", type: " + packet.Type);
                }
                else
                {
                    m_log.Warn("Received a duplicate (not marked as resend) of packet #" + packet.Header.Sequence + ", type: " + packet.Type);
                }

                // ACK this packet immediately to avoid further resends of this same packet
                SendAckImmediate((IPEndPoint)buffer.RemoteEndPoint, packet.Header.Sequence);

                // Avoid firing a callback twice for the same packet
                return;
            }

            #endregion Incoming Packet Accounting

            #region ACK Sending

            if (packet.Header.Reliable)
            {
                agent.PendingAcks.Enqueue(packet.Header.Sequence);
            }

            #endregion ACK Sending

            #region Ping Check Handling

            if (packet.Type == PacketType.StartPingCheck)
            {
                // We don't need to do anything else with ping checks
                StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
                CompletePing(agent, startPing.PingID.PingID);
                return;
            }
            else if (packet.Type == PacketType.CompletePingCheck)
            {
                // We don't currently track client ping times
                return;
            }

            #endregion Ping Check Handling

            // Inbox insertion
            m_packetInbox.Enqueue(new IncomingPacket(agent, packet, now));
        }
예제 #33
0
파일: Agent.cs 프로젝트: RavenB/gridsearch
        public void SendAck(uint ack)
        {
            PacketAckPacket acks = new PacketAckPacket();
            acks.Header.Reliable = false;
            acks.Packets = new PacketAckPacket.PacketsBlock[1];
            acks.Packets[0] = new PacketAckPacket.PacketsBlock();
            acks.Packets[0].ID = ack;

            SendPacket(acks, true);
        }
예제 #34
0
        /// <summary>
        /// Callback handler for incomming data
        /// </summary>
        /// <param name="result"></param>
        private void OnReceivedData(IAsyncResult result)
        {
            ipeSender = new IPEndPoint(IPAddress.Any, 0);
            epSender  = (EndPoint)ipeSender;
            Packet packet = null;
            int    numBytes;

            // If we're receiving data the sim connection is open
            connected = true;

            // Update the disconnect flag so this sim doesn't time out
            DisconnectCandidate = false;
            NetworkInfo User_info = null;

            lock (RecvBuffer)
            {
                // Retrieve the incoming packet
                try
                {
                    numBytes = Connection.EndReceiveFrom(result, ref epSender);

                    //find user_agent_info

                    int packetEnd = numBytes - 1;
                    packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer);


                    //should check if login/useconnection packet first
                    if (packet.Type == PacketType.UseCircuitCode)
                    {
                        //new connection
                        //TODO check that this circuit and session is expected
                        UseCircuitCodePacket cir_pack = (UseCircuitCodePacket)packet;
                        NetworkInfo          new_user = new NetworkInfo();
                        new_user.CircuitCode        = cir_pack.CircuitCode.Code;
                        new_user.User.AgentID       = cir_pack.CircuitCode.ID;
                        new_user.User.SessionID     = cir_pack.CircuitCode.SessionID;
                        new_user.endpoint           = epSender;
                        new_user.Inbox              = new Queue <uint>(Settings.INBOX_SIZE);
                        new_user.Connection         = new ClientConnection();
                        new_user.Connection.NetInfo = new_user;
                        new_user.Connection.Start();

                        //this.CallbackObject.NewUserCallback(new_user);
                        this.User_agents.Add(new_user);
                    }

                    NetworkInfo temp_agent = null;
                    IPEndPoint  send_ip    = (IPEndPoint)epSender;
                    //	this.callback_object.error("incoming: address is "+send_ip.Address +"port number is: "+send_ip.Port.ToString());

                    for (int ii = 0; ii < this.User_agents.Count; ii++)
                    {
                        temp_agent = (NetworkInfo)this.User_agents[ii];
                        IPEndPoint ag_ip = (IPEndPoint)temp_agent.endpoint;
                        //this.callback_object.error("searching: address is "+ag_ip.Address +"port number is: "+ag_ip.Port.ToString());

                        if ((ag_ip.Address.ToString() == send_ip.Address.ToString()) && (ag_ip.Port.ToString() == send_ip.Port.ToString()))
                        {
                            //this.callback_object.error("found user");
                            User_info = temp_agent;
                            break;
                        }
                    }

                    Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
                }
                catch (SocketException)
                {
                    // Client.Log(endPoint.ToString() + " socket is closed, shutting down " + this.Region.Name,
                    //     Helpers.LogLevel.Info);

                    connected = false;
                    //Network.DisconnectSim(this);
                    return;
                }
            }
            if (User_info == null)
            {
                //error finding agent
                //this.CallbackObject.ErrorCallback("no user found");
                return;
            }

            // Fail-safe check
            if (packet == null)
            {
                //this.CallbackObject.ErrorCallback("couldn't build packet");
                // Client.Log("Couldn't build a message from the incoming data", Helpers.LogLevel.Warning);
                return;
            }
            //this.callback_object.error("past tests");
            // Track the sequence number for this packet if it's marked as reliable
            if (packet.Header.Reliable)
            {
                if (User_info.PendingAcks.Count > Settings.MAX_PENDING_ACKS)
                {
                    SendAcks(User_info);
                }

                // Check if we already received this packet
                if (User_info.Inbox.Contains(packet.Header.Sequence))
                {
                    //Client.Log("Received a duplicate " + packet.Type.ToString() + ", sequence=" +
                    //    packet.Header.Sequence + ", resent=" + ((packet.Header.Resent) ? "Yes" : "No") +
                    //    ", Inbox.Count=" + Inbox.Count + ", NeedAck.Count=" + NeedAck.Count,
                    //    Helpers.LogLevel.Info);

                    // Send an ACK for this packet immediately
                    //SendAck(packet.Header.Sequence);

                    // TESTING: Try just queuing up ACKs for resent packets instead of immediately triggering an ACK
                    lock (User_info.PendingAcks)
                    {
                        uint sequence = (uint)packet.Header.Sequence;
                        if (!User_info.PendingAcks.ContainsKey(sequence))
                        {
                            User_info.PendingAcks[sequence] = sequence;
                        }
                    }

                    // Avoid firing a callback twice for the same packet
                    // this.callback_object.error("avoiding callback");
                    return;
                }
                else
                {
                    lock (User_info.PendingAcks)
                    {
                        uint sequence = (uint)packet.Header.Sequence;
                        if (!User_info.PendingAcks.ContainsKey(sequence))
                        {
                            User_info.PendingAcks[sequence] = sequence;
                        }
                    }
                }
            }

            // Add this packet to our inbox
            lock (User_info.Inbox)
            {
                while (User_info.Inbox.Count >= Settings.INBOX_SIZE)
                {
                    User_info.Inbox.Dequeue();
                }
                User_info.Inbox.Enqueue(packet.Header.Sequence);
            }

            // Handle appended ACKs
            if (packet.Header.AppendedAcks)
            {
                lock (User_info.NeedAck)
                {
                    foreach (uint ack in packet.Header.AckList)
                    {
                        User_info.NeedAck.Remove(ack);
                    }
                }
            }

            // Handle PacketAck packets
            if (packet.Type == PacketType.PacketAck)
            {
                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                lock (User_info.NeedAck)
                {
                    foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
                    {
                        User_info.NeedAck.Remove(block.ID);
                    }
                }
            }

            //if it is a ping check send return
            if ((packet.Type == PacketType.StartPingCheck))
            {
                //reply to pingcheck
                libsecondlife.Packets.StartPingCheckPacket    startPing = (libsecondlife.Packets.StartPingCheckPacket)packet;
                libsecondlife.Packets.CompletePingCheckPacket endPing   = new CompletePingCheckPacket();
                endPing.PingID.PingID = startPing.PingID.PingID;
                SendPacket(endPing, true, User_info);
            }
            else if (packet.Type != PacketType.PacketAck)
            {
                User_info.Connection.InQueue.Enqueue(packet);
            }
        }
예제 #35
0
        /// <summary>
        /// Sends out pending acknowledgements
        /// </summary>
        /// <returns>Number of ACKs sent</returns>
        private int SendAcks()
        {
            uint ack;
            int ackCount = 0;

            if (PendingAcks.TryDequeue(out ack))
            {
                List<PacketAckPacket.PacketsBlock> blocks = new List<PacketAckPacket.PacketsBlock>();
                PacketAckPacket.PacketsBlock block = new PacketAckPacket.PacketsBlock();
                block.ID = ack;
                blocks.Add(block);

                while (PendingAcks.TryDequeue(out ack))
                {
                    block = new PacketAckPacket.PacketsBlock();
                    block.ID = ack;
                    blocks.Add(block);
                }

                PacketAckPacket packet = new PacketAckPacket();
                packet.Header.Reliable = false;
                packet.Packets = blocks.ToArray();

                ackCount = blocks.Count;
                SendPacket(packet);
            }

            return ackCount;
        }
예제 #36
0
        /// <summary>
        /// Add a new client circuit.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="epSender"></param>
        /// <param name="epProxy"></param>
        protected virtual void AddNewClient(UseCircuitCodePacket useCircuit, EndPoint epSender, EndPoint epProxy)
        {
            //Slave regions don't accept new clients
            if (m_localScene.RegionStatus != RegionStatus.SlaveScene)
            {
                AuthenticateResponse sessionInfo;
                bool isNewCircuit = false;

                if (!m_packetServer.IsClientAuthorized(useCircuit, m_circuitManager, out sessionInfo))
                {
                    m_log.WarnFormat(
                        "[CONNECTION FAILURE]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
                        useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code, epSender);

                    return;
                }

                lock (clientCircuits)
                {
                    if (!clientCircuits.ContainsKey(epSender))
                    {
                        clientCircuits.Add(epSender, useCircuit.CircuitCode.Code);
                        isNewCircuit = true;
                    }
                }

                if (isNewCircuit)
                {
                    // This doesn't need locking as it's synchronized data
                    clientCircuits_reverse[useCircuit.CircuitCode.Code] = epSender;

                    lock (proxyCircuits)
                    {
                        proxyCircuits[useCircuit.CircuitCode.Code] = epProxy;
                    }

                    m_packetServer.AddNewClient(epSender, useCircuit, m_assetCache, sessionInfo, epProxy);

                    //m_log.DebugFormat(
                    //    "[CONNECTION SUCCESS]: Incoming client {0} (circuit code {1}) received and authenticated for {2}",
                    //    useCircuit.CircuitCode.ID, useCircuit.CircuitCode.Code, m_localScene.RegionInfo.RegionName);
                }
            }

            // Ack the UseCircuitCode packet
            PacketAckPacket ack_it = (PacketAckPacket)PacketPool.Instance.GetPacket(PacketType.PacketAck);

            // TODO: don't create new blocks if recycling an old packet
            ack_it.Packets       = new PacketAckPacket.PacketsBlock[1];
            ack_it.Packets[0]    = new PacketAckPacket.PacketsBlock();
            ack_it.Packets[0].ID = useCircuit.Header.Sequence;
            // ((useCircuit.Header.Sequence < uint.MaxValue) ? useCircuit.Header.Sequence : 0) is just a failsafe to ensure that we don't overflow.
            ack_it.Header.Sequence = ((useCircuit.Header.Sequence < uint.MaxValue) ? useCircuit.Header.Sequence : 0) + 1;
            ack_it.Header.Reliable = false;

            byte[] ackmsg = ack_it.ToBytes();

            // Need some extra space in case we need to add proxy
            // information to the message later
            byte[] msg = new byte[4096];
            Buffer.BlockCopy(ackmsg, 0, msg, 0, ackmsg.Length);

            SendPacketTo(msg, ackmsg.Length, SocketFlags.None, useCircuit.CircuitCode.Code);

            PacketPool.Instance.ReturnPacket(useCircuit);
        }
예제 #37
0
            // CheckAcks: check for and remove ACKs of packets we've injected
            public Packet CheckAcks(Packet packet, Direction direction, ref int length, ref bool needsCopy)
            {
                Dictionary<uint, Packet> acks = direction == Direction.Incoming ? outgoingAcks : incomingAcks;
                List<uint> seenAcks = direction == Direction.Incoming ? outgoingSeenAcks : incomingSeenAcks;

                if (acks.Count == 0)
                    return packet;

                // check for embedded ACKs
                if (packet.Type == PacketType.PacketAck)
                {
                    bool changed = false;
                    List<PacketAckPacket.PacketsBlock> newPacketBlocks = new List<PacketAckPacket.PacketsBlock>();
                    foreach (PacketAckPacket.PacketsBlock pb in ((PacketAckPacket)packet).Packets)
                    {
                        uint id = pb.ID;
#if DEBUG_SEQUENCE
						string hrup = "Check !" + id;
#endif
                        if (acks.ContainsKey(id))
                        {
#if DEBUG_SEQUENCE
							hrup += " get's";
#endif
                            acks.Remove(id);
                            seenAcks.Add(id);
                            changed = true;
                        }
                        else
                            newPacketBlocks.Add(pb);
#if DEBUG_SEQUENCE
						Console.WriteLine(hrup);
#endif
                    }
                    if (changed)
                    {
                        PacketAckPacket newPacket = new PacketAckPacket();
                        newPacket.Packets = new PacketAckPacket.PacketsBlock[newPacketBlocks.Count];

                        int a = 0;
                        foreach (PacketAckPacket.PacketsBlock pb in newPacketBlocks)
                        {
                            newPacket.Packets[a++] = pb;
                        }

                        SwapPacket(packet, (Packet)newPacket);
                        packet = newPacket;
                        length = packet.Header.Data.Length;
                        needsCopy = false;
                    }
                }

                // check for appended ACKs
                if ((packet.Header.Data[0] & Helpers.MSG_APPENDED_ACKS) != 0)
                {
                    int ackCount = packet.Header.AckList.Length;
                    for (int i = 0; i < ackCount; )
                    {
                        uint ackID = packet.Header.AckList[i]; // FIXME FIXME FIXME
#if DEBUG_SEQUENCE
						string hrup = "Check @" + ackID;
#endif
                        if (acks.ContainsKey(ackID))
                        {
#if DEBUG_SEQUENCE
							hrup += " get's";
#endif
                            uint[] newAcks = new uint[ackCount - 1];
                            Array.Copy(packet.Header.AckList, 0, newAcks, 0, i);
                            Array.Copy(packet.Header.AckList, i + 1, newAcks, i, ackCount - i - 1);
                            packet.Header.AckList = newAcks;
                            --ackCount;
                            acks.Remove(ackID);
                            seenAcks.Add(ackID);
                            needsCopy = false;
                        }
                        else
                            ++i;
#if DEBUG_SEQUENCE
						Console.WriteLine(hrup);
#endif
                    }
                    if (ackCount == 0)
                    {
                        packet.Header.Flags ^= Helpers.MSG_APPENDED_ACKS;
                        packet.Header.AckList = new uint[0];
                    }
                }

                return packet;
            }
예제 #38
0
        private void PacketHandler()
        {
            IncomingPacket incomingPacket = new IncomingPacket();
            Packet         packet         = null;
            Simulator      simulator      = null;

            while (connected)
            {
                // Reset packet to null for the check below
                packet = null;

                if (PacketInbox.Dequeue(200, ref incomingPacket))
                {
                    packet    = incomingPacket.Packet;
                    simulator = incomingPacket.Simulator;

                    if (packet != null)
                    {
                        // Skip the ACK handling on packets synthesized from CAPS messages
                        if (packet.Header.Sequence != 0)
                        {
                            #region ACK accounting
                            // TODO: Replace PacketArchive Queue<> with something more efficient

                            // Check the archives to see whether we already received this packet
                            lock (simulator.PacketArchive)
                            {
                                if (simulator.PacketArchive.Contains(packet.Header.Sequence))
                                {
                                    if (packet.Header.Resent)
                                    {
                                        Client.DebugLog("Received resent packet #" + packet.Header.Sequence);
                                    }
                                    else
                                    {
                                        Client.Log(String.Format("Received a duplicate of packet #{0}, current type: {1}",
                                                                 packet.Header.Sequence, packet.Type), Helpers.LogLevel.Warning);
                                    }

                                    // Avoid firing a callback twice for the same packet
                                    continue;
                                }
                                else
                                {
                                    // Keep the PacketArchive size within a certain capacity
                                    while (simulator.PacketArchive.Count >= Settings.PACKET_ARCHIVE_SIZE)
                                    {
                                        simulator.PacketArchive.Dequeue(); simulator.PacketArchive.Dequeue();
                                        simulator.PacketArchive.Dequeue(); simulator.PacketArchive.Dequeue();
                                    }

                                    simulator.PacketArchive.Enqueue(packet.Header.Sequence);
                                }
                            }

                            #endregion ACK accounting

                            #region ACK handling

                            // Handle appended ACKs
                            if (packet.Header.AppendedAcks)
                            {
                                lock (simulator.NeedAck)
                                {
                                    for (int i = 0; i < packet.Header.AckList.Length; i++)
                                    {
                                        simulator.NeedAck.Remove(packet.Header.AckList[i]);
                                    }
                                }
                            }

                            // Handle PacketAck packets
                            if (packet.Type == PacketType.PacketAck)
                            {
                                PacketAckPacket ackPacket = (PacketAckPacket)packet;

                                lock (simulator.NeedAck)
                                {
                                    for (int i = 0; i < ackPacket.Packets.Length; i++)
                                    {
                                        simulator.NeedAck.Remove(ackPacket.Packets[i].ID);
                                    }
                                }
                            }

                            #endregion ACK handling
                        }

                        #region FireCallbacks

                        if (Client.Settings.SYNC_PACKETCALLBACKS)
                        {
                            PacketEvents.RaiseEvent(PacketType.Default, packet, simulator);
                            PacketEvents.RaiseEvent(packet.Type, packet, simulator);
                        }
                        else
                        {
                            PacketEvents.BeginRaiseEvent(PacketType.Default, packet, simulator);
                            PacketEvents.BeginRaiseEvent(packet.Type, packet, simulator);
                        }

                        #endregion FireCallbacks
                    }
                }
            }
        }
예제 #39
0
        /// <summary>
        /// Sends out pending acknowledgements
        /// </summary>
        private void SendAcks()
        {
            lock (PendingAcks)
            {
                if (PendingAcks.Count > 0)
                {
                    if (PendingAcks.Count > 250)
                    {
                        Logger.Log("Too many ACKs queued up!", Helpers.LogLevel.Error, Client);
                        return;
                    }

                    PacketAckPacket acks = new PacketAckPacket();
                    acks.Header.Reliable = false;
                    acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];

                    for (int i = 0; i < PendingAcks.Count; i++)
                    {
                        acks.Packets[i] = new PacketAckPacket.PacketsBlock();
                        acks.Packets[i].ID = PendingAcks.Values[i];
                    }

                    SendPacket(acks, true);

                    PendingAcks.Clear();
                }
            }
        }
예제 #40
0
        private void ack_pack(Packet Pack)
        {
            if (Pack.Header.Reliable)
            {
                libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
                ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
                ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
                ack_it.Packets[0].ID = Pack.Header.Sequence;
                ack_it.Header.Reliable = false;

                OutPacket(ack_it);

            }
            /*
            if (Pack.Header.Reliable)
            {
                lock (PendingAcks)
                {
                    uint sequence = (uint)Pack.Header.Sequence;
                    if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
                }
            }*/
        }
예제 #41
0
 // SpoofAck: create an ACK for the given packet
 public Packet SpoofAck(uint sequence)
 {
     PacketAckPacket spoof = new PacketAckPacket();
     spoof.Packets = new PacketAckPacket.PacketsBlock[1];
     spoof.Packets[0] = new PacketAckPacket.PacketsBlock();
     spoof.Packets[0].ID = sequence;
     return (Packet)spoof;
 }
예제 #42
0
        private void SendAcks()
        {
            lock (PendingAcks)
            {
                if (PendingAcks.Count > 0)
                {
                    if (PendingAcks.Count > 250)
                    {
                        // FIXME: Handle the odd case where we have too many pending ACKs queued up
                        OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Too many ACKs queued up!");
                        return;
                    }

                    //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Sending PacketAck");

                    int i = 0;
                    PacketAckPacket acks = new PacketAckPacket();
                    acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];

                    foreach (uint ack in PendingAcks.Values)
                    {
                        acks.Packets[i] = new PacketAckPacket.PacketsBlock();
                        acks.Packets[i].ID = ack;
                        i++;
                    }

                    acks.Header.Reliable = false;
                    OutPacket(acks);

                    PendingAcks.Clear();
                }
            }
        }
예제 #43
0
            // CheckAcks: check for and remove ACKs of packets we've injected
            public Packet CheckAcks(Packet packet, Direction direction, ref int length, ref bool needsCopy)
            {
                Dictionary<uint, Packet> acks = direction == Direction.Incoming ? outgoingAcks : incomingAcks;
                List<uint> seenAcks = direction == Direction.Incoming ? outgoingSeenAcks : incomingSeenAcks;

                if (acks.Count == 0)
                    return packet;

                // check for embedded ACKs
                if (packet.Type == PacketType.PacketAck)
                {
                    bool changed = false;
                    List<PacketAckPacket.PacketsBlock> newPacketBlocks = new List<PacketAckPacket.PacketsBlock>();
                    foreach (PacketAckPacket.PacketsBlock pb in ((PacketAckPacket)packet).Packets)
                    {
                        uint id = pb.ID;
                        if (acks.ContainsKey(id))
                        {
                            acks.Remove(id);
                            seenAcks.Add(id);
                            changed = true;
                        }
                        else
                        {
                            newPacketBlocks.Add(pb);
                        }
                    }
                    if (changed)
                    {
                        PacketAckPacket newPacket = new PacketAckPacket();
                        newPacket.Packets = new PacketAckPacket.PacketsBlock[newPacketBlocks.Count];

                        int a = 0;
                        foreach (PacketAckPacket.PacketsBlock pb in newPacketBlocks)
                        {
                            newPacket.Packets[a++] = pb;
                        }

                        SwapPacket(packet, (Packet)newPacket);
                        packet = newPacket;
                        needsCopy = false;
                    }
                }

                // check for appended ACKs
                if (packet.Header.AppendedAcks)
                {
                    int ackCount = packet.Header.AckList.Length;
                    for (int i = 0; i < ackCount; )
                    {
                        uint ackID = packet.Header.AckList[i]; // FIXME FIXME FIXME

                        if (acks.ContainsKey(ackID))
                        {
                            uint[] newAcks = new uint[ackCount - 1];
                            Array.Copy(packet.Header.AckList, 0, newAcks, 0, i);
                            Array.Copy(packet.Header.AckList, i + 1, newAcks, i, ackCount - i - 1);
                            packet.Header.AckList = newAcks;
                            --ackCount;
                            acks.Remove(ackID);
                            seenAcks.Add(ackID);
                            needsCopy = false;
                        }
                        else
                            ++i;
                    }
                    if (ackCount == 0)
                    {
                        packet.Header.AppendedAcks = false;
                        packet.Header.AckList = new uint[0];
                    }
                }

                return packet;
            }
        private void SendAck(ushort id)
        {
            PacketAckPacket ack = new PacketAckPacket();

            ack.Packets = new PacketAckPacket.PacketsBlock[1];
            ack.Packets[0] = new PacketAckPacket.PacketsBlock();
            ack.Packets[0].ID = id;
            ack.Header.Reliable = false;

            lock (PendingAcks)
            {
                if (PendingAcks.Contains(id))
                {
                    PendingAcks.Remove(id);
                }
            }

            SendPacket(ack, true);
        }
예제 #45
0
        /// <summary>
        /// Send an ack immediately to the given endpoint.
        /// </summary>
        /// <remarks>
        /// FIXME: Might be possible to use SendPacketData() like everything else, but this will require refactoring so
        /// that we can obtain the UDPClient easily at this point.
        /// </remarks>
        /// <param name="remoteEndpoint"></param>
        /// <param name="sequenceNumber"></param>
        private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
        {
            PacketAckPacket ack = new PacketAckPacket();
            ack.Header.Reliable = false;
            ack.Packets = new PacketAckPacket.PacketsBlock[1];
            ack.Packets[0] = new PacketAckPacket.PacketsBlock();
            ack.Packets[0].ID = sequenceNumber;

            SendAckImmediate(remoteEndpoint, ack);
        }
        private void SendAcks()
        {
            lock (PendingAcks)
            {
                if (PendingAcks.Count > 0)
                {
                    int i = 0;
                    PacketAckPacket acks = new PacketAckPacket();
                    acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];

                    foreach (uint ack in PendingAcks)
                    {
                        acks.Packets[i] = new PacketAckPacket.PacketsBlock();
                        acks.Packets[i].ID = ack;
                        i++;
                    }

                    acks.Header.Reliable = false;

                    SendPacket(acks, true);

                    PendingAcks.Clear();
                }
            }
        }
예제 #47
0
        /// <summary>
        /// Sends out pending acknowledgements
        /// </summary>
        private void SendAcks()
        {
            uint ack;

            if (PendingAcks.TryDequeue(out ack))
            {
                Interlocked.Decrement(ref PendingAckCount);

                List<PacketAckPacket.PacketsBlock> blocks = new List<PacketAckPacket.PacketsBlock>();
                PacketAckPacket.PacketsBlock block = new PacketAckPacket.PacketsBlock();
                block.ID = ack;
                blocks.Add(block);

                while (PendingAcks.TryDequeue(out ack))
                {
                    Interlocked.Decrement(ref PendingAckCount);

                    block = new PacketAckPacket.PacketsBlock();
                    block.ID = ack;
                    blocks.Add(block);
                }

                PacketAckPacket packet = new PacketAckPacket();
                packet.Header.Reliable = false;
                packet.Packets = blocks.ToArray();

                SendPacket(packet);
            }
        }
예제 #48
0
        void IncomingPacketHandler()
        {
            IncomingPacket incomingPacket = new IncomingPacket();
            Packet         packet         = null;
            UDPClient      client         = null;

            while (IsRunning)
            {
                // Reset packet to null for the check below
                packet = null;

                if (packetInbox.Dequeue(100, ref incomingPacket))
                {
                    packet = incomingPacket.Packet;
                    client = incomingPacket.Client;

                    if (packet != null)
                    {
                        #region ACK accounting

                        // Check the archives to see whether we already received this packet
                        lock (client.PacketArchive)
                        {
                            if (client.PacketArchive.Contains(packet.Header.Sequence))
                            {
                                if (packet.Header.Resent)
                                {
                                    Logger.DebugLog("Received resent packet #" + packet.Header.Sequence);
                                }
                                else
                                {
                                    Logger.Log(String.Format("Received a duplicate of packet #{0}, current type: {1}",
                                                             packet.Header.Sequence, packet.Type), Helpers.LogLevel.Warning);
                                }

                                // Avoid firing a callback twice for the same packet
                                continue;
                            }
                            else
                            {
                                // Keep the PacketArchive size within a certain capacity
                                while (client.PacketArchive.Count >= Settings.PACKET_ARCHIVE_SIZE)
                                {
                                    client.PacketArchive.Dequeue(); client.PacketArchive.Dequeue();
                                    client.PacketArchive.Dequeue(); client.PacketArchive.Dequeue();
                                }

                                client.PacketArchive.Enqueue(packet.Header.Sequence);
                            }
                        }

                        #endregion ACK accounting

                        #region ACK handling

                        // Handle appended ACKs
                        if (packet.Header.AppendedAcks)
                        {
                            lock (client.NeedAcks)
                            {
                                for (int i = 0; i < packet.Header.AckList.Length; i++)
                                {
                                    client.NeedAcks.Remove(packet.Header.AckList[i]);
                                }
                            }
                        }

                        // Handle PacketAck packets
                        if (packet.Type == PacketType.PacketAck)
                        {
                            PacketAckPacket ackPacket = (PacketAckPacket)packet;

                            lock (client.NeedAcks)
                            {
                                for (int i = 0; i < ackPacket.Packets.Length; i++)
                                {
                                    client.NeedAcks.Remove(ackPacket.Packets[i].ID);
                                }
                            }
                        }

                        #endregion ACK handling

                        packetEvents.BeginRaiseEvent(packet.Type, packet, client.Agent);
                    }
                }
            }
        }