Refactors

This commit is contained in:
ChsBuffer
2021-07-16 05:24:36 +08:00
parent 98f3218e28
commit a62f694908
19 changed files with 114 additions and 103 deletions

View File

@@ -15,7 +15,7 @@ namespace Netch.Controllers
await FreeAsync();
}
public void Start()
public async Task StartAsync()
{
MainController.PortCheck(Global.Settings.AioDNS.ListenPort, "DNS");
@@ -28,7 +28,7 @@ namespace Netch.Controllers
Dial(NameList.TYPE_CDNS, $"{aioDnsConfig.ChinaDNS}");
Dial(NameList.TYPE_ODNS, $"{aioDnsConfig.OtherDNS}");
if (!Init())
if (!await InitAsync())
throw new Exception("AioDNS start failed.");
}
}

View File

@@ -71,7 +71,7 @@ namespace Netch.Controllers
{
State = State.Starting;
_logFileStream = File.Open(LogPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read);
_logFileStream = File.Open(LogPath, FileMode.Create, FileAccess.Write, FileShare.Read);
_logStreamWriter = new StreamWriter(_logFileStream) { AutoFlush = true };
Instance.StartInfo.Arguments = argument;

View File

@@ -62,6 +62,7 @@ namespace Netch.Controllers
throw;
default:
Log.Error(e, "Unhandled Exception When Start MainController");
Utils.Utils.Open(Constants.LogFile);
throw new MessageException($"{i18N.Translate("Unhandled Exception")}\n{e.Message}");
}
}

View File

@@ -42,12 +42,17 @@ namespace Netch.Controllers
}
if (output.IsNullOrWhiteSpace())
if (!error.IsNullOrWhiteSpace())
{
if (error.IsNullOrWhiteSpace())
{
var errorFirst = error.GetLines().First();
return (errorFirst.SplitTrimEntries(':').Last(), null, null);
Log.Warning("NTT no output");
return (null, null, null);
}
var errorFirst = error.GetLines().First();
return (errorFirst.SplitTrimEntries(':').Last(), null, null);
}
foreach (var line in output.Split('\n'))
{
var str = line.SplitTrimEntries(':');

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
@@ -38,10 +39,10 @@ namespace Netch.Controllers
var outboundNetworkInterface = NetworkInterfaceUtils.GetBest();
var argument = new StringBuilder($@"-i \Device\NPF_{outboundNetworkInterface.Id}");
if (_server is Socks5 socks5 && !socks5.Auth())
if (_server is Socks5Bridge socks5)
argument.Append($" --destination {await socks5.AutoResolveHostnameAsync()}:{socks5.Port}");
else
argument.Append($" --destination 127.0.0.1:{Global.Settings.Socks5LocalPort}");
Trace.Assert(false);
argument.Append($" {_mode.GetRules().FirstOrDefault() ?? "-P n"}");
await StartGuardAsync(argument.ToString());
@@ -77,10 +78,11 @@ namespace Netch.Controllers
if (new FileInfo(LogPath).Length == 0)
{
Task.Run(() =>
{
Thread.Sleep(1000);
Utils.Utils.Open("https://github.com/zhxie/pcap2socks#dependencies");
}).Forget();
{
Thread.Sleep(1000);
Utils.Utils.Open("https://github.com/zhxie/pcap2socks#dependencies");
})
.Forget();
throw new MessageException("Pleases install pcap2socks's dependency");
}

View File

@@ -86,7 +86,7 @@ namespace Netch.Controllers
}
else
{
_aioDnsController.Start();
await _aioDnsController.StartAsync();
Dial(NameList.TYPE_DNSADDR, $"127.0.0.1:{Global.Settings.AioDNS.ListenPort}");
}

View File

@@ -67,7 +67,7 @@ namespace Netch.Controllers
else
Log.Error(e, "获取新版本异常");
NewVersionFoundFailed?.Invoke(null, new EventArgs());
NewVersionFoundFailed?.Invoke(null, EventArgs.Empty);
}
}

View File

