mirror of
https://github.com/netchx/netch.git
synced 2026-03-14 17:43:18 +08:00
Update TUNController (tun2socks.bin)
This commit is contained in:
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -11,12 +11,13 @@ using Netch.Models;
|
||||
using Netch.Servers.Socks5;
|
||||
using Netch.Utils;
|
||||
using Vanara.PInvoke;
|
||||
using static Netch.Controllers.TUNInterop;
|
||||
using static Vanara.PInvoke.IpHlpApi;
|
||||
using static Vanara.PInvoke.Ws2_32;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TUNController : Guard, IModeController
|
||||
public class TUNController : IModeController
|
||||
{
|
||||
private readonly List<string> _directIPs = new();
|
||||
|
||||
@@ -29,56 +30,95 @@ namespace Netch.Controllers
|
||||
/// <summary>
|
||||
/// 本地 DNS 服务控制器
|
||||
/// </summary>
|
||||
public DNSController DNSController = new();
|
||||
public readonly DNSController DNSController = new();
|
||||
|
||||
protected override IEnumerable<string> StartedKeywords { get; set; } = new[] {"Started"};
|
||||
|
||||
protected override IEnumerable<string> StoppedKeywords { get; set; } = new List<string>();
|
||||
|
||||
public override string MainFile { get; protected set; } = "tun2socks.exe";
|
||||
|
||||
protected override Encoding InstanceOutputEncoding { get; } = Encoding.UTF8;
|
||||
|
||||
public override string Name { get; } = "tun2socks";
|
||||
public string Name { get; } = "tun2socks";
|
||||
|
||||
private readonly OutboundAdapter _outboundAdapter = new();
|
||||
private IAdapter _tunAdapter = null!;
|
||||
private readonly TUNInterop _tunInterop = new();
|
||||
|
||||
public void Start(in Mode mode)
|
||||
{
|
||||
var server = MainController.Server!;
|
||||
_serverAddresses = DnsUtils.Lookup(server.Hostname)!; // server address have been cached when MainController.Start
|
||||
|
||||
var parameter = new WinTun2socksParameter();
|
||||
_tunInterop.Dial(NameList.TYPE_ADAPMTU, "1500");
|
||||
_tunInterop.Dial(NameList.TYPE_BYPBIND, "10.0.0.100");
|
||||
_tunInterop.Dial(NameList.TYPE_BYPLIST, "disabled");
|
||||
|
||||
|
||||
#region Server
|
||||
|
||||
_tunInterop.Dial(NameList.TYPE_TCPREST, "");
|
||||
_tunInterop.Dial(NameList.TYPE_TCPTYPE, "Socks5");
|
||||
|
||||
_tunInterop.Dial(NameList.TYPE_UDPREST, "");
|
||||
_tunInterop.Dial(NameList.TYPE_UDPTYPE, "Socks5");
|
||||
|
||||
if (server is Socks5 socks5)
|
||||
{
|
||||
parameter.hostname = $"{server.AutoResolveHostname()}:{server.Port}";
|
||||
_tunInterop.Dial(NameList.TYPE_TCPHOST, $"{server.AutoResolveHostname()}:{server.Port}");
|
||||
|
||||
_tunInterop.Dial(NameList.TYPE_UDPHOST, $"{server.AutoResolveHostname()}:{server.Port}");
|
||||
|
||||
if (socks5.Auth())
|
||||
{
|
||||
parameter.username = socks5.Username!;
|
||||
parameter.password = socks5.Password!;
|
||||
_tunInterop.Dial(NameList.TYPE_TCPUSER, socks5.Username!);
|
||||
_tunInterop.Dial(NameList.TYPE_TCPPASS, socks5.Password!);
|
||||
|
||||
_tunInterop.Dial(NameList.TYPE_UDPUSER, socks5.Username!);
|
||||
_tunInterop.Dial(NameList.TYPE_UDPPASS, socks5.Password!);
|
||||
}
|
||||
}
|
||||
else
|
||||
parameter.hostname = $"127.0.0.1:{Global.Settings.Socks5LocalPort}";
|
||||
{
|
||||
_tunInterop.Dial(NameList.TYPE_TCPHOST, $"127.0.0.1:{Global.Settings.Socks5LocalPort}");
|
||||
|
||||
_tunInterop.Dial(NameList.TYPE_UDPHOST, $"127.0.0.1:{Global.Settings.Socks5LocalPort}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DNS
|
||||
|
||||
List<string> dns;
|
||||
if (Global.Settings.WinTUN.UseCustomDNS)
|
||||
{
|
||||
dns = Global.Settings.WinTUN.DNS.Any() ? Global.Settings.WinTUN.DNS : Global.Settings.WinTUN.DNS = new List<string> {"1.1.1.1"};
|
||||
}
|
||||
else
|
||||
{
|
||||
MainController.PortCheck(53, "DNS");
|
||||
DNSController.Start();
|
||||
dns = new List<string> {"127.0.0.1"};
|
||||
}
|
||||
|
||||
_tunInterop.Dial(NameList.TYPE_DNSADDR, DnsUtils.Join(dns));
|
||||
|
||||
#endregion
|
||||
|
||||
Console.WriteLine("tun2socks init");
|
||||
_tunInterop.Init();
|
||||
|
||||
MainFile = "tun2socks.exe";
|
||||
StartInstanceAuto(parameter.ToString());
|
||||
_tunAdapter = new TunAdapter();
|
||||
|
||||
NativeMethods.CreateUnicastIP((int)AddressFamily.InterNetwork, Global.Settings.WinTUN.Address, 24, _tunAdapter.InterfaceIndex);
|
||||
NativeMethods.CreateUnicastIP((int) AddressFamily.InterNetwork, Global.Settings.WinTUN.Address, 24, _tunAdapter.InterfaceIndex);
|
||||
SetupRouteTable(mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// TUN/TAP停止
|
||||
/// </summary>
|
||||
public override void Stop()
|
||||
public void Stop()
|
||||
{
|
||||
var tasks = new[]
|
||||
{
|
||||
Task.Run(StopInstance),
|
||||
Task.Run(() =>
|
||||
{
|
||||
_tunInterop.Free();
|
||||
// _tunInterop.Unload();
|
||||
}),
|
||||
Task.Run(ClearRouteTable),
|
||||
Task.Run(DNSController.Stop)
|
||||
};
|
||||
@@ -168,20 +208,6 @@ namespace Netch.Controllers
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TestFakeDNS()
|
||||
{
|
||||
try
|
||||
{
|
||||
InitInstance("-h");
|
||||
Instance!.Start();
|
||||
return Instance.StandardError.ReadToEnd().Contains("-fakeDns");
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#region Package
|
||||
|
||||
private void RouteAction(Action action, in IEnumerable<string> ipNetworks, RouteType routeType, int metric = 0)
|
||||
@@ -225,22 +251,19 @@ namespace Netch.Controllers
|
||||
switch (action)
|
||||
{
|
||||
case Action.Create:
|
||||
|
||||
result = NativeMethods.CreateRoute((int)AddressFamily.InterNetwork, network, cidr, gateway, index, metric);
|
||||
#if DEBUG
|
||||
Console.WriteLine($"CreateRoute(\"{network}\", {cidr}, \"{gateway}\", {index}, {metric})");
|
||||
#endif
|
||||
result = NativeMethods.CreateRoute((int) AddressFamily.InterNetwork, network, cidr, gateway, index, metric);
|
||||
ipList.Add(ipNetwork);
|
||||
break;
|
||||
case Action.Delete:
|
||||
result = NativeMethods.DeleteRoute((int)AddressFamily.InterNetwork, network, cidr, gateway, index, metric);
|
||||
result = NativeMethods.DeleteRoute((int) AddressFamily.InterNetwork, network, cidr, gateway, index, metric);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(action), action, null);
|
||||
}
|
||||
|
||||
Logging.Debug($"{action}Route(\"{network}\", {cidr}, \"{gateway}\", {index}, {metric})");
|
||||
if (!result)
|
||||
Logging.Warning($"Failed to {action} Route on {routeType} Adapter: {ipNetwork} metric {metric}");
|
||||
Logging.Warning($"Failed to invoke {action}Route(\"{network}\", {cidr}, \"{gateway}\", {index}, {metric})");
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -257,45 +280,6 @@ namespace Netch.Controllers
|
||||
Delete
|
||||
}
|
||||
|
||||
[Verb]
|
||||
public class Tap2SocksParameter : ParameterBase
|
||||
{
|
||||
public string? proxyServer { get; set; }
|
||||
|
||||
public string? tunAddr { get; set; }
|
||||
|
||||
public string? tunMask { get; set; }
|
||||
|
||||
public string? tunGw { get; set; }
|
||||
|
||||
public string? tunDns { get; set; }
|
||||
|
||||
public string? tunName { get; set; }
|
||||
|
||||
public bool fakeDns { get; set; }
|
||||
}
|
||||
|
||||
[Verb]
|
||||
class WinTun2socksParameter : ParameterBase
|
||||
{
|
||||
public string? bind { get; set; } = "10.0.0.100";
|
||||
|
||||
[Quote]
|
||||
public string? list { get; set; } = "disabled";
|
||||
|
||||
public string? hostname { get; set; }
|
||||
|
||||
[Optional]
|
||||
public string? username { get; set; }
|
||||
|
||||
[Optional]
|
||||
public string? password { get; set; }
|
||||
|
||||
public string? dns { get; set; } = "1.1.1.1:53";
|
||||
|
||||
public int? mtu { get; set; } = 1500;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
74
Netch/Controllers/TUNInterop.cs
Normal file
74
Netch/Controllers/TUNInterop.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Netch.Utils;
|
||||
|
||||
namespace Netch.Controllers
|
||||
{
|
||||
public class TUNInterop
|
||||
{
|
||||
public enum NameList
|
||||
{
|
||||
TYPE_BYPBIND,
|
||||
TYPE_BYPLIST,
|
||||
TYPE_DNSADDR,
|
||||
TYPE_ADAPMTU,
|
||||
TYPE_TCPREST,
|
||||
TYPE_TCPTYPE,
|
||||
TYPE_TCPHOST,
|
||||
TYPE_TCPUSER,
|
||||
TYPE_TCPPASS,
|
||||
TYPE_TCPMETH,
|
||||
TYPE_TCPPROT,
|
||||
TYPE_TCPPRPA,
|
||||
TYPE_TCPOBFS,
|
||||
TYPE_TCPOBPA,
|
||||
TYPE_UDPREST,
|
||||
TYPE_UDPTYPE,
|
||||
TYPE_UDPHOST,
|
||||
TYPE_UDPUSER,
|
||||
TYPE_UDPPASS,
|
||||
TYPE_UDPMETH,
|
||||
TYPE_UDPPROT,
|
||||
TYPE_UDPPRPA,
|
||||
TYPE_UDPOBFS,
|
||||
TYPE_UDPOBPA
|
||||
}
|
||||
|
||||
public bool Dial(NameList name, string value)
|
||||
{
|
||||
Logging.Debug($"Dial {name} {value}");
|
||||
return tun_dial(name, Encoding.UTF8.GetBytes(value));
|
||||
}
|
||||
|
||||
public bool Init()
|
||||
{
|
||||
return tun_init();
|
||||
}
|
||||
|
||||
public bool Free()
|
||||
{
|
||||
return tun_free();
|
||||
}
|
||||
|
||||
private const string tun2socks_bin = "tun2socks.bin";
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool tun_dial(NameList name, byte[] value);
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool tun_init();
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool tun_free();
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern ulong tun_luid();
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern ulong tun_getUP();
|
||||
|
||||
[DllImport(tun2socks_bin, CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern ulong tun_getDL();
|
||||
}
|
||||
}
|
||||
2
Netch/Forms/SettingForm.Designer.cs
generated
2
Netch/Forms/SettingForm.Designer.cs
generated
@@ -549,7 +549,6 @@ namespace Netch.Forms
|
||||
this.TUNTAPGroupBox.TabIndex = 0;
|
||||
this.TUNTAPGroupBox.TabStop = false;
|
||||
this.TUNTAPGroupBox.Text = "TUN/TAP";
|
||||
this.TUNTAPGroupBox.Visible = false;
|
||||
//
|
||||
// TUNTAPAddressLabel
|
||||
//
|
||||
@@ -584,6 +583,7 @@ namespace Netch.Forms
|
||||
this.TUNTAPNetmaskTextBox.Size = new System.Drawing.Size(294, 21);
|
||||
this.TUNTAPNetmaskTextBox.TabIndex = 3;
|
||||
this.TUNTAPNetmaskTextBox.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
|
||||
this.TUNTAPNetmaskTextBox.Visible = false;
|
||||
//
|
||||
// TUNTAPGatewayLabel
|
||||
//
|
||||
|
||||
@@ -13,17 +13,18 @@ namespace Netch.Models
|
||||
public TunAdapter()
|
||||
{
|
||||
AdapterId = AdapterUtils.GetAdapterId(ComponentIdWintun) ?? throw new Exception("wintun adapter not found");
|
||||
|
||||
NetworkInterface = NetworkInterface.GetAllNetworkInterfaces().First(i => i.Id == AdapterId);
|
||||
InterfaceIndex = NetworkInterface.GetIPProperties().GetIPv4Properties().Index;
|
||||
Logging.Info($"TAP 适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {InterfaceIndex}");
|
||||
Gateway = IPAddress.Parse(Global.Settings.WinTUN.Gateway);
|
||||
|
||||
Logging.Info($"WinTUN 适配器:{NetworkInterface.Name} {NetworkInterface.Id} {NetworkInterface.Description}, index: {InterfaceIndex}");
|
||||
}
|
||||
|
||||
public string AdapterId { get; set; }
|
||||
|
||||
public int InterfaceIndex { get; }
|
||||
|
||||
public IPAddress Gateway { get; } = IPAddress.Parse("100.64.0.1");
|
||||
public IPAddress Gateway { get; }
|
||||
|
||||
public NetworkInterface NetworkInterface { get; }
|
||||
}
|
||||
|
||||
2
binaries
2
binaries
Submodule binaries updated: 0535f7b310...85be39db26
Reference in New Issue
Block a user