Exemplo n.º 1
0
        public void FreshHello()
        {
            var connectionId = 15690248817103694251U;

            var packet = new RegularPacket(connectionId, 1, null);

            Assert.IsNotNull(packet.ConnectionId);
            packet.AddFrame(new StreamFrame(ClientHandshakeMessageTest.ClientInchoateGoogleFreshParametersClientMessageFactory.Value, false, 1, 0));
            var packetBytes = packet.PadAndNullEncrypt();

            Assert.IsNotNull(packet.MessageAuthenticationHash);

            Debug.WriteLine("Message authentication hash: " + packet.MessageAuthenticationHash.Select(b => b.ToString("x2")).Aggregate((c, n) => c + " " + n));
            Debug.WriteLine(packetBytes.GenerateHexDumpWithASCII());

            Assert.AreEqual(PacketLibrary.ClientInchoateGoogleFresh.Length, packetBytes.Length);

            // Soft warn
            for (var i = 0; i < packetBytes.Length; i++)
            {
                if (packetBytes[i] != PacketLibrary.ClientInchoateGoogleFresh[i])
                {
                    Debug.WriteLine($"Byte difference at position {i}: generated byte is {packetBytes[i]:x2} but reference byte was {PacketLibrary.ClientInchoateGoogleFresh[i]:x2}");
                }
            }

            // Hard test fail
            for (var i = 0; i < packetBytes.Length; i++)
            {
                Assert.AreEqual(PacketLibrary.ClientInchoateGoogleFresh[i], packetBytes[i], $"Byte difference at position {i}: generated byte is {packetBytes[i]:x2} but reference byte was {PacketLibrary.ClientInchoateGoogleFresh[i]:x2}");
            }

            // Now try to reverse engineer it to ensure packet parsing works.
            AbstractPacketBase rePacket;

            AbstractPacketBase.TryParse(packetBytes, out rePacket);

            Assert.IsNotNull(rePacket);
            Assert.IsInstanceOfType(rePacket, typeof(RegularPacket));
            var rp = (RegularPacket)rePacket;

            Assert.AreEqual(rp.ConnectionId, packet.ConnectionId.Value);
            Assert.AreEqual(rp.Entropy, packet.Entropy);
            Assert.AreEqual(rp.FecGroup, packet.FecGroup);
            Assert.IsNotNull(rp.MessageAuthenticationHash);
            Assert.AreEqual(rp.MessageAuthenticationHash.Sum(b => (int)b), packet.MessageAuthenticationHash.Sum(b => (int)b));
            Assert.AreEqual(rp.PacketNumber, packet.PacketNumber);

            var rpBytes = rp.ToByteArray();

            //Debug.WriteLine(rpBytes.GenerateHexDumpWithASCII());
            Assert.AreEqual(packetBytes.Length, rpBytes.Length);

            // Soft reverse engineering warn
            for (var i = 0; i < packetBytes.Length; i++)
            {
                if (packetBytes[i] != rpBytes[i])
                {
                    Debug.WriteLine($"Byte difference at position {i}: generated byte is {rpBytes[i]:x2} but reference byte was {packetBytes[i]:x2}");
                }
            }

            // Hard test fail
            for (var i = 0; i < packetBytes.Length; i++)
            {
                Assert.AreEqual(packetBytes[i], rpBytes[i], $"Byte difference at position {i}: generated byte is {rpBytes[i]:x2} but reference byte was {packetBytes[i]:x2}");
            }
        }
Exemplo n.º 2
0
        private async Task RunAcceptLoopAsync()
        {
            try
            {
                while (true)
                {
                    for (var schedulerIndex = 0; schedulerIndex < _numSchedulers; schedulerIndex++)
                    {
                        try
                        {
                            ArraySegment <byte>     buffer        = new ArraySegment <byte>(new byte[4096]);
                            IPEndPoint              sender        = new IPEndPoint(_listenSocket.AddressFamily == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any, 0);
                            SocketReceiveFromResult receiveResult = await _listenSocket.ReceiveFromAsync(buffer, SocketFlags.None, sender);

                            if (receiveResult.ReceivedBytes > 0)
                            {
                                AbstractPacketBase packet = AbstractPacketBase.Parse(buffer.AsSpan());
                                System.Console.WriteLine($"rcv {receiveResult.RemoteEndPoint} " + packet.ToString());

                                //var response = new RegularPacket(connectionID, 2, null);
                                //await _listenSocket.SendToAsync(new ArraySegment<byte>(response.PadAndNullEncrypt()), SocketFlags.None, receiveResult.RemoteEndPoint);

                                /*
                                 * if (_connections.TryGetValue(connectionID, out QuicConnection connection))
                                 * {
                                 *  await connection.Input.WriteAsync(buffer);
                                 * }
                                 * else
                                 * {
                                 *  connection = new QuicConnection(connectionID.ToString(), _listenSocket, _memoryPool, _schedulers[schedulerIndex], _logger);
                                 *  _connections.Add(connectionID, connection);
                                 *  await connection.StartAsync(_dispatcher);
                                 * }
                                 */
                            }
                        }
                        catch (SocketException ex) when(ex.SocketErrorCode == SocketError.ConnectionReset)
                        {
                            // REVIEW: Should there be a separate log message for a connection reset this early?
                            _logger.LogDebug($"Connection Reset: connectionId: ({null})");
                        }
                        catch (SocketException ex) when(!_unbinding)
                        {
                            _logger.LogError(ex, $"Connection Error: connectionId: ({null})");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (_unbinding)
                {
                    // Means we must be unbinding. Eat the exception.
                }
                else
                {
                    _logger.LogCritical(ex, $"Unexpected exeption in {nameof(QuicTransport)}.{nameof(RunAcceptLoopAsync)}.");
                    _listenException = ex;

                    // Request shutdown so we can rethrow this exception
                    // in Stop which should be observable.
                    _applicationLifetime.StopApplication();
                }
            }
        }