XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text;
using XFESystem.Network;

namespace XFESystem.Network.Tests;

public sealed class ProtocolTests
{
    static (Ipv4Network Stack, PacketFixture Peer, TestPlatform Clock) Setup()
    { var peer = new PacketFixture(); var clock = new TestPlatform(); return (new(peer, clock, Ipv4Configuration.QemuUserNat), peer, clock); }
    [Fact]
    public void ActualPacketsPerformArpDnsTcpAndPreserveStreamBytes()
    {
        var (stack, peer, clock) = Setup(); using Stream stream = stack.OpenTcp("www.bing.com", 443, 1000);
        stream.Write("client bytes"u8); Assert.Equal("client bytes", Encoding.ASCII.GetString(peer.Written.ToArray()));
        peer.QueueData("server bytes", fin: true); using var result = new MemoryStream(); byte[] part = new byte[3]; int count;
        while ((count = stream.Read(part)) != 0) result.Write(part, 0, count);
        Assert.Equal("server bytes", Encoding.ASCII.GetString(result.ToArray()));
        Assert.Contains(clock.Messages, line => line.Contains("XFE_NETWORK_ARP"));
        Assert.Contains(clock.Messages, line => line.Contains("XFE_NETWORK_DNS|Host|www.bing.com|Address|1.2.3.4"));
        Assert.Contains(clock.Messages, line => line.Contains("XFE_NETWORK_TCP|Address|1.2.3.4|Port|443|Established|1"));
        Assert.All(peer.Sent.Where(frame => NetworkPackets.Read16(frame, 12) == 0x0800), frame =>
        {
            Assert.Equal(0, NetworkPackets.Checksum(frame.AsSpan(14, 20)));
            int length = NetworkPackets.Read16(frame, 16) - 20;
            Assert.Equal(0, NetworkPackets.TransportChecksum(NetworkPackets.Read32(frame, 26), NetworkPackets.Read32(frame, 30), frame[23], frame.AsSpan(34, length)));
        });
    }
    [Fact]
    public void LostSynAndDataAckRetransmitWithoutDuplicatingApplicationBytes()
    {
        var (stack, peer, clock) = Setup(); peer.DropFirstSyn = peer.DropFirstDataAck = true;
        using Stream stream = stack.OpenTcp("1.2.3.4", 443, 2000); stream.Write("once"u8);
        Assert.Equal(2, peer.SynCount); Assert.Equal(2, peer.DataSends);
        Assert.Equal("once", Encoding.ASCII.GetString(peer.Written.ToArray())); Assert.True(clock.Milliseconds >= 600);
    }
    [Fact]
    public void CorruptTcpChecksumNeverReachesTheStream()
    {
        var (stack, peer, _) = Setup(); using Stream stream = stack.OpenTcp("1.2.3.4", 443);
        peer.QueueCorruptThenValid("correct"); byte[] bytes = new byte[20];
        Assert.Equal(7, stream.Read(bytes)); Assert.Equal("correct", Encoding.ASCII.GetString(bytes, 0, 7));
    }
    [Fact]
    public void OutOfOrderAndDuplicateDataRequireActualRetransmittedBytes()
    {
        var (stack, peer, _) = Setup(); using Stream stream = stack.OpenTcp("1.2.3.4", 443);
        uint sequence = peer.PeerNext; peer.QueueDataAt(sequence + 5, "world"); peer.QueueDataAt(sequence, "hello");
        peer.QueueDataAt(sequence, "hello"); peer.QueueDataAt(sequence + 5, "world");
        byte[] bytes = new byte[20]; Assert.Equal(10, stream.Read(bytes)); Assert.Equal("helloworld", Encoding.ASCII.GetString(bytes, 0, 10));
    }
    [Fact]
    public void RstRequiresExactNextSequence()
    {
        var (stack, peer, _) = Setup(); using Stream stream = stack.OpenTcp("1.2.3.4", 443);
        peer.QueueReset(false); peer.QueueData("ok"); Assert.Equal(2, stream.Read(new byte[8]));
        peer.QueueReset(true); Assert.Throws<IOException>(() => stream.Read(new byte[8]));
    }
    [Fact]
    public void PeerSilenceIsBoundedAndDoesNotInventReadData()
    {
        var (stack, _, clock) = Setup(); using Stream stream = stack.OpenTcp("1.2.3.4", 443);
        stream.ReadTimeout = 40; Assert.Throws<IOException>(() => stream.Read(new byte[10])); Assert.InRange(clock.Milliseconds, 40, 45);
    }
    [Fact]
    public void FailedArpDnsAndTcpHaveBoundedTimeouts()
    {
        foreach (int layer in new[] { 0, 1, 2 })
        {
            var (stack, peer, clock) = Setup(); peer.AnswerArp = layer != 0; peer.AnswerDns = layer != 1; peer.AnswerTcp = layer != 2;
            Assert.Throws<IOException>(() => stack.OpenTcp("www.bing.com", 443, 50)); Assert.InRange(clock.Milliseconds, 50, 55);
        }
    }
    [Fact]
    public void ActiveOwnerIsExclusiveAndDisposeAllowsTheNextRealConnection()
    {
        var (stack, _, _) = Setup(); using (Stream first = stack.OpenTcp("1.2.3.4", 443))
            Assert.Throws<InvalidOperationException>(() => stack.OpenTcp("1.2.3.4", 443));
        using Stream second = stack.OpenTcp("1.2.3.4", 80); Assert.True(second.CanRead);
    }
    [Theory]
    [InlineData("0.0.0.0")]
    [InlineData("224.0.0.1")]
    [InlineData("255.255.255.255")]
    [InlineData("10.0.2.15")]
    public void UnusableTcpDestinationsAreRejected(string host)
    { var (stack, _, _) = Setup(); Assert.Throws<IOException>(() => stack.OpenTcp(host, 443)); }
    [Fact]
    public void OddLengthChecksumIncludesTheFinalHighByte()
    {
        Assert.Equal(0xfbfd, NetworkPackets.Checksum(new byte[] { 1, 2, 3 }));
        Assert.True(NetworkPackets.TryParseAddress("10.0.2.15", out uint address)); Assert.Equal(0x0a00020fu, address);
        Assert.False(NetworkPackets.TryParseAddress("10.0.2.256", out _));
    }
}