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}"); } }
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(); } } }