Exemplo n.º 1
0
        void SendAck(RudpPacket packet)
        {
            RudpPacket ack = new RudpPacket();

            ack.TargetID     = Session.UserID;
            ack.TargetClient = Session.ClientID;
            ack.PeerID       = RemotePeerID;
            ack.PacketType   = RudpPacketType.Ack;
            ack.Sequence     = packet.Sequence;
            ack.Payload      = RudpAck.Encode(HighestSeqRecvd, (byte)(MAX_WINDOW_SIZE - RecvPacketMap.Count));
            ack.Ident        = packet.Ident;

            //Session.Log("Ack Sent, Seq " + ack.Sequence.ToString() + ", ID " + ack.PeerID.ToString() + ", highest " + HighestSeqRecvd.ToString());

            if (!AckMap.Contains(ack.Sequence))
            {
                AckMap[ack.Sequence] = true;
                AckOrder.Enqueue(ack.Sequence);
            }

            while (AckMap.Count > MAX_WINDOW_SIZE * 2)
            {
                AckMap.Remove(AckOrder.Dequeue());
            }

            SendTracked(new TrackPacket(ack));
        }
Exemplo n.º 2
0
        void ReceiveAck(RudpPacket packet)
        {
            int latency = 0;
            int retries = -1;

            // find original packet that was sent
            TrackPacket sent = null;

            lock (SendSection)
            {
                foreach (TrackPacket tracked in SendPacketMap)
                {
                    if (tracked.Packet.Sequence == packet.Sequence)
                    {
                        sent = tracked;
                        break;
                    }
                }
            }

            // mark packet as acked
            if (sent != null)
            {
                sent.Target.LastAck = Core.TimeNow;

                // connect handshake
                if (State == RudpState.Connecting && sent.Packet.PacketType == RudpPacketType.Syn)
                {
                    SynAckReceieved = true;

                    SetPrimaryAddress(packet.Ident);

                    if (SynAckSent && SynAckReceieved)
                    {
                        Session.Log("Connected (recv ack)");
                        ChangeState(RudpState.Connected);
                        SetConnected();

                        // if data packets received before final connection ack, process them now
                        ManageRecvWindow();
                    }
                }

                if (!sent.Acked)
                {
                    InOrderAcks++;

                    if (sent.Retries == 0)
                    {
                        latency = (int)sent.TimeEllapsed(Core);
                        latency = latency < 5 ? 5 : latency;
                        AvgLatency.Input(latency);
                        AvgLatency.Next();
                    }
                }

                retries = sent.Retries;

                sent.Acked = true;
            }

            RudpAck ack = new RudpAck(packet.Payload);

            //Session.Log("Ack Recv, Seq " + packet.Sequence.ToString() + ", ID " + packet.PeerID.ToString() + ", highest " + ack.Start.ToString() + ", retries " + retries.ToString() + ", latency " + latency.ToString());

            lock (SendSection)
            {
                // ack possibly un-acked packets
                foreach (TrackPacket tracked in SendPacketMap)
                {
                    // ack if start past the zero boundry with sequences behind
                    if (tracked.Packet.Sequence > 0xFF - 25 && ack.Start < 25)
                    {
                        tracked.Acked = true;
                    }

                    // break start before boundry and sequences ahead are not recvd/acked yet
                    if (ack.Start > 0xFF - 25 && tracked.Packet.Sequence < 25)
                    {
                        break;
                    }

                    // normal acking procedure
                    else if (ack.Start >= tracked.Packet.Sequence)
                    {
                        tracked.Acked = true;
                    }

                    else
                    {
                        break;
                    }
                }

                // remove acked, only remove packets from front
                while (SendPacketMap.Count > 0 && SendPacketMap.Peek().Acked)
                {
                    // calculate receive speed of remote host by rate they ack
                    AvgBytesSent.Input(SendPacketMap.Peek().Packet.Payload.Length);

                    SendPacketMap.Dequeue();
                    PacketsCompleted++;
                }
            }

            // increase window if packets removed from beginning of buffer
            //if(packetsRemoved && SendWindowSize < 25)
            //  SendWindowSize++;


            ManageSendWindow();
        }