Exemple #1
0
        private bool ResendPackages(IEnumerable <OutgoingPacket> packetList)
        {
            var now = Util.Now;

            foreach (var outgoingPacket in packetList)
            {
                // Check if the packet timed out completely
                if (outgoingPacket.FirstSendTime < now - PacketTimeout)
                {
                    ColorDbg.WriteResend(outgoingPacket, "TIMEOUT");
                    return(true);
                }

                // Check if we should retransmit a packet because it probably got lost
                if (outgoingPacket.LastSendTime < now - currentRto)
                {
                    ColorDbg.WriteResend(outgoingPacket, "RESEND");
                    currentRto = currentRto + currentRto;
                    if (currentRto > MaxRetryInterval)
                    {
                        currentRto = MaxRetryInterval;
                    }
                    SendRaw(outgoingPacket);
                }
            }
            return(false);
        }
Exemple #2
0
        private void AddOutgoingPacket(OutgoingPacket packet, PacketFlags flags = PacketFlags.None)
        {
            lock (sendLoopLock)
            {
                var ids = GetPacketCounter(packet.PacketType);
                if (ts3Crypt.CryptoInitComplete)
                {
                    IncPacketCounter(packet.PacketType);
                }

                packet.PacketId     = ids.Id;
                packet.GenerationId = ids.Generation;
                packet.ClientId     = ClientId;
                packet.PacketFlags |= flags;

                switch (packet.PacketType)
                {
                case PacketType.Voice:
                case PacketType.VoiceWhisper:
                    packet.PacketFlags |= PacketFlags.Unencrypted;
                    NetUtil.H2N(packet.PacketId, packet.Data, 0);
                    break;

                case PacketType.Command:
                case PacketType.CommandLow:
                    packet.PacketFlags |= PacketFlags.Newprotocol;
                    packetAckManager.Add(packet.PacketId, packet);
                    break;

                case PacketType.Ping:
                    lastSentPingId      = packet.PacketId;
                    packet.PacketFlags |= PacketFlags.Unencrypted;

                    break;

                case PacketType.Pong:
                    packet.PacketFlags |= PacketFlags.Unencrypted;
                    break;

                case PacketType.Ack:
                case PacketType.AckLow:
                    break;                     // Nothing to do

                case PacketType.Init1:
                    packet.PacketFlags |= PacketFlags.Unencrypted;
                    packetAckManager.Add(packet.PacketId, packet);
                    break;

                default: throw Util.UnhandledDefault(packet.PacketType);
                }

                ColorDbg.WritePkgOut(packet);

                ts3Crypt.Encrypt(packet);

                packet.FirstSendTime = Util.Now;

                SendRaw(packet);
            }
        }
Exemple #3
0
 public void ReceiveInitAck()
 {
     // this method is a bit hacky since it removes ALL Init1 packets
     // from the sendQueue instead of the one with the preceding
     // init step id (see Ts3Crypt.ProcessInit1).
     // But usually this should be no problem since the init order is linear
     lock (sendLoopLock)
     {
         ColorDbg.WriteDetail("Cleaned Inits", "INIT");
         var remPacket = packetAckManager.Values.Where(x => x.PacketType == PacketType.Init1).ToArray();
         foreach (var packet in remPacket)
         {
             packetAckManager.Remove(packet.PacketId);
         }
     }
 }
Exemple #4
0
 private void UpdateRto(TimeSpan sampleRtt)
 {
     // Timeout calculation (see: https://tools.ietf.org/html/rfc6298)
     // SRTT_{i+1}    = (1-a) * SRTT_i   + a * RTT
     // DevRTT_{i+1}  = (1-b) * DevRTT_i + b * | RTT - SRTT_{i+1} |
     // Timeout_{i+1} = SRTT_{i+1} + max(ClockRes, 4 * DevRTT_{i+1})
     if (smoothedRtt < TimeSpan.Zero)
     {
         smoothedRtt = sampleRtt;
     }
     else
     {
         smoothedRtt = TimeSpan.FromTicks((long)((1 - AlphaSmooth) * smoothedRtt.Ticks + AlphaSmooth * sampleRtt.Ticks));
     }
     smoothedRttVar = TimeSpan.FromTicks((long)((1 - BetaSmooth) * smoothedRttVar.Ticks + BetaSmooth * Math.Abs(sampleRtt.Ticks - smoothedRtt.Ticks)));
     currentRto     = smoothedRtt + Util.Max(ClockResolution, TimeSpan.FromTicks(4 * smoothedRttVar.Ticks));
     ColorDbg.WriteRtt(smoothedRtt, smoothedRttVar, currentRto);
 }
Exemple #5
0
        public IncomingPacket FetchPacket()
        {
            while (true)
            {
                if (Closed)
                {
                    return(null);
                }

                if (TryFetchPacket(receiveQueue, out var packet))
                {
                    return(packet);
                }
                if (TryFetchPacket(receiveQueueLow, out packet))
                {
                    return(packet);
                }

                var    dummy = new IPEndPoint(IPAddress.Any, 0);
                byte[] buffer;

                try { buffer = udpClient.Receive(ref dummy); }
                catch (IOException) { return(null); }
                catch (SocketException) { return(null); }

                if (dummy.Address.Equals(remoteAddress.Address) && dummy.Port != remoteAddress.Port)
                {
                    continue;
                }

                packet = Ts3Crypt.GetIncommingPacket(buffer);
                // Invalid packet, ignore
                if (packet == null)
                {
                    ColorDbg.WritePkgRaw(buffer, "DROPPING");
                    continue;
                }

                GenerateGenerationId(packet);
                if (!ts3Crypt.Decrypt(packet))
                {
                    continue;
                }

                NetworkStats.LogInPacket(packet);

                ColorDbg.WritePkgIn(packet);

                switch (packet.PacketType)
                {
                case PacketType.Voice: break;

                case PacketType.VoiceWhisper: break;

                case PacketType.Command: packet = ReceiveCommand(packet, receiveQueue, PacketType.Ack); break;

                case PacketType.CommandLow: packet = ReceiveCommand(packet, receiveQueueLow, PacketType.AckLow); break;

                case PacketType.Ping: ReceivePing(packet); break;

                case PacketType.Pong: ReceivePong(packet); break;

                case PacketType.Ack: packet = ReceiveAck(packet); break;

                case PacketType.AckLow: break;

                case PacketType.Init1: ReceiveInitAck(); break;

                default: throw Util.UnhandledDefault(packet.PacketType);
                }

                if (packet != null)
                {
                    return(packet);
                }
            }
        }