狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

.NET借助虛擬網(wǎng)卡實現(xiàn)一個簡單異地組網(wǎng)工具

freeflydom
2024年6月11日 9:27 本文熱度 1163

由于工作需要,經(jīng)常需要遠(yuǎn)程客戶的服務(wù)器,但是并不是所有服務(wù)器都能開外網(wǎng)端口,使用向日葵等軟件終究還是不太方便,于是找了很多工具,包括zerotier 等,但是由于服務(wù)器在國外等有時候還不同,

于是開始自己想辦法研究一個屬于自己的組網(wǎng)工具,最后找到snltty大佬的 https://github.com/snltty/p2p-tunnel ,學(xué)習(xí)后發(fā)現(xiàn)是基于tun2socks實現(xiàn)的,

tun2socks 的優(yōu)點是 把虛擬網(wǎng)卡的數(shù)據(jù)都打包到socket代理了,但是過濾了ping (ICmp)的包,他自行返回了 成功,這不是我要的效果

于是看了一下tun2socks 的實現(xiàn),是基于tun/tap實現(xiàn)的,于是研究了一下,手動基于tun/tap實現(xiàn)了一個簡易的

核心代碼

[SupportedOSPlatform("windows")]

 public class WinTunDriveHostedService : TunDriveHostedService

 {

     private readonly static string DriverPath = AppDomain.CurrentDomain.BaseDirectory + "Drivers";

     private const string AdapterKey = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}";

     private const string ConnectionKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}";



     public const int TAP_WIN_IOCTL_GET_MAC = 1;

     public const int TAP_WIN_IOCTL_GET_VERSION = 2;

     public const int TAP_WIN_IOCTL_GET_MTU = 3;

     public const int TAP_WIN_IOCTL_GET_INFO = 4;

     public const int TAP_WIN_IOCTL_CONFIG_POINT_TO_POINT = 5;

     public const int TAP_WIN_IOCTL_SET_MEDIA_STATUS = 6;

     public const int TAP_WIN_IOCTL_CONFIG_DHCP_MASQ = 7;

     public const int TAP_WIN_IOCTL_GET_LOG_LINE = 8;

     public const int TAP_WIN_IOCTL_CONFIG_DHCP_SET_OPT = 9;

     public const int TAP_WIN_IOCTL_CONFIG_TUN = 10;


     public const uint FILE_ATTRIBUTE_SYSTEM = 0x4;

     public const uint FILE_FLAG_OVERLAPPED = 0x40000000;

     public const uint METHOD_BUFFERED = 0;

     public const uint FILE_ANY_ACCESS = 0;

     public const uint FILE_DEVICE_UNKNOWN = 0x22;

     public WinTunDriveHostedService(IOptions<TunDriveConfig> tunDriveConfigOptions, ILogger<WinTunDriveHostedService> logger) : base(tunDriveConfigOptions, logger)

     {

     }

     [DllImport("Kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]

     public static extern bool DeviceIoControl(SafeHandle device, uint IoControlCode, IntPtr InBuffer, uint InBufferSize, IntPtr OutBuffer, uint OutBufferSize, ref uint BytesReturned, IntPtr Overlapped);



     protected override FileStream OpenDrive()

     {

         var className = InstallOrGetClassNameDrive();

         var safeFileHandle = System.IO.File.OpenHandle($@"\\.\\Global\\{className}.tap", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, FileOptions.Asynchronous);

         return new FileStream(safeFileHandle, FileAccess.ReadWrite, 1500);

     }

     protected virtual string InstallOrGetClassNameDrive()

     {

         using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(ConnectionKey))

         {

             var names = registryKey.GetSubKeyNames();

             foreach (var name in names)

             {

                 using (var connectionRegistryKey = registryKey.OpenSubKey(name).OpenSubKey("Connection"))

                 {

                     if (connectionRegistryKey != null && connectionRegistryKey.GetValue("Name").ToString() == TunDriveConfig.TunDriveName)

                     {

                         return name;

                     }

                 }

             }


             Directory.CreateDirectory(DriverPath);

             ZipArchive zipArchive = new ZipArchive(typeof(WinTunDriveHostedService).Assembly.GetManifestResourceStream($"RemoteNetwork.{(Environment.Is64BitOperatingSystem ? "amd64" : "i386")}.zip"), ZipArchiveMode.Read);

             foreach (ZipArchiveEntry entry in zipArchive.Entries)

             {

                 entry.ExtractToFile(Path.Combine(DriverPath, entry.FullName), overwrite: true);

             }

             StartProcess(Path.Combine(DriverPath, "tapinstall.exe"), $"install OemVista.inf TAP0901", "runas", DriverPath);

             foreach (var name in registryKey.GetSubKeyNames())

             {

                 if (!names.Contains(name))

                 {

                     using (var connectionRegistryKey = registryKey.OpenSubKey(name).OpenSubKey("Connection"))

                     {

                         if (connectionRegistryKey != null)

                         {

                             StartProcess("netsh", @$"interface set interface name=""{connectionRegistryKey.GetValue("Name")}"" newname=""{TunDriveConfig.TunDriveName}""");

                             return name;

                         }

                     }

                 }

             }

             return string.Empty;

         }

     }

     private static int ParseIP(string address)

     {

         byte[] addressBytes = address.Split('.').Select(s => byte.Parse(s)).ToArray();

         return addressBytes[0] | (addressBytes[1] << 8) | (addressBytes[2] << 16) | (addressBytes[3] << 24);

     }

     protected override void ConfigIP(string ip, string netmask)

     {

         StartProcess("netsh", $"interface ip set address name=\"{TunDriveConfig.TunDriveName}\" source=static addr={ip} mask={netmask} gateway=none");

         IntPtr intPtr = Marshal.AllocHGlobal(12);

         Marshal.WriteInt32(intPtr, 0, ParseIP(ip));

         Marshal.WriteInt32(intPtr, 4, 0);

         Marshal.WriteInt32(intPtr, 8,0);

         uint lpBytesReturned = 0;

         bool result = DeviceIoControl(TunStream.SafeFileHandle, 2228264, intPtr, 12u, intPtr, 12u, ref lpBytesReturned, IntPtr.Zero);

         Marshal.FreeHGlobal(intPtr);

     }

     private static uint CTL_CODE(uint iDeviceType, uint iFunction, uint iMethod, uint iAccess)

     {

         return ((iDeviceType << 16) | (iAccess << 14) | (iFunction << 2) | iMethod);

     }

     public override bool ConnectionState(bool connection)

     {

         uint Length = 0;

         IntPtr cconfig = Marshal.AllocHGlobal(4);

         Marshal.WriteInt32(cconfig, connection ? 1 : 0);


         var b = DeviceIoControl(TunStream.SafeFileHandle, CTL_CODE(FILE_DEVICE_UNKNOWN, TAP_WIN_IOCTL_SET_MEDIA_STATUS, METHOD_BUFFERED, FILE_ANY_ACCESS), cconfig, 4, cconfig, 4, ref Length, IntPtr.Zero);

         StartProcess("netsh", $"netsh interface ipv4 set subinterface \"{TunDriveConfig.TunDriveName}\" mtu=\"1400\" store=persistent");

         return b;

     }

 }

