public void Deserialize_Allocate()
 {
     for (int i = 0; i < 10000; i++)
     {
         var deserializer = CryptoDtoDeserializer.DeserializeIgnoreSequence(remoteChannel, cryptoDtoPacket);
     }
 }
 public void DeserializeGetDto_Allocate()
 {
     for (int i = 0; i < 10000; i++)
     {
         var deserializer = CryptoDtoDeserializer.DeserializeIgnoreSequence(remoteChannel, cryptoDtoPacket);
         var dto          = deserializer.GetDto <BenchmarkDto>();
     }
 }
 public void Deserialize_LowAllocate()
 {
     for (int i = 0; i < 10000; i++)
     {
         buffer.Clear();
         var deserializer = CryptoDtoDeserializer.DeserializeIgnoreSequence(buffer, remoteChannel, cryptoDtoPacket);
     }
 }
예제 #4
0
        private static void TaskVoiceServerReceive(
            Logger logger,
            CancellationToken cancelToken,
            ClientConnectionData connection,
            UdpClient udpClient,
            BlockingCollection <IMsgPackTypeName> receiveQueue)
        {
            logger.Debug(nameof(TaskVoiceServerReceive) + " started");

            try
            {
                IPEndPoint sender = new IPEndPoint(IPAddress.Any, 60005);
                byte[]     data;

                while (!cancelToken.IsCancellationRequested)
                {
                    data = udpClient.Receive(ref sender);               //UDP is a datagram protocol, not a streaming protocol, so it's whole datagrams here.
                    if (data.Length < 30 || data.Length > 1500)
                    {
                        continue;
                    }
                    //Could check that the sender has the right IP - but NAT-ing significantly reduces the attack surface here
                    connection.VoiceServerBytesReceived += data.Length;
                    var deserializer = CryptoDtoDeserializer.DeserializeIgnoreSequence(connection.VoiceCryptoChannel, data);
                    if (!deserializer.IsSequenceValid())
                    {
                        logger.Debug("Duplicate or old packet received");
                        continue;       //If a duplicate packet received (because it's UDP) - ignore it
                    }
                    //Crypto DTO stream is only concerned with duplicated or old packets, it doesn't discard out-of-order. Need to find out if Opus discards OOO packets.

                    var dtoName = deserializer.GetDtoName();

                    if (dtoName == "AR")
                    {
                        dtoName = RadioRxDto.TypeNameConst;     //The server will be sending RadioRxDto as "AR" to maintain backwards compatibility for a year or two until old clients get updated.
                    }
                    switch (dtoName)
                    {
                    case RadioRxDto.TypeNameConst:
                    {
                        var dto = deserializer.GetDto <RadioRxDto>();
                        if (connection.ReceiveAudio && connection.IsConnected)
                        {
                            receiveQueue.Add(dto);
                        }
                        break;
                    }

                    case nameof(CallRequestDto):
                    case ShortDtoNames.CallRequest:
                    {
                        var dto = deserializer.GetDto <CallRequestDto>();
                        if (connection.ReceiveAudio && connection.IsConnected)
                        {
                            receiveQueue.Add(dto);
                        }
                        break;
                    }

                    case nameof(CallResponseDto):
                    case ShortDtoNames.CallResponse:
                    {
                        var dto = deserializer.GetDto <CallResponseDto>();
                        if (connection.ReceiveAudio && connection.IsConnected)
                        {
                            receiveQueue.Add(dto);
                        }
                        break;
                    }

                    case nameof(HeartbeatAckDto):
                    case ShortDtoNames.HeartbeatAckDto:
                        connection.LastVoiceServerHeartbeatAckUtc = DateTime.UtcNow;
                        logger.Trace("Received voice server heartbeat");
                        break;
                    }
                }
            }
            catch (SocketException sex)
            {
                if (connection.IsConnected)     //If the socket exception occurs whilst disconnected, it's likely to just be a forced socket closure from doing disconnect().
                {
                    logger.Error(sex);
                }
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }

            logger.Debug(nameof(TaskVoiceServerReceive) + " stopped");
        }