@@ -53,7 +53,8 @@ namespace Netch.Forms
private void AddAddServerToolStripMenuItems()
{
foreach (var serversUtil in ServerHelper.ServerUtils.Where(i => !string.IsNullOrEmpty(i.FullName)))
foreach (var serversUtil in ServerHelper.ServerUtilDictionary.Values.OrderBy(i => i.Priority)
.Where(i => !string.IsNullOrEmpty(i.FullName)))
{
var fullName = serversUtil.FullName;
var control = new ToolStripMenuItem
@@ -636,9 +637,6 @@ namespace Netch.Forms
return;
}
if (!server.Valid())
return;
Hide();
ServerHelper.GetUtilByTypeName(server.Type).Edit(server);
LoadServers();
@@ -679,9 +677,6 @@ namespace Netch.Forms
return;
}
if (!server.Valid())
return;
try
{
//听说巨硬BUG经常会炸所以Catch一下 :D

View File

@@ -15,6 +15,11 @@ namespace Netch.Interops
return aiodns_dial(name, Encoding.UTF8.GetBytes(value));
}
public static async Task<bool> InitAsync()
{
return await Task.Run(Init).ConfigureAwait(false);
}
public static async Task FreeAsync()
{
await Task.Run(Free).ConfigureAwait(false);

View File

@@ -118,19 +118,6 @@ namespace Netch.Models
return Global.Settings.ResolveServerHostname ? (await DnsUtils.LookupAsync(server.Hostname))!.ToString() : server.Hostname;
}
public static bool Valid(this Server server)
{
try
{
ServerHelper.GetTypeByTypeName(server.Type);
return true;
}
catch
{
return false;
}
}
public static bool IsInGroup(this Server server)
{
return server.Group is not Constants.DefaultGroup;

View File

@@ -51,7 +51,9 @@ namespace Netch
Directory.CreateDirectory(item);
// 加载配置
#pragma warning disable VSTHRD002
Configuration.LoadAsync().Wait();
#pragma warning restore VSTHRD002
if (!SingleInstance.IsFirstInstance)
{

View File

@@ -53,69 +53,68 @@ namespace Netch.Utils
var counterLock = new object();
//int sent = 0;
//var processList = Process.GetProcessesByName(ProcessName).Select(p => p.Id).ToHashSet();
var instances = new List<Process>();
var processes = new List<Process>();
switch (MainController.ServerController)
{
case null:
break;
case Guard guard:
instances.Add(guard.Instance);
processes.Add(guard.Instance);
break;
}
if (!instances.Any())
if (!processes.Any())
switch (MainController.ModeController)
{
case null:
break;
case NFController:
instances.Add(Process.GetCurrentProcess());
case NFController or TUNController:
processes.Add(Process.GetCurrentProcess());
break;
case Guard guard:
instances.Add(guard.Instance);
processes.Add(guard.Instance);
break;
}
var processList = instances.Select(instance => instance.Id).ToHashSet();
var pidHastSet = processes.Select(instance => instance.Id).ToHashSet();
Log.Information("流量统计进程: {Processes}", string.Join(',', instances.Select(v => $"({v.Id}){v.ProcessName}")));
Log.Information("流量统计进程: {Processes}", string.Join(',', processes.Select(v => $"({v.Id}){v.ProcessName}")));
received = 0;
if (!instances.Any())
if (!processes.Any())
return;
Global.MainForm.BandwidthState(true);
Task.Run(() =>
{
tSession = new TraceEventSession("KernelAndClrEventsSession");
tSession.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP);
//这玩意儿上传和下载得到的data是一样的:)
//所以暂时没办法区分上传下载流量
tSession.Source.Kernel.TcpIpRecv += data =>
{
if (processList.Contains(data.ProcessID))
lock (counterLock)
received += (ulong)data.size;
tSession = new TraceEventSession("KernelAndClrEventsSession");
tSession.EnableKernelProvider(KernelTraceEventParser.Keywords.NetworkTCPIP);
// Debug.WriteLine($"TcpIpRecv: {ToByteSize(data.size)}");
};
//这玩意儿上传和下载得到的data是一样的:)
//所以暂时没办法区分上传下载流量
tSession.Source.Kernel.TcpIpRecv += data =>
{
if (pidHastSet.Contains(data.ProcessID))
lock (counterLock)
received += (ulong)data.size;
tSession.Source.Kernel.UdpIpRecv += data =>
{
if (processList.Contains(data.ProcessID))
lock (counterLock)
received += (ulong)data.size;
// Debug.WriteLine($"TcpIpRecv: {ToByteSize(data.size)}");
};
// Debug.WriteLine($"UdpIpRecv: {ToByteSize(data.size)}");
};
tSession.Source.Kernel.UdpIpRecv += data =>
{
if (pidHastSet.Contains(data.ProcessID))
lock (counterLock)
received += (ulong)data.size;
tSession.Source.Process();
}).Forget();
// Debug.WriteLine($"UdpIpRecv: {ToByteSize(data.size)}");
};
tSession.Source.Process();
})
.Forget();
while (Global.MainForm.State != State.Stopped)
{

View File

@@ -45,6 +45,8 @@ namespace Netch.Utils
return;
}
await using var _ = await _lock.ReadLockAsync();
if (await LoadCoreAsync(FileFullName))
return;

View File

@@ -1,8 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
using Serilog;
@@ -14,13 +16,23 @@ namespace Netch.Utils
/// 缓存
/// </summary>
private static readonly Hashtable Cache = new();
private static readonly Hashtable Cache6 = new();
public static async Task<IPAddress?> LookupAsync(string hostname, int timeout = 3000)
public static async Task<IPAddress?> LookupAsync(string hostname, AddressFamily inet = AddressFamily.InterNetwork, int timeout = 3000)
{
try
{
if (Cache.Contains(hostname))
return Cache[hostname] as IPAddress;
if (inet == AddressFamily.InterNetwork)
{
if (Cache.Contains(hostname))
return Cache[hostname] as IPAddress;
}
else
{
Trace.Assert(inet == AddressFamily.InterNetworkV6);
if (Cache6.Contains(hostname))
return Cache6[hostname] as IPAddress;
}
var task = Dns.GetHostAddressesAsync(hostname);
@@ -28,14 +40,18 @@ namespace Netch.Utils
if (resTask == task)
{
var result = await task;
var addresses = await task;
if (result.Length == 0)
var result = addresses.FirstOrDefault(i => i.AddressFamily == inet);
if (result == null)
return null;
Cache.Add(hostname, result[0]);
if (inet == AddressFamily.InterNetwork)
Cache.Add(hostname, result);
else
Cache6.Add(hostname, result);
return result[0];
return result;
}
return null;
@@ -55,6 +71,7 @@ namespace Netch.Utils
public static void ClearCache()
{
Cache.Clear();
Cache6.Clear();
}
public static IEnumerable<string> Split(string dns)

View File

@@ -14,12 +14,16 @@ namespace Netch.Utils
{
public static NetworkInterface GetBest(AddressFamily addressFamily = AddressFamily.InterNetwork)
{
var ipAddress = addressFamily switch
string ipAddress;
if (addressFamily == AddressFamily.InterNetwork)
{
AddressFamily.InterNetwork => "114.114.114.114",
AddressFamily.InterNetworkV6 => throw new NotImplementedException(),
_ => throw new ArgumentOutOfRangeException(nameof(addressFamily), addressFamily, null)
};
ipAddress = "114.114.114.114";
}
else
{
Trace.Assert(addressFamily == AddressFamily.InterNetworkV6);
throw new NotImplementedException();
}
if (PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0), 0, out var route) != 0)
throw new MessageException("GetBestRoute 搜索失败");

View File

@@ -4,6 +4,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Windows.Win32;
using Windows.Win32.NetworkManagement.IpHelper;
@@ -31,13 +32,13 @@ namespace Netch.Utils
}
}
internal static IEnumerable<Process> GetProcessByUsedTcpPort(ushort port, ADDRESS_FAMILY inet = ADDRESS_FAMILY.AF_INET)
internal static IEnumerable<Process> GetProcessByUsedTcpPort(ushort port, AddressFamily inet = AddressFamily.InterNetwork)
{
if (port == 0)
throw new ArgumentOutOfRangeException();
if (inet is ADDRESS_FAMILY.AF_UNSPEC)
throw new ArgumentOutOfRangeException(nameof(inet));
if (inet != AddressFamily.InterNetwork)
Trace.Assert(inet == AddressFamily.InterNetworkV6);
var process = new List<Process>();
unsafe
@@ -50,9 +51,9 @@ namespace Netch.Utils
if ((err = PInvoke.GetExtendedTcpTable(tcpTable, ref size, false, (uint)inet, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_LISTENER, 0)) != 0)
throw new Win32Exception((int)err);
for (var i = 0; i < tcpTable->dwNumEntries; i++)
for (var i = 0; i < tcpTable -> dwNumEntries; i++)
{
var row = tcpTable->table.ReadOnlyItemRef(i);
var row = tcpTable -> table.ReadOnlyItemRef(i);
if (row.dwOwningPid is 0 or 4)
continue;

View File

@@ -16,6 +16,7 @@ namespace Netch.Utils
try
{
var type = ServerHelper.GetTypeByTypeName(jsonElement.GetProperty("Type").GetString()!);
// TODO replace with .NET 6 Deserialize from DOM
return (Server)JsonSerializer.Deserialize(jsonElement.GetRawText(), type)!;
}
catch

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
@@ -19,12 +20,7 @@ namespace Netch.Utils
.GetExportedTypes()
.Where(type => type.GetInterfaces().Contains(typeof(IServerUtil)));
ServerUtils = serversUtilsTypes.Select(t => (IServerUtil)Activator.CreateInstance(t)!).OrderBy(util => util.Priority);
}
public static Type GetTypeByTypeName(string typeName)
{
return ServerUtils.Single(i => i.TypeName.Equals(typeName)).ServerType;
ServerUtilDictionary = serversUtilsTypes.Select(t => (IServerUtil)Activator.CreateInstance(t)!).ToDictionary(util => util.TypeName);
}
#region Delay
@@ -118,27 +114,21 @@ namespace Netch.Utils
#region Handler
public static readonly IEnumerable<IServerUtil> ServerUtils;
public static Dictionary<string, IServerUtil> ServerUtilDictionary { get; set; }
public static IServerUtil GetUtilByTypeName(string typeName)
{
if (string.IsNullOrEmpty(typeName))
throw new ArgumentNullException();
return ServerUtils.Single(i => i.TypeName.Equals(typeName));
return ServerUtilDictionary[typeName];
}
public static IServerUtil GetUtilByFullName(string fullName)
public static IServerUtil? GetUtilByUriScheme(string scheme)
{
if (string.IsNullOrEmpty(fullName))
throw new ArgumentNullException();
return ServerUtils.Single(i => i.FullName.Equals(fullName));
return ServerUtilDictionary.Values.SingleOrDefault(i => i.UriScheme.Any(s => s.Equals(scheme)));
}
public static IServerUtil? GetUtilByUriScheme(string typeName)
public static Type GetTypeByTypeName(string typeName)
{
return ServerUtils.SingleOrDefault(i => i.UriScheme.Any(s => s.Equals(typeName)));
return GetUtilByTypeName(typeName).ServerType;
}
#endregion

View File

@@ -73,9 +73,9 @@ namespace Netch.Utils
return value.Split(separator, StringSplitOptions.RemoveEmptyEntries);
}
public static string? ValueOrDefault(this string? value)
public static string? ValueOrDefault(this string? value, string? defaultValue = default)
{
return string.IsNullOrWhiteSpace(value) ? null : value;
return string.IsNullOrWhiteSpace(value) ? defaultValue : value;
}
public static string[]? SplitOrDefault(this string? value)