liunx 核心代碼

public class TunNetWorkFrameHostedService : BackgroundService

{

    private  readonly string exchangeHostName = "";

    private readonly int P2PPort = 61000;

    protected readonly ILogger<TunNetWorkFrameHostedService> _logger;

    public static TunNetWorkFrameHostedService Instance { get; private set; }

    private readonly UdpClient udpClient;

    private readonly System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(0, 0);

    public TunNetWorkFrameHostedService(ILogger<TunNetWorkFrameHostedService> logger, IOptions<TunDriveConfig> tunDriveConfigOptions)

    {

        exchangeHostName = tunDriveConfigOptions.Value.DataExchangeHostName;

        _logger = logger;

        Instance = this;

        udpClient = new UdpClient(0); if (Environment.OSVersion.Platform == PlatformID.Win32NT)

        {

            const int SIP_UDP_CONNRESET = -1744830452;

            udpClient.Client.IOControl(SIP_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);

        }

    }



    protected override async Task ExecuteAsync(CancellationToken stoppingToken)

    {

        udpClient.BeginReceive(ReceiveCallback, udpClient);

        while (!stoppingToken.IsCancellationRequested)

        {

            await udpClient.SendAsync(TunDriveHostedService.Instance.Id, exchangeHostName, P2PPort, stoppingToken).ConfigureAwait(false);

            await Task.Delay(1000*30, stoppingToken).ConfigureAwait(false);

        }

    }

    void ReceiveCallback(IAsyncResult ar)

    {

        System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(0, 0);

        byte[] bytes = null;

        try

        {


            bytes = udpClient.EndReceive(ar, ref remoteEndPoint);


        }

        finally

        {

            udpClient.BeginReceive(ReceiveCallback, udpClient);

        }

        if (bytes.Length == 4)

        {

            return;

        }

        if (bytes.Length == 5)

        {

            if (bytes[0] == 2)

            {

                P2PUDPSocketHostedService.Instance.TestP2P(bytes.Skip(1).ToArray(),false);

            }

            return;

        }


        TunDriveHostedService.Instance.WriteFrameBuffer(bytes);

    }

    public virtual async Task WriteFrameBufferAsync(Memory<byte> buffer, CancellationToken stoppingToken)

    {

        var destId = BitConverter.ToInt32(buffer.Slice(16, 4).ToArray(), 0);


       var tunNetWorkFrameSend= P2PUDPSocketHostedService.Instance.GetP2PClient(buffer.Slice(16, 4).ToArray());

        if (tunNetWorkFrameSend != null)

        {

            await tunNetWorkFrameSend.SendAsync(buffer, stoppingToken).ConfigureAwait(false);

            return;

        }

        var bytes = new byte[buffer.Length + 8];

        buffer.Slice(12, 8).CopyTo(bytes);

        Array.Copy(buffer.ToArray(), 0,bytes,8,buffer.Length);

        await udpClient.SendAsync(bytes, exchangeHostName, P2PPort, stoppingToken).ConfigureAwait(false);

        //var destId = BitConverter.ToInt32(buffer.Slice(16, 4).ToArray(), 0);// string.Join(".", buffer.Slice(16, 4).ToArray());// span[16] << 24 | span[17] << 16 | span[18] << 8 | span[19];

        //var sourceId = BitConverter.ToInt32(buffer.Slice(12, 4).ToArray(), 0);

        //_logger.LogInformation($"{sourceId} 發(fā)送到{destId}");

    }

    /// <summary>

    /// 發(fā)送打洞請求

    /// </summary>

    /// <param name="destId"></param>

    /// <param name="stoppingToken"></param>

    /// <returns></returns>

    public virtual async Task SendP2PRequestAsync(byte[] destId, CancellationToken stoppingToken)

    {

        using (MemoryStream memoryStream = new MemoryStream()) {

            memoryStream.Write(TunDriveHostedService.Instance.Id);

            memoryStream.Write(destId);

            memoryStream.WriteByte(2);

            memoryStream.Write(TunDriveHostedService.Instance.Id);

            await udpClient.SendAsync(memoryStream.ToArray(), exchangeHostName, P2PPort, stoppingToken).ConfigureAwait(false);

        }


    }

}

以下是遠(yuǎn)程桌面的效果

客戶端運(yùn)行

 打洞成功

 測速

 

代碼地址

https://github.com/hn-lyf/RemoteNetwork

測試客戶端

 

 https://files.cnblogs.com/files/dotnet-org-cn/linux-x64.zip?t=1717937932&download=true

https://files.cnblogs.com/files/dotnet-org-cn/win-x64.zip?t=1717937932&download=true

https://files.cnblogs.com/files/dotnet-org-cn/win-x86.zip?t=1717937932&download=true



該文章在 2024/6/11 9:27:44 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊、財務(wù)費(fèi)用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved