Example #1
0
        /// <summary>
        ///
        /// </summary>
        public void SendPing()
        {
            uint oldestUnacked = 0;

            // Get the oldest NeedAck value, the first entry in the sorted dictionary
            lock (NeedAck)
            {
                if (NeedAck.Count > 0)
                {
                    SortedDictionary <uint, NetworkManager.OutgoingPacket> .KeyCollection.Enumerator en = NeedAck.Keys.GetEnumerator();
                    en.MoveNext();
                    oldestUnacked = en.Current;
                }
            }

            //if (oldestUnacked != 0)
            //    Logger.DebugLog("Sending ping with oldestUnacked=" + oldestUnacked);

            StartPingCheckPacket ping = new StartPingCheckPacket();

            ping.PingID.PingID        = Stats.LastPingID++;
            ping.PingID.OldestUnacked = oldestUnacked;
            ping.Header.Reliable      = false;
            SendPacket(ping);
            Stats.LastPingSent = Environment.TickCount;
        }
        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);
            }
        }
Example #3
0
        /// <summary>
        ///
        /// </summary>
        public void SendPing()
        {
            StartPingCheckPacket ping = new StartPingCheckPacket();

            ping.PingID.PingID        = Stats.LastPingID++;
            ping.PingID.OldestUnacked = 0; // FIXME
            ping.Header.Reliable      = false;
            SendPacket(ping, true);
            Stats.LastPingSent = Environment.TickCount;
        }
        void StartPingCheckHandler(Packet packet, Agent agent)
        {
            StartPingCheckPacket start = (StartPingCheckPacket)packet;

            CompletePingCheckPacket complete = new CompletePingCheckPacket();

            complete.Header.Reliable = false;
            complete.PingID.PingID   = start.PingID.PingID;

            server.UDP.SendPacket(agent.AgentID, complete, PacketCategory.Overhead);
        }
        public void SendPing(LLUDPClient udpClient)
        {
            StartPingCheckPacket pc = (StartPingCheckPacket)PacketPool.Instance.GetPacket(PacketType.StartPingCheck);

            pc.Header.Reliable = false;

            pc.PingID.PingID = (byte)udpClient.CurrentPingSequence++;
            // We *could* get OldestUnacked, but it would hurt performance and not provide any benefit
            pc.PingID.OldestUnacked = 0;

            SendPacket(udpClient, pc, ThrottleOutPacketType.Unknown, false);
        }
Example #6
0
        public void SendPing(LLAgent agent)
        {
            StartPingCheckPacket pc = new StartPingCheckPacket();

            pc.Header.Reliable = false;

            pc.PingID.PingID = (byte)agent.CurrentPingSequence++;
            // We *could* get OldestUnacked, but it would hurt performance and not provide any benefit
            pc.PingID.OldestUnacked = 0;

            SendPacket(agent, pc, ThrottleCategory.Unknown, false);
        }
Example #7
0
        private void StartPingCheckHandler(Packet packet, Simulator simulator)
        {
            StartPingCheckPacket    incomingPing = (StartPingCheckPacket)packet;
            CompletePingCheckPacket ping         = new CompletePingCheckPacket();

            ping.PingID.PingID   = incomingPing.PingID.PingID;
            ping.Header.Reliable = false;
            // TODO: We can use OldestUnacked to correct transmission errors
            //   I don't think that's right.  As far as I can tell, the Viewer
            //   only uses this to prune its duplicate-checking buffer. -bushing

            SendPacket(ping, simulator);
        }
Example #8
0
        /// <summary>
        /// 
        /// </summary>
        public void SendPing()
        {
            uint oldestUnacked = 0;

            // Get the oldest NeedAck value, the first entry in the sorted dictionary
            lock (NeedAck)
            {
                if (NeedAck.Count > 0)
                {
                    SortedDictionary<uint, NetworkManager.OutgoingPacket>.KeyCollection.Enumerator en = NeedAck.Keys.GetEnumerator();
                    en.MoveNext();
                    oldestUnacked = en.Current;
                }
            }

            //if (oldestUnacked != 0)
            //    Logger.DebugLog("Sending ping with oldestUnacked=" + oldestUnacked);

            StartPingCheckPacket ping = new StartPingCheckPacket();
            ping.PingID.PingID = Stats.LastPingID++;
            ping.PingID.OldestUnacked = oldestUnacked;
            ping.Header.Reliable = false;
            SendPacket(ping);
            Stats.LastPingSent = Environment.TickCount;
        }
Example #9
0
 /// <summary>
 /// 
 /// </summary>
 public void SendPing()
 {
     StartPingCheckPacket ping = new StartPingCheckPacket();
     ping.PingID.PingID = Stats.LastPingID++;
     ping.PingID.OldestUnacked = 0; // FIXME
     ping.Header.Reliable = false;
     SendPacket(ping, true);
     Stats.LastPingSent = Environment.TickCount;
 }
Example #10
0
        public void SendPing(LLAgent agent)
        {
            StartPingCheckPacket pc = new StartPingCheckPacket();
            pc.Header.Reliable = false;

            pc.PingID.PingID = (byte)agent.CurrentPingSequence++;
            // We *could* get OldestUnacked, but it would hurt performance and not provide any benefit
            pc.PingID.OldestUnacked = 0;

            SendPacket(agent, pc, ThrottleCategory.Unknown, false);
        }
Example #11
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));
        }
Example #12
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));
        }