void StartPingCheckHandler(Packet packet, Agent agent)
        {
            StartPingCheckPacket start = (StartPingCheckPacket)packet;

            CompletePingCheckPacket complete = new CompletePingCheckPacket();
            complete.Header.Reliable = false;
            complete.PingID.PingID = start.PingID.PingID;

            agent.SendPacket(complete);
        }
Example #2
0
 public void CompletePing(LLUDPClient udpClient, byte pingID)
 {
     CompletePingCheckPacket completePing = new CompletePingCheckPacket();
     completePing.PingID.PingID = pingID;
     SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false, null);
 }
Example #3
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);
        }
        private void StartPingCheckHandler(Packet packet, Simulator simulator)
        {
            StartPingCheckPacket incomingPing = (StartPingCheckPacket)packet;
            CompletePingCheckPacket ping = new CompletePingCheckPacket();
            ping.PingID.PingID = incomingPing.PingID.PingID;

            // TODO: We can use OldestUnacked to correct transmission errors

            SendPacket((Packet)ping, simulator);
        }
Example #5
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);
            }
        }
Example #6
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)
            {
                m_log.ErrorFormat("[LLUDPSERVER]: 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("[LLUDPSERVER]: 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("[LLUDPSERVER]: Handling UseCircuitCode packet from " + buffer.RemoteEndPoint);
                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.Debug("[LLUDPSERVER]: Received a resend of already processed packet #" + packet.Header.Sequence + ", type: " + packet.Type);
                else
                    m_log.Warn("[LLUDPSERVER]: Received a duplicate (not marked as resend) of packet #" + packet.Header.Sequence + ", type: " + packet.Type);

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

            #endregion Incoming Packet Accounting

            #region Ping Check Handling

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

                CompletePingCheckPacket completePing = new CompletePingCheckPacket();
                completePing.PingID.PingID = startPing.PingID.PingID;
                SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
                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 #7
0
 public void CompletePing(LLAgent agent, byte pingID)
 {
     CompletePingCheckPacket completePing = new CompletePingCheckPacket();
     completePing.Header.Reliable = false;
     completePing.PingID.PingID = pingID;
     SendPacket(agent, completePing, ThrottleCategory.Unknown, false);
 }
        /// <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);
             		}
        }