using System.Runtime.InteropServices; using XFESystem.Network; namespace XFESystem.NativeRuntime.Application.Network; /// Lazy network initialization belongs to the caller's network worker, never the desktop UI. public static class NativeNetwork { static readonly object gate = new(); static Func? random; static Ipv4Network? network; static E1000Device? device; public static void ConfigureEntropy(Func random32) { ArgumentNullException.ThrowIfNull(random32); lock (gate) random = random32; } public static Stream OpenTcp(string host, int port, int timeoutMilliseconds = 15000) { Func? entropy = Volatile.Read(ref random); if (entropy == null) throw new InvalidOperationException("Native TCP requires an explicitly configured strong random source."); if (timeoutMilliseconds is < 1 or > 120000) throw new ArgumentOutOfRangeException(nameof(timeoutMilliseconds)); long deadline = checked(NativePlatform.Milliseconds() + timeoutMilliseconds); long remaining = deadline - NativePlatform.Milliseconds(); if (remaining <= 0 || !Monitor.TryEnter(gate, checked((int)remaining))) throw new IOException("Native network ownership timed out."); try { if (NativePlatform.Milliseconds() >= deadline) throw new IOException("Native network ownership timed out."); if (network == null) { var platform = new Platform(entropy); device = new E1000Device(new Hardware(), platform, deadline); network = new Ipv4Network(device, platform, Ipv4Configuration.QemuUserNat); NativePlatform.Write("XFE_NETWORK_CONFIGURATION|Mode|ExplicitStaticQemuUserNat|Address|10.0.2.15|Mask|255.255.255.0|Gateway|10.0.2.2|Dns|10.0.2.3|Dhcp|0\n"); } return network.OpenTcpUntil(host, port, deadline, timeoutMilliseconds); } finally { Monitor.Exit(gate); } } sealed class Platform(Func random32) : INetworkPlatform { public long Milliseconds => NativePlatform.Milliseconds(); public void Wait(int milliseconds) => Thread.Sleep(milliseconds); public uint Random32() => random32(); public void Trace(string text) => NativePlatform.Write(text); } sealed unsafe class Hardware : IE1000Hardware { const string Library = "xfe_pal"; [DllImport(Library, EntryPoint = "xfe_network_pci_read", CallingConvention = CallingConvention.Cdecl)] static extern uint PciRead(uint bus, uint device, uint function, uint offset); [DllImport(Library, EntryPoint = "xfe_network_pci_write", CallingConvention = CallingConvention.Cdecl)] static extern int PciWrite(uint bus, uint device, uint function, uint offset, uint value); [DllImport(Library, EntryPoint = "xfe_network_map_mmio", CallingConvention = CallingConvention.Cdecl)] static extern ulong Map(ulong physical, uint bytes); [DllImport(Library, EntryPoint = "xfe_mmio_read32", CallingConvention = CallingConvention.Cdecl)] static extern uint MmioRead(ulong address); [DllImport(Library, EntryPoint = "xfe_mmio_write32", CallingConvention = CallingConvention.Cdecl)] static extern void MmioWrite(ulong address, uint value); [DllImport(Library, EntryPoint = "xfe_network_dma_allocate", CallingConvention = CallingConvention.Cdecl)] static extern void* Allocate(uint pages, ulong* physical); [DllImport(Library, EntryPoint = "xfe_network_dma_free", CallingConvention = CallingConvention.Cdecl)] static extern int Free(void* address, uint pages); public uint ReadPci(uint bus, uint device, uint function, uint offset) => PciRead(bus, device, function, offset); public void WritePci(uint bus, uint device, uint function, uint offset, uint value) { if (PciWrite(bus, device, function, offset, value) != 1) throw new IOException("Invalid PCI configuration write."); } public nuint MapMmio(ulong physical, uint bytes) => checked((nuint)Map(physical, bytes)); public uint ReadMmio(nuint address) => MmioRead(address); public void WriteMmio(nuint address, uint value) => MmioWrite(address, value); public DmaMemory AllocateDma(uint pages) { ulong physical = 0; void* address = Allocate(pages, &physical); return new((nuint)address, physical, pages); } public void FreeDma(DmaMemory memory) { if (Free((void*)memory.Address, memory.Pages) != 1) throw new IOException("Native DMA ownership release failed."); } } }