组网的一些更新
12
.github/workflows/dotnet.yml
vendored
@@ -48,18 +48,12 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: '${{ secrets.ACTIONS_TOKEN }}'
|
||||
with:
|
||||
tag_name: v1.2.0.3
|
||||
release_name: v1.2.0.3.${{ steps.date.outputs.today }}
|
||||
tag_name: v1.2.0.4
|
||||
release_name: v1.2.0.4.${{ steps.date.outputs.today }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: |
|
||||
1. 重要更新
|
||||
2. 重写的虚拟网卡,不再依赖tun2socks,(仅windows、linux,暂时的)
|
||||
3. 虚拟网卡支持广播、点对网、网对网了
|
||||
4. 公开`linker.tun`库,可以nuget安装,将网卡集成到你的项目中
|
||||
5. webui显示设备区域,设备系统,及是否docker
|
||||
6. 服务器穿透支持端口范围
|
||||
7. 要更新服务器,要更新服务器,要更新服务器
|
||||
1. 测试中,不要更新
|
||||
|
||||
- name: upload win x64
|
||||
id: upload-win-x64
|
||||
|
@@ -14,6 +14,16 @@ sidebar_position: 1
|
||||
6. 打洞失败回退、这需要你中继部署服务器进行中继通信
|
||||
7. 易用的web管理页面
|
||||
|
||||
|
||||
:::danger[win10以下]
|
||||
|
||||
1. win7 或 win8 可能需要安装一些环境,才能运行
|
||||
2. <a href="https://aka.ms/vs/16/release/vc_redist.x64.exe" target="_blank">Microsoft Visual C++ 2015-2019 Redistributable </a>
|
||||
2. <a href="https://www.microsoft.com/download/details.aspx?id=47442" target="_blank">KB3063858 </a>
|
||||
|
||||
:::
|
||||
|
||||
|
||||
:::tip[加入组织]
|
||||
|
||||
<a href="https://jq.qq.com/?_wv=1027&k=ucoIVfz4" target="_blank">你可以加入QQ群:1121552990,可以申请一些免费的中继服务器 </a>
|
||||
|
@@ -8,8 +8,7 @@ sidebar_position: 1
|
||||
|
||||
1. 各个设备的`网卡IP`,不要一样,要同一网段,且不应该使用`1`、`255`
|
||||
2. 请使用 `10.0.0.0 - 10.255.255.255`、`172.16.0.0 - 172.31.255.255`、`192.168.0.0 - 192.168.255.255` 范围内的IP
|
||||
3. `局域网IP`,是选填的,可以不填,不懂是啥时,不要填、不要填、不要填
|
||||
4. 虽然支持UDP广播,但是UDP广播不会去主动连接所有设备,所以,你可以先 ping 以下对方,让两端相互连接
|
||||
3. 虽然支持UDP广播,但是UDP广播不会去主动连接所有设备,所以,你可以先 ping 以下对方,让两端相互连接
|
||||
:::
|
||||
|
||||
|
||||
@@ -17,20 +16,24 @@ sidebar_position: 1
|
||||
|
||||
在设备,虚拟网卡一栏,点击IP配置
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
开启网卡成功后,即可通过`虚拟IP`访问目标设备(当然,前提是能够打洞成功,或者中继成功)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
试一下能不能连接,第一次连接时,会尝试去打洞或中继,时间可能会比较久,耐心等待
|
||||

|
||||

|
||||
|
||||
## 2、点对网(局域网IP)
|
||||
## 2、点对网
|
||||
|
||||
:::tip[说明]
|
||||
:::danger[重要]
|
||||
你要确定你知道你在搞什么,如果只是简单的P2P通信,上面的内容已经够了,以下的东西不要看,不要看,不要看
|
||||
:::
|
||||
|
||||
:::tip[1、情况1,你的设备支持NAT转发时]
|
||||
|
||||
1. linux,已经自动添加NAT转发
|
||||
2. windows,你可以尝试在`powershell`运行 `Get-NetNat` 如果没有报错则可以正常使用,如果报错,那你可能需要打开`Hyper-V`才能使用点对网功能, `控制面板\程序\启用或关闭 Windows 功能`
|
||||
@@ -44,25 +47,36 @@ nat on en0 from 192.168.54.0/24 to any -> (en0)
|
||||
# 加载规则
|
||||
sudo pfctl -f /etc/pf.conf -e
|
||||
```
|
||||
3. 局域网IP,是你设备所在局域网的IP,不是虚拟网卡IP、不是虚拟网卡IP、不是虚拟网卡IP
|
||||
|
||||
:::
|
||||
|
||||
我这里,B端的局域网IP是 `192.168.1.35`
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
尝试连接 对方的局域网IP,或者局域网内其它设备(记得关闭防火墙,或者防火墙添加一条规则,允许ICMP通过)
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
:::tip[2、情况2,你的设备无法使用NAT转发时]
|
||||
|
||||
1. 你的设备无法使用NAT转发(一般出现在低版本windows下,win10以下),那你只能使用windows的端口转发功能来访问你当前设备局域网下的其它设备
|
||||
2. 按如下配置。当其它设备通过`192.168.54.2:12345` 访问时,将访问到你的局域网的`192.168.1.35:3389`
|
||||
|
||||

|
||||
|
||||
:::
|
||||
|
||||
|
||||
## 3、网对网
|
||||
|
||||
:::tip[说明]
|
||||
|
||||
1. 如果你把linker安装在路由器上,勾选我是网关即可
|
||||
1. 如果你把linker安装在路由器上,可以勾选
|
||||
2. 假设B端设置的`局域网IP`为`192.168.1.35/24`,那么在A端勾选此项,则A端下局域网内的所有设备都能通过`192.168.1.x`去访问B端局域网内的设备
|
||||
|
||||

|
||||

|
||||
|
||||
:::
|
||||
|
||||
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 150 KiB |
BIN
linker.doc.web/docs/4、通信功能/img/tun-add1.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
linker.doc.web/docs/4、通信功能/img/tun-forward.png
Normal file
After Width: | Height: | Size: 127 KiB |
BIN
linker.doc.web/docs/4、通信功能/img/tun-gateway.png
Normal file
After Width: | Height: | Size: 120 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
BIN
linker.doc.web/docs/4、通信功能/img/tun-local.png
Normal file
After Width: | Height: | Size: 125 KiB |
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 157 KiB |
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 154 KiB |
Before Width: | Height: | Size: 155 KiB After Width: | Height: | Size: 155 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 149 KiB |
Before Width: | Height: | Size: 49 KiB |
@@ -8,24 +8,26 @@ namespace linker.libs
|
||||
{
|
||||
public static string Windows(string arg, string[] commands)
|
||||
{
|
||||
return Execute("cmd.exe", arg, commands);
|
||||
return Execute("cmd.exe", arg, commands,out string error);
|
||||
}
|
||||
public static string PowerShell(string arg, string[] commands)
|
||||
public static string PowerShell(string arg, string[] commands, out string error)
|
||||
{
|
||||
error = string.Empty;
|
||||
if (IsPowerShellInstalled() == false)
|
||||
{
|
||||
error = "PowerShell is not installed";
|
||||
return string.Empty;
|
||||
}
|
||||
return Execute("powershell.exe", arg, commands);
|
||||
return Execute("powershell.exe", arg, commands,out error);
|
||||
}
|
||||
|
||||
public static string Linux(string arg, string[] commands)
|
||||
{
|
||||
return Execute("/bin/bash", arg, commands);
|
||||
return Execute("/bin/bash", arg, commands, out string error);
|
||||
}
|
||||
public static string Osx(string arg, string[] commands)
|
||||
{
|
||||
return Execute("/bin/bash", arg, commands);
|
||||
return Execute("/bin/bash", arg, commands, out string error);
|
||||
}
|
||||
|
||||
public static Process Execute(string fileName, string arg)
|
||||
@@ -45,7 +47,7 @@ namespace linker.libs
|
||||
return proc;
|
||||
}
|
||||
|
||||
public static string Execute(string fileName, string arg, string[] commands)
|
||||
public static string Execute(string fileName, string arg, string[] commands,out string error)
|
||||
{
|
||||
using Process proc = new Process();
|
||||
proc.StartInfo.WorkingDirectory = Path.GetFullPath(Path.Join("./"));
|
||||
@@ -68,7 +70,7 @@ namespace linker.libs
|
||||
proc.StandardInput.AutoFlush = true;
|
||||
proc.StandardInput.WriteLine("exit");
|
||||
proc.StandardInput.Close();
|
||||
string error = proc.StandardError.ReadToEnd();
|
||||
error = proc.StandardError.ReadToEnd();
|
||||
string output = string.Empty;
|
||||
if (string.IsNullOrWhiteSpace(error))
|
||||
{
|
||||
|
@@ -57,7 +57,7 @@ cmd /c netsh advfirewall firewall add rule name=""{fileName}"" dir=in action=all
|
||||
string firewall = Path.Join(distPath, "firewall.bat");
|
||||
|
||||
File.WriteAllText(firewall, content);
|
||||
CommandHelper.Execute(firewall, string.Empty, new string[0]);
|
||||
CommandHelper.Execute(firewall, string.Empty, new string[0],out string error);
|
||||
File.Delete(firewall);
|
||||
}
|
||||
catch (Exception)
|
||||
|
@@ -61,20 +61,24 @@ namespace linker.libs
|
||||
|
||||
|
||||
static List<string> starts = new() { "10.", "100.", "192.168.", "172." };
|
||||
static string domain = "linker.snltty.com";
|
||||
public static ushort GetRouteLevel(out List<IPAddress> result)
|
||||
public static ushort GetRouteLevel(string server, out List<IPAddress> result)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(server) == false)
|
||||
{
|
||||
server = server.Split(':')[0];
|
||||
}
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
return GetRouteLevelWindows(out result);
|
||||
return GetRouteLevelWindows(server, out result);
|
||||
}
|
||||
return GetRouteLevelLinux(out result);
|
||||
return GetRouteLevelLinux(server, out result);
|
||||
}
|
||||
private static ushort GetRouteLevelLinux(out List<IPAddress> result)
|
||||
private static ushort GetRouteLevelLinux(string server, out List<IPAddress> result)
|
||||
{
|
||||
result = new List<IPAddress>();
|
||||
|
||||
string str = CommandHelper.Linux(string.Empty, new string[] { $"traceroute {domain} -4 -m 5" });
|
||||
string str = CommandHelper.Linux(string.Empty, new string[] { $"traceroute {server} -4 -m 5" });
|
||||
string[] lines = str.Split(Environment.NewLine);
|
||||
|
||||
Regex regex = new Regex(@"(\d+\.\d+\.\d+\.\d+)");
|
||||
@@ -93,12 +97,12 @@ namespace linker.libs
|
||||
|
||||
return 3;
|
||||
}
|
||||
private static ushort GetRouteLevelWindows(out List<IPAddress> result)
|
||||
private static ushort GetRouteLevelWindows(string server, out List<IPAddress> result)
|
||||
{
|
||||
result = new List<IPAddress>();
|
||||
try
|
||||
{
|
||||
IPAddress target = Dns.GetHostEntry(domain).AddressList.FirstOrDefault(c => c.AddressFamily == AddressFamily.InterNetwork);
|
||||
IPAddress target = Dns.GetHostEntry(server).AddressList.FirstOrDefault(c => c.AddressFamily == AddressFamily.InterNetwork);
|
||||
|
||||
for (ushort i = 1; i <= 5; i++)
|
||||
{
|
||||
|
@@ -15,8 +15,8 @@
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<Version>1.2.0</Version>
|
||||
<AssemblyVersion>1.2.0.3</AssemblyVersion>
|
||||
<FileVersion>1.2.0.3</FileVersion>
|
||||
<AssemblyVersion>1.2.0.4</AssemblyVersion>
|
||||
<FileVersion>1.2.0.4</FileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
|
@@ -1,139 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace linker.service
|
||||
{
|
||||
partial class LinkerService : ServiceBase
|
||||
{
|
||||
private readonly string[] args;
|
||||
public LinkerService(string[] args)
|
||||
{
|
||||
this.args = args;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private string mainExeName = "linker";
|
||||
private CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
protected override void OnStart(string[] _args)
|
||||
{
|
||||
OpenExe();
|
||||
CheckMainProcess();
|
||||
}
|
||||
protected override void OnStop()
|
||||
{
|
||||
cancellationTokenSource?.Cancel();
|
||||
KillExe();
|
||||
|
||||
}
|
||||
|
||||
private Process proc;
|
||||
private void CheckMainProcess()
|
||||
{
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (cancellationTokenSource.IsCancellationRequested == false)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Process.GetProcessesByName(mainExeName).Any() == false)
|
||||
{
|
||||
string filename = Process.GetCurrentProcess().MainModule.FileName;
|
||||
string dir = Path.GetDirectoryName(filename);
|
||||
if (File.Exists(Path.Combine(dir, $"{mainExeName}.exe.temp")))
|
||||
{
|
||||
RestartService();
|
||||
}
|
||||
else
|
||||
{
|
||||
KillExe();
|
||||
OpenExe();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
await Task.Delay(3000).ConfigureAwait(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
private bool OpenExe()
|
||||
{
|
||||
try
|
||||
{
|
||||
string filename = Process.GetCurrentProcess().MainModule.FileName;
|
||||
string dir = Path.GetDirectoryName(filename);
|
||||
proc = Process.Start(new ProcessStartInfo()
|
||||
{
|
||||
WorkingDirectory = dir,
|
||||
FileName = Path.Combine(dir, $"{mainExeName}.exe"),
|
||||
CreateNoWindow = false,
|
||||
ErrorDialog = false,
|
||||
UseShellExecute = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
//Arguments = string.Join(" ", this.args),
|
||||
Verb = "runas",
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
try
|
||||
{
|
||||
proc.Kill();
|
||||
proc.Dispose();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
proc = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private void KillExe()
|
||||
{
|
||||
try
|
||||
{
|
||||
proc?.Close();
|
||||
proc?.Dispose();
|
||||
|
||||
foreach (var item in Process.GetProcessesByName(mainExeName))
|
||||
{
|
||||
try
|
||||
{
|
||||
item.Kill();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in Process.GetProcessesByName("tun2socks"))
|
||||
{
|
||||
item.Kill();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
proc = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void RestartService()
|
||||
{
|
||||
try
|
||||
{
|
||||
KillExe();
|
||||
Environment.Exit(1);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace linker.service
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
AppDomain.CurrentDomain.UnhandledException += (a, b) =>
|
||||
{
|
||||
};
|
||||
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
ServiceBase[] ServicesToRun;
|
||||
ServicesToRun = new ServiceBase[]
|
||||
{
|
||||
new LinkerService(args)
|
||||
};
|
||||
ServiceBase.Run(ServicesToRun);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<!-- UAC 清单选项
|
||||
如果想要更改 Windows 用户帐户控制级别,请使用
|
||||
以下节点之一替换 requestedExecutionLevel 节点。
|
||||
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
|
||||
|
||||
指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
|
||||
如果你的应用程序需要此虚拟化来实现向后兼容性,则移除此
|
||||
元素。
|
||||
-->
|
||||
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
|
||||
Windows 版本的列表。取消评论适当的元素,
|
||||
Windows 将自动选择最兼容的环境。 -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- 指示该应用程序可感知 DPI 且 Windows 在 DPI 较高时将不会对其进行
|
||||
自动缩放。Windows Presentation Foundation (WPF)应用程序自动感知 DPI,无需
|
||||
选择加入。选择加入此设置的 Windows 窗体应用程序(面向 .NET Framework 4.6)还应
|
||||
在其 app.config 中将 "EnableWindowsFormsHighDpiAutoResizing" 设置设置为 "true"。
|
||||
|
||||
将应用程序设为感知长路径。请参阅 https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation -->
|
||||
<!--
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
|
||||
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
-->
|
||||
|
||||
<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
|
||||
<!--
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
</assembly>
|
Before Width: | Height: | Size: 28 KiB |
@@ -1,43 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
<PublishAot>false</PublishAot>
|
||||
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
|
||||
<EnablePreviewFeatures>true</EnablePreviewFeatures>
|
||||
<Version>1.2.0</Version>
|
||||
<Authors>snltty</Authors>
|
||||
<Company>snltty</Company>
|
||||
<Description>snltty</Description>
|
||||
<Copyright>snltty</Copyright>
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<PackageReleaseNotes>snltty service</PackageReleaseNotes>
|
||||
<AssemblyVersion>1.2.0.3</AssemblyVersion>
|
||||
<FileVersion>1.2.0.3</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
<Optimize>True</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_LastSelectedProfileId>D:\desktop\cmonitor\cmonitor.sas.service\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="LinkerService.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
16
linker.sln
@@ -9,13 +9,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.libs", "linker.libs\
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.tests", "linker.tests\linker.tests.csproj", "{04AA3054-5350-4D8B-97F6-31495AE0609D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.service", "linker.service\linker.service.csproj", "{E8AB5039-3A42-424F-AAEC-A102C8CAA305}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.tunnel", "linker.tunnel\linker.tunnel.csproj", "{AFADE8D6-AB00-456B-9F43-53BC95B7B608}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.tun", "linker.tun\linker.tun.csproj", "{0DE134E0-7CD8-4DCF-8D2A-325CEBE5895F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linker.tun.test", "linker.tun.test\linker.tun.test.csproj", "{4A660D3B-76DE-4E6F-9E90-90BA0DBE906A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.tun.test", "linker.tun.test\linker.tun.test.csproj", "{4A660D3B-76DE-4E6F-9E90-90BA0DBE906A}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -63,18 +61,6 @@ Global
|
||||
{04AA3054-5350-4D8B-97F6-31495AE0609D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{04AA3054-5350-4D8B-97F6-31495AE0609D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{04AA3054-5350-4D8B-97F6-31495AE0609D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E8AB5039-3A42-424F-AAEC-A102C8CAA305}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AFADE8D6-AB00-456B-9F43-53BC95B7B608}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AFADE8D6-AB00-456B-9F43-53BC95B7B608}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AFADE8D6-AB00-456B-9F43-53BC95B7B608}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
|
@@ -1,6 +1,7 @@
|
||||
|
||||
using linker.config;
|
||||
using linker.plugins.serializes;
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.plugins.tuntap.config;
|
||||
using linker.tunnel.connection;
|
||||
using linker.tunnel.transport;
|
||||
@@ -19,29 +20,46 @@ namespace linker.Tests
|
||||
MemoryPackFormatterProvider.Register(new IPAddressFormatter());
|
||||
|
||||
|
||||
TuntapInfo tuntapInfo = new TuntapInfo
|
||||
|
||||
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(new SignInListRequestInfo1
|
||||
{
|
||||
Error = "dfgdgdfgdfgddfgdfhdhdhdhdfhdfdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
Gateway = false,
|
||||
IP = IPAddress.Any,
|
||||
LanIPs = new IPAddress[] { IPAddress.Any, IPAddress.Loopback, IPAddress.Broadcast },
|
||||
Masks = [24, 24, 24],
|
||||
MachineId = "dfgdgdfgdfgddfgdfhdhdhdhdfhdfdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
Status = TuntapStatus.Normal,
|
||||
System = "dfgdgdfgdfgddfgdfhdhdhdhdfhdfdfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||
};
|
||||
List<TuntapInfo> tuntapInfos = new List<TuntapInfo>();
|
||||
for (int i = 0; i < 100; i++)
|
||||
GroupId = string.Empty,
|
||||
Ids =[],
|
||||
Name = "11",
|
||||
Page = 1,
|
||||
Size = 1,
|
||||
});
|
||||
|
||||
SignInListRequestInfo tuntapInfos1 = MemoryPackSerializer.Deserialize<SignInListRequestInfo>(bytes);
|
||||
|
||||
Assert.AreEqual(tuntapInfos1.Name, "11");
|
||||
}
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public sealed partial class SignInListRequestInfo1
|
||||
{
|
||||
tuntapInfos.Add(tuntapInfo);
|
||||
}
|
||||
|
||||
byte[] bytes = MemoryPackSerializer.Serialize(tuntapInfos);
|
||||
|
||||
List<TuntapInfo> tuntapInfos1 = MemoryPackSerializer.Deserialize<List<TuntapInfo>>(bytes);
|
||||
|
||||
Assert.AreEqual(tuntapInfos1.Count, tuntapInfos.Count);
|
||||
}
|
||||
/// <summary>
|
||||
/// <20><>ǰҳ
|
||||
/// </summary>
|
||||
public int Page { get; set; } = 1;
|
||||
/// <summary>
|
||||
/// ÿҳ<C3BF><D2B3>С
|
||||
/// </summary>
|
||||
public int Size { get; set; } = 10;
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD>ڷ<EFBFBD><DAB7><EFBFBD>
|
||||
/// </summary>
|
||||
public string GroupId { get; set; }
|
||||
/// <summary>
|
||||
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// <20><>id<69><64>ȡ
|
||||
/// </summary>
|
||||
public string[] Ids { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<project ver="10" name="linker.tray.win" libEmbed="true" icon="..\linker\favicon.ico" ui="win" output="linker.tray.win.exe" CompanyName="snltty" FileDescription="linker.tray.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="linker.tray.win" InternalName="linker.install.win" FileVersion="0.0.0.59" ProductVersion="0.0.0.59" publishDir="/dist/" dstrip="false" local="false" ignored="false">
|
||||
<project ver="10" name="linker.tray.win" libEmbed="true" icon="..\linker\favicon.ico" ui="win" output="linker.tray.win.exe" CompanyName="snltty" FileDescription="linker.tray.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="linker.tray.win" InternalName="linker.install.win" FileVersion="0.0.0.63" ProductVersion="0.0.0.63" publishDir="/dist/" dstrip="false" local="false" ignored="false">
|
||||
<file name="main.aardio" path="main.aardio" comment="main.aardio"/>
|
||||
<folder name="资源文件" path="res" embed="true" local="false" ignored="false">
|
||||
<file name="favicon.ico" path="res\favicon.ico" comment="res\favicon.ico"/>
|
||||
|
BIN
linker.tray.win/dist/linker.tray.win.exe
vendored
@@ -30,7 +30,7 @@ catch(e){
|
||||
|
||||
|
||||
mainForm.serviceName = "linker.service";
|
||||
mainForm.exeName = "linker.service.exe";
|
||||
mainForm.exeName = "linker.exe";
|
||||
|
||||
import win.image;
|
||||
hIcon = win.image.loadIconFromFile("/res/favicon.ico",true);
|
||||
@@ -51,6 +51,8 @@ mainForm.wndproc = function(hwnd,message,wParam,lParam){
|
||||
//左键
|
||||
if(lParam === 0x0202){
|
||||
mainForm.show();
|
||||
win.setTopmost(mainForm.hwnd);
|
||||
win.setTopmost(mainForm.hwnd,false);
|
||||
}
|
||||
}
|
||||
//关闭
|
||||
@@ -248,6 +250,8 @@ mainForm.showPopmenu();
|
||||
if(!_ARGV["task"])
|
||||
{
|
||||
mainForm.show();
|
||||
win.setTopmost(mainForm.hwnd);
|
||||
win.setTopmost(mainForm.hwnd,false);
|
||||
}
|
||||
|
||||
mainForm.setInterval(
|
||||
@@ -257,12 +261,15 @@ mainForm.setInterval(
|
||||
try{
|
||||
if(io.exist(io._exefile+".temp"))
|
||||
{
|
||||
mainForm.reStart();
|
||||
/*
|
||||
var prcs = process.popen.cmd("tasklist | findstr "+mainForm.serviceName);
|
||||
var str = prcs.readAll();
|
||||
if(!!!string.indexOf(str,mainForm.serviceName))
|
||||
{
|
||||
mainForm.reStart();
|
||||
}
|
||||
*/
|
||||
}
|
||||
}catch(e)
|
||||
{
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace linker.tun
|
||||
{
|
||||
@@ -50,6 +51,18 @@ namespace linker.tun
|
||||
/// </summary>
|
||||
public void RemoveNat(out string error);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 添加端口转发
|
||||
/// </summary>
|
||||
/// <param name="forwards"></param>
|
||||
public void AddForward(List<LinkerTunDeviceForwardItem> forwards);
|
||||
/// <summary>
|
||||
/// 删除端口转发
|
||||
/// </summary>
|
||||
/// <param name="forwards"></param>
|
||||
public void RemoveForward(List<LinkerTunDeviceForwardItem> forwards);
|
||||
|
||||
/// <summary>
|
||||
/// 添加路由
|
||||
/// </summary>
|
||||
@@ -90,6 +103,17 @@ namespace linker.tun
|
||||
public Task Callback(LinkerTunDevicPacket packet);
|
||||
}
|
||||
|
||||
public sealed class LinkerTunDeviceForwardItem
|
||||
{
|
||||
public IPAddress ListenAddr { get; set; } = IPAddress.Any;
|
||||
public int ListenPort { get; set; }
|
||||
public IPAddress ConnectAddr { get; set; } = IPAddress.Any;
|
||||
public int ConnectPort { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public bool Enable => ListenPort > 0 && ConnectAddr.Equals(IPAddress.Any) == false && ConnectPort > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据包
|
||||
/// </summary>
|
||||
|
@@ -162,6 +162,15 @@ namespace linker.tun
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddForward(List<LinkerTunDeviceForwardItem> forwards)
|
||||
{
|
||||
}
|
||||
public void RemoveForward(List<LinkerTunDeviceForwardItem> forwards)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip, bool gateway)
|
||||
{
|
||||
if (gateway)
|
||||
@@ -276,8 +285,9 @@ namespace linker.tun
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -112,6 +112,14 @@ namespace linker.tun
|
||||
error = string.Empty;
|
||||
}
|
||||
|
||||
public void AddForward(List<LinkerTunDeviceForwardItem> forwards)
|
||||
{
|
||||
}
|
||||
public void RemoveForward(List<LinkerTunDeviceForwardItem> forwards)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private byte[] buffer = new byte[2 * 1024];
|
||||
public ReadOnlyMemory<byte> Read()
|
||||
{
|
||||
|
@@ -16,6 +16,10 @@ namespace linker.tun
|
||||
private string error = string.Empty;
|
||||
public string Error => error;
|
||||
|
||||
private string error1 = string.Empty;
|
||||
public string Error1 => error1;
|
||||
|
||||
|
||||
private uint operating = 0;
|
||||
public LinkerTunDeviceStatus Status
|
||||
{
|
||||
@@ -125,7 +129,6 @@ namespace linker.tun
|
||||
{
|
||||
cancellationTokenSource?.Cancel();
|
||||
linkerTunDevice?.Shutdown();
|
||||
linkerTunDevice?.RemoveNat(out error);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -142,14 +145,31 @@ namespace linker.tun
|
||||
/// </summary>
|
||||
public void SetNat()
|
||||
{
|
||||
linkerTunDevice?.SetNat(out error);
|
||||
linkerTunDevice?.SetNat(out error1);
|
||||
}
|
||||
/// <summary>
|
||||
/// 移除NAT转发
|
||||
/// </summary>
|
||||
public void RemoveNat()
|
||||
{
|
||||
linkerTunDevice?.RemoveNat(out error);
|
||||
linkerTunDevice?.RemoveNat(out error1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加端口转发
|
||||
/// </summary>
|
||||
/// <param name="forwards"></param>
|
||||
public void AddForward(List<LinkerTunDeviceForwardItem> forwards)
|
||||
{
|
||||
linkerTunDevice?.AddForward(forwards);
|
||||
}
|
||||
/// <summary>
|
||||
/// 移除端口转发
|
||||
/// </summary>
|
||||
/// <param name="forwards"></param>
|
||||
public void RemoveForward(List<LinkerTunDeviceForwardItem> forwards)
|
||||
{
|
||||
linkerTunDevice?.RemoveForward(forwards);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -118,9 +118,9 @@ namespace linker.tun
|
||||
error = string.Empty;
|
||||
try
|
||||
{
|
||||
CommandHelper.PowerShell($"start-service WinNat", []);
|
||||
CommandHelper.PowerShell($"start-service WinNat", [], out error);
|
||||
IPAddress network = NetworkHelper.ToNetworkIp(this.address, NetworkHelper.MaskValue(prefixLength));
|
||||
CommandHelper.PowerShell($"New-NetNat -Name {Name} -InternalIPInterfaceAddressPrefix {network}/{prefixLength}", []);
|
||||
CommandHelper.PowerShell($"New-NetNat -Name {Name} -InternalIPInterfaceAddressPrefix {network}/{prefixLength}", [], out error);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -148,8 +148,8 @@ namespace linker.tun
|
||||
|
||||
try
|
||||
{
|
||||
CommandHelper.PowerShell($"start-service WinNat", []);
|
||||
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", []);
|
||||
CommandHelper.PowerShell($"start-service WinNat", [], out error);
|
||||
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -176,6 +176,25 @@ namespace linker.tun
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddForward(List<LinkerTunDeviceForwardItem> forwards)
|
||||
{
|
||||
string[] commands = forwards.Where(c => c != null && c.Enable).Select(c =>
|
||||
{
|
||||
return $"netsh interface portproxy add v4tov4 listenaddress={c.ListenAddr} listenport={c.ListenPort} connectaddress={c.ConnectAddr} connectport={c.ConnectPort}";
|
||||
}).ToArray();
|
||||
CommandHelper.Windows(string.Empty, commands);
|
||||
}
|
||||
public void RemoveForward(List<LinkerTunDeviceForwardItem> forwards)
|
||||
{
|
||||
string[] commands = forwards.Where(c => c != null && c.Enable).Select(c =>
|
||||
{
|
||||
return $"netsh interface portproxy delete v4tov4 listenport={c.ListenPort} listenaddress={c.ListenAddr}";
|
||||
}).ToArray();
|
||||
CommandHelper.Windows(string.Empty, commands);
|
||||
}
|
||||
|
||||
|
||||
public void AddRoute(LinkerTunDeviceRouteItem[] ips, IPAddress ip, bool gateway)
|
||||
{
|
||||
if (interfaceNumber > 0)
|
||||
|
@@ -17,8 +17,8 @@
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<PackageReleaseNotes>linker tun</PackageReleaseNotes>
|
||||
<AssemblyVersion>1.2.0.3</AssemblyVersion>
|
||||
<FileVersion>1.2.0.3</FileVersion>
|
||||
<AssemblyVersion>1.2.0.4</AssemblyVersion>
|
||||
<FileVersion>1.2.0.4</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
@@ -17,8 +17,8 @@
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<PackageReleaseNotes>linker tunnel</PackageReleaseNotes>
|
||||
<AssemblyVersion>1.2.0.3</AssemblyVersion>
|
||||
<FileVersion>1.2.0.3</FileVersion>
|
||||
<AssemblyVersion>1.2.0.4</AssemblyVersion>
|
||||
<FileVersion>1.2.0.4</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
|
@@ -230,7 +230,7 @@ namespace linker.tunnel.transport
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}).AsTask().WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
|
||||
}).AsTask().WaitAsync(TimeSpan.FromMilliseconds(1000)).ConfigureAwait(false);
|
||||
QuicStream quicStream = await connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional).ConfigureAwait(false);
|
||||
return new TunnelConnectionMsQuic
|
||||
{
|
||||
|
@@ -11,6 +11,9 @@ export const setSignInServers = (servers) => {
|
||||
export const getSignInfo = () => {
|
||||
return sendWebsocketMsg('signInclient/info');
|
||||
}
|
||||
export const setSignInIndex = (ids) => {
|
||||
return sendWebsocketMsg('signInclient/setindex', ids);
|
||||
}
|
||||
export const getSignInList = (data) => {
|
||||
return sendWebsocketMsg('signInclient/List', data);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-table-column prop="MachineId" label="设备">
|
||||
<el-table-column prop="MachineId" label="设备" width="240">
|
||||
<template #header>
|
||||
<div class="flex">
|
||||
<span class="flex-1">设备</span>
|
||||
@@ -13,7 +13,7 @@
|
||||
<div>
|
||||
<p>
|
||||
<template v-if="tuntap.list[scope.row.MachineId] && tuntap.list[scope.row.MachineId].system">
|
||||
<span :title="tuntap.list[scope.row.MachineId].System">
|
||||
<span :title="tuntap.list[scope.row.MachineId].SystemInfo">
|
||||
<img v-if="scope.row.countryFlag" class="system" :src="scope.row.countryFlag" />
|
||||
<img class="system":src="`/${tuntap.list[scope.row.MachineId].system}.svg`" />
|
||||
<img v-if="tuntap.list[scope.row.MachineId].systemDocker" class="system" src="/docker.svg" />
|
||||
|
@@ -1,5 +1,13 @@
|
||||
<template>
|
||||
<div class="home-list-wrap absolute" >
|
||||
<el-table border style="width: 100%" height="32px" size="small" @sort-change="handleSortChange" class="table-sort">
|
||||
<el-table-column prop="MachineId" label="设备名" width="120" sortable ></el-table-column>
|
||||
<el-table-column prop="Version" label="版本" width="120" sortable></el-table-column>
|
||||
<el-table-column prop="tunnel" label="网关" width="90" sortable></el-table-column>
|
||||
<el-table-column prop="tuntap" label="网卡IP" width="150" sortable></el-table-column>
|
||||
<el-table-column prop="forward" label=""></el-table-column>
|
||||
<el-table-column label="" width="74" fixed="right"></el-table-column>
|
||||
</el-table>
|
||||
<el-table :data="devices.page.List" stripe border style="width: 100%" :height="`${state.height}px`" size="small">
|
||||
<Device @edit="handleDeviceEdit" @refresh="handlePageRefresh"></Device>
|
||||
<Tunnel @edit="handleTunnelEdit" @refresh="handleTunnelRefresh" @connections="handleTunnelConnections"></Tunnel>
|
||||
@@ -55,14 +63,14 @@ export default {
|
||||
|
||||
const globalData = injectGlobalData();
|
||||
const state = reactive({
|
||||
height: computed(()=>globalData.value.height-60),
|
||||
height: computed(()=>globalData.value.height-90),
|
||||
});
|
||||
|
||||
const {devices, machineId, _getSignList, _getSignList1,
|
||||
handleDeviceEdit, handlePageChange, handlePageSizeChange, handleDel,clearDevicesTimeout} = provideDevices();
|
||||
handleDeviceEdit, handlePageChange, handlePageSizeChange, handleDel,clearDevicesTimeout,setSort} = provideDevices();
|
||||
|
||||
const {tuntap,_getTuntapInfo,handleTuntapEdit,handleTuntapRefresh,clearTuntapTimeout,getTuntapMachines} = provideTuntap();
|
||||
const {tunnel,_getTunnelInfo,handleTunnelEdit,handleTunnelRefresh,clearTunnelTimeout} = provideTunnel();
|
||||
const {tuntap,_getTuntapInfo,handleTuntapEdit,handleTuntapRefresh,clearTuntapTimeout,getTuntapMachines,sortTuntapIP} = provideTuntap();
|
||||
const {tunnel,_getTunnelInfo,handleTunnelEdit,handleTunnelRefresh,clearTunnelTimeout,sortTunnel} = provideTunnel();
|
||||
const {forward,_getForwardInfo,handleForwardEdit,_testTargetForwardInfo,clearForwardTimeout,getForwardMachines} = provideForward();
|
||||
const {sforward,_getSForwardInfo,handleSForwardEdit,_testLocalSForwardInfo,clearSForwardTimeout,getSForwardMachines} = provideSforward();
|
||||
const {connections,
|
||||
@@ -73,6 +81,30 @@ export default {
|
||||
|
||||
const {_getUpdater,clearUpdaterTimeout} = provideUpdater();
|
||||
|
||||
const handleSortChange = (row)=>{
|
||||
|
||||
devices.page.Request.Prop = row.prop;
|
||||
devices.page.Request.Asc = row.order == 'ascending';
|
||||
|
||||
let fn = new Promise((resolve,reject)=>{
|
||||
resolve();
|
||||
});
|
||||
if(row.prop == 'tunnel'){
|
||||
const ids = sortTunnel(devices.page.Request.Asc);
|
||||
if(ids .length > 0){
|
||||
fn = setSort(ids);
|
||||
}
|
||||
}else if(row.prop == 'tuntap'){
|
||||
const ids = sortTuntapIP(devices.page.Request.Asc);
|
||||
if(ids .length > 0){
|
||||
fn = setSort(ids);
|
||||
}
|
||||
}
|
||||
fn.then(()=>{
|
||||
handlePageChange();
|
||||
}).catch(()=>{});
|
||||
}
|
||||
|
||||
const _handleForwardEdit = (machineId) => {
|
||||
handleForwardEdit(machineId,devices.page.List.filter(c => c.MachineId == machineId)[0].MachineName);
|
||||
}
|
||||
@@ -142,7 +174,7 @@ export default {
|
||||
});
|
||||
|
||||
return {
|
||||
state,devices, machineId,
|
||||
state,devices, machineId,handleSortChange,
|
||||
handleDeviceEdit,handlePageRefresh,handlePageSearch, handlePageChange,handlePageSizeChange, handleDel,
|
||||
tuntap, handleTuntapEdit, handleTuntapRefresh,
|
||||
tunnel,connections, handleTunnelEdit, handleTunnelRefresh,handleTunnelConnections,
|
||||
@@ -152,7 +184,18 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus">
|
||||
.table-sort.el-table
|
||||
{
|
||||
th.el-table__cell.is-leaf{border-bottom:0}
|
||||
.el-table__inner-wrapper:before{height:0}
|
||||
}
|
||||
</style>
|
||||
<style lang="stylus" scoped>
|
||||
.table-sort
|
||||
{
|
||||
th{border-bottom:0}
|
||||
}
|
||||
.home-list-wrap{
|
||||
padding:1rem;
|
||||
|
||||
|
@@ -10,8 +10,8 @@
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="javascript:;" class="a-line" @click="handleConnections(scope.row.MachineId)">
|
||||
<span>连接数 : {{connectionCount(scope.row.MachineId)}}</span>
|
||||
<a href="javascript:;" class="a-line" :class="{green:connectionCount(scope.row.MachineId)>0}" @click="handleConnections(scope.row.MachineId)">
|
||||
连接数 : <span>{{connectionCount(scope.row.MachineId)}}</span>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
@@ -57,4 +57,6 @@ export default {
|
||||
<style lang="stylus" scoped>
|
||||
|
||||
.el-switch.is-disabled{opacity :1;}
|
||||
|
||||
.green{font-weight:bold;}
|
||||
</style>
|
@@ -33,9 +33,28 @@
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<div v-for="(item,index) in tuntap.list[scope.row.MachineId].LanIPs" :key="index">
|
||||
<template v-if="tuntap.list[scope.row.MachineId].Error1">
|
||||
<el-popover placement="top" title="msg" width="20rem" trigger="hover" :content="tuntap.list[scope.row.MachineId].Error1">
|
||||
<template #reference>
|
||||
<div class="yellow">
|
||||
<template v-for="(item,index) in tuntap.list[scope.row.MachineId].LanIPs" :key="index">
|
||||
<div>
|
||||
{{ item }} / {{ tuntap.list[scope.row.MachineId].Masks[index] }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div>
|
||||
<template v-for="(item,index) in tuntap.list[scope.row.MachineId].LanIPs" :key="index">
|
||||
<div>
|
||||
{{ item }} / {{ tuntap.list[scope.row.MachineId].Masks[index] }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@@ -1,17 +1,24 @@
|
||||
<template>
|
||||
<el-dialog v-model="state.show" :close-on-click-modal="false" append-to=".app-wrap" title="设置虚拟网卡IP" width="420">
|
||||
<el-dialog v-model="state.show" :close-on-click-modal="false" append-to=".app-wrap" title="组网设置" top="1vh" width="700">
|
||||
<div>
|
||||
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="80">
|
||||
<el-form ref="ruleFormRef" :model="state.ruleForm" :rules="state.rules" label-width="140">
|
||||
<el-form-item prop="gateway" style="margin-bottom:0">
|
||||
<el-checkbox v-model="state.ruleForm.Gateway" label="我在路由器,我是网关" size="large" />
|
||||
赐予此设备IP,其它可以通过这个IP访问
|
||||
</el-form-item>
|
||||
<el-form-item label="虚拟网卡IP" prop="IP">
|
||||
<el-input v-model="state.ruleForm.IP" style="width:12rem" /> / 24
|
||||
<el-form-item label="此设备的虚拟网卡IP" prop="IP">
|
||||
<el-input v-model="state.ruleForm.IP" style="width:12rem" /> / <el-input @change="handlePrefixLengthChange" v-model="state.ruleForm.PrefixLength" style="width:4rem" />
|
||||
</el-form-item>
|
||||
<el-form-item style="margin-bottom:0">
|
||||
<div>局域网IP选填,不懂是啥的时候,不要填</div>
|
||||
<el-form-item prop="upgrade" style="margin-bottom:0">
|
||||
<el-checkbox v-model="state.ruleForm.Upgrade" label="我很懂,我要使用高级功能(点对网和网对网)" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item label="局域网IP" prop="LanIP">
|
||||
<div class="upgrade-wrap" v-if="state.ruleForm.Upgrade">
|
||||
<el-form-item prop="gateway" style="margin-bottom:0">
|
||||
<el-checkbox v-model="state.ruleForm.Gateway" label="此设备在路由器(网对网,将对方的 局域网IP 转发到对方)" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="gateway" style="margin-bottom:0">
|
||||
<span class="yellow">此设备可以用NAT转发,那填写局域网IP,其它交给NAT(linux、macos、win10+)</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="此设备局域网IP" prop="LanIP">
|
||||
<template v-for="(item, index) in state.ruleForm.LanIPs" :key="index">
|
||||
<div class="flex" style="margin-bottom:.6rem">
|
||||
<div class="flex-1">
|
||||
@@ -24,6 +31,25 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-form-item>
|
||||
<el-form-item prop="gateway" style="margin-bottom:0">
|
||||
<span class="yellow">此设备不能用NAT转发,那可以使用系统端口转发实现类似的效果(仅windows)</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="端口转发" prop="foreards">
|
||||
<template v-for="(item, index) in state.ruleForm.Forwards" :key="index">
|
||||
<div class="flex" style="margin-bottom:.6rem">
|
||||
<div class="flex-1">
|
||||
<el-input v-model="item.ListenAddr" style="width:7rem" readonly /> : <el-input @change="handleForwardChange(index)" v-model="item.ListenPort" style="width:6rem" />
|
||||
-> <el-input v-model="item.ConnectAddr" style="width:12rem" /> : <el-input @change="handleForwardChange(index)" v-model="item.ConnectPort" style="width:6rem" />
|
||||
</div>
|
||||
<div class="pdl-10">
|
||||
|
||||
<el-button type="danger" @click="handleDelForward(index)"><el-icon><Delete /></el-icon></el-button>
|
||||
<el-button type="primary" @click="handleAddForward(index)"><el-icon><Plus /></el-icon></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="" prop="Btns">
|
||||
<div>
|
||||
<el-button @click="state.show = false">取消</el-button>
|
||||
@@ -57,7 +83,13 @@ export default {
|
||||
IP: tuntap.value.current.IP,
|
||||
LanIPs: tuntap.value.current.LanIPs.slice(0),
|
||||
Masks: tuntap.value.current.Masks.slice(0),
|
||||
PrefixLength:tuntap.value.current.PrefixLength || 24,
|
||||
Gateway: tuntap.value.current.Gateway,
|
||||
Upgrade: tuntap.value.current.Upgrade,
|
||||
|
||||
Forwards:tuntap.value.current.Forwards.slice(0) || [
|
||||
{ListenAddr:'0.0.0.0',ListenPort:0,ConnectAddr:'0.0.0.0',ConnectPort:0}
|
||||
]
|
||||
},
|
||||
rules: {}
|
||||
});
|
||||
@@ -73,6 +105,13 @@ export default {
|
||||
}
|
||||
});
|
||||
|
||||
const handlePrefixLengthChange = ()=>{
|
||||
var value = +state.ruleForm.PrefixLength;
|
||||
if(value>32 || value<16 || isNaN(value)){
|
||||
value = 24;
|
||||
}
|
||||
state.ruleForm.PrefixLength = value;
|
||||
}
|
||||
const handleMaskChange = (index)=>{
|
||||
var value = +state.ruleForm.Masks[index];
|
||||
if(value>32 || value<16 || isNaN(value)){
|
||||
@@ -81,9 +120,11 @@ export default {
|
||||
state.ruleForm.Masks[index] = value;
|
||||
}
|
||||
const handleDel = (index) => {
|
||||
if (state.ruleForm.LanIPs.length == 1) return;
|
||||
state.ruleForm.LanIPs.splice(index, 1);
|
||||
state.ruleForm.Masks.splice(index, 1);
|
||||
if (state.ruleForm.LanIPs.length == 0){
|
||||
handleAdd(0);
|
||||
}
|
||||
}
|
||||
const handleAdd = (index) => {
|
||||
state.ruleForm.LanIPs.splice(index + 1, 0, '');
|
||||
@@ -101,7 +142,14 @@ export default {
|
||||
},{lanips:[],masks:[]});
|
||||
json.LanIPs = lanips;
|
||||
json.Masks = masks;
|
||||
json.PrefixLength = +state.ruleForm.PrefixLength;
|
||||
json.Gateway = state.ruleForm.Gateway;
|
||||
json.Upgrade = state.ruleForm.Upgrade;
|
||||
json.Forwards = state.ruleForm.Forwards;
|
||||
json.Forwards.forEach(c=>{
|
||||
c.ListenPort=+c.ListenPort;
|
||||
c.ConnectPort=+c.ConnectPort;
|
||||
});
|
||||
updateTuntap(json).then(() => {
|
||||
state.show = false;
|
||||
ElMessage.success('已操作!');
|
||||
@@ -111,12 +159,32 @@ export default {
|
||||
});
|
||||
}
|
||||
|
||||
const handleDelForward = (index) => {
|
||||
state.ruleForm.Forwards.splice(index, 1);
|
||||
if (state.ruleForm.Forwards.length == 0) {
|
||||
handleAddForward(0);
|
||||
}
|
||||
}
|
||||
const handleAddForward = (index) => {
|
||||
state.ruleForm.Forwards.splice(index + 1, 0, {ListenAddr:'0.0.0.0',ListenPort:0,ConnectAddr:'0.0.0.0',ConnectPort:0});
|
||||
}
|
||||
const handleForwardChange = ()=>{
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
state, ruleFormRef,handleMaskChange, handleDel, handleAdd, handleSave
|
||||
state, ruleFormRef,handlePrefixLengthChange,handleMaskChange, handleDel, handleAdd, handleSave,
|
||||
handleForwardChange,handleDelForward,handleAddForward
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="stylus" scoped>
|
||||
.el-switch.is-disabled{opacity :1;}
|
||||
|
||||
.upgrade-wrap{
|
||||
border:1px solid #ddd;
|
||||
margin-bottom:2rem
|
||||
padding:1rem 0;
|
||||
}
|
||||
</style>
|
@@ -1,4 +1,4 @@
|
||||
import { getSignInList, signInDel } from "@/apis/signin";
|
||||
import { getSignInList, signInDel, setSignInIndex } from "@/apis/signin";
|
||||
import { injectGlobalData } from "@/provide";
|
||||
import { computed, reactive } from "vue";
|
||||
|
||||
@@ -12,7 +12,7 @@ export const provideDevices = () => {
|
||||
timer: 0,
|
||||
page: {
|
||||
Request: {
|
||||
Page: 1, Size: +(localStorage.getItem('ps') || '10'), Name: '', Ids: []
|
||||
Page: 1, Size: +(localStorage.getItem('ps') || '10'), Name: '', Ids: [], Prop: '', Asc: true
|
||||
},
|
||||
Count: 0,
|
||||
List: []
|
||||
@@ -23,7 +23,6 @@ export const provideDevices = () => {
|
||||
});
|
||||
const _getSignList = () => {
|
||||
getSignInList(devices.page.Request).then((res) => {
|
||||
console.log(res);
|
||||
devices.page.Request = res.Request;
|
||||
devices.page.Count = res.Count;
|
||||
for (let j in res.List) {
|
||||
@@ -33,7 +32,7 @@ export const provideDevices = () => {
|
||||
|
||||
|
||||
}
|
||||
devices.page.List = res.List.sort((a, b) => b.Connected - a.Connected);
|
||||
devices.page.List = res.List;
|
||||
for (let i = 0; i < devices.page.List.length; i++) {
|
||||
queue.push(devices.page.List[i]);
|
||||
}
|
||||
@@ -112,7 +111,12 @@ export const provideDevices = () => {
|
||||
devices.timer = 0;
|
||||
}
|
||||
|
||||
const setSort = (ids) => {
|
||||
return setSignInIndex(ids);
|
||||
}
|
||||
|
||||
return {
|
||||
devices, machineId, _getSignList, _getSignList1, handleDeviceEdit, handlePageChange, handlePageSizeChange, handleDel, clearDevicesTimeout
|
||||
devices, machineId, _getSignList, _getSignList1, handleDeviceEdit, handlePageChange, handlePageSizeChange, handleDel, clearDevicesTimeout,
|
||||
setSort
|
||||
}
|
||||
}
|
@@ -40,8 +40,13 @@ export const provideTunnel = () => {
|
||||
const clearTunnelTimeout = () => {
|
||||
clearTimeout(tunnel.value.timer);
|
||||
}
|
||||
const sortTunnel = (asc) => {
|
||||
return Object.values(tunnel.value.list).sort((a, b) => {
|
||||
return asc ? a.RouteLevel - b.RouteLevel : b.RouteLevel - a.RouteLevel;
|
||||
}).map(c => c.MachineId);
|
||||
}
|
||||
return {
|
||||
tunnel, _getTunnelInfo, handleTunnelEdit, handleTunnelRefresh, clearTunnelTimeout
|
||||
tunnel, _getTunnelInfo, handleTunnelEdit, handleTunnelRefresh, clearTunnelTimeout, sortTunnel
|
||||
}
|
||||
}
|
||||
export const useTunnel = () => {
|
||||
|
@@ -27,13 +27,14 @@ export const provideTuntap = () => {
|
||||
if (globalData.value.api.connected) {
|
||||
getTuntapInfo(tuntap.value.hashcode.toString()).then((res) => {
|
||||
tuntap.value.hashcode = res.HashCode;
|
||||
console.log(res);
|
||||
if (res.List) {
|
||||
for (let j in res.List) {
|
||||
res.List[j].running = res.List[j].Status == 2;
|
||||
res.List[j].loading = res.List[j].Status == 1;
|
||||
res.List[j].system = 'system';
|
||||
|
||||
const systemStr = res.List[j].System.toLowerCase();
|
||||
const systemStr = res.List[j].SystemInfo.toLowerCase();
|
||||
res.List[j].systemDocker = systemStr.indexOf('docker') >= 0;
|
||||
|
||||
for (let jj in systems) {
|
||||
@@ -81,8 +82,22 @@ export const provideTuntap = () => {
|
||||
.filter(c => c.IP.indexOf(name) >= 0 || (c.LanIPs.filter(d => d.indexOf(name) >= 0).length > 0))
|
||||
.map(c => c.MachineId);
|
||||
}
|
||||
const sortTuntapIP = (asc) => {
|
||||
return Object.values(tuntap.value.list).sort((a, b) => {
|
||||
const arrA = a.IP.split('.').map(c => Number(c));
|
||||
const arrB = b.IP.split('.').map(c => Number(c));
|
||||
for (let i = 0; i < arrA.length; i++) {
|
||||
if (arrA[i] != arrB[i]) {
|
||||
return asc ? arrA[i] - arrB[i] : arrB[i] - arrA[i];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}).map(c => c.MachineId);
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
tuntap, _getTuntapInfo, handleTuntapEdit, handleTuntapRefresh, clearTuntapTimeout, getTuntapMachines
|
||||
tuntap, _getTuntapInfo, handleTuntapEdit, handleTuntapRefresh, clearTuntapTimeout, getTuntapMachines, sortTuntapIP
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -3,17 +3,39 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Reflection;
|
||||
using linker.startup;
|
||||
using linker.config;
|
||||
using System.ServiceProcess;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace linker
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
static async Task Main(string[] args)
|
||||
{
|
||||
if (Environment.UserInteractive == false && OperatingSystem.IsWindows())
|
||||
{
|
||||
AppDomain.CurrentDomain.UnhandledException += (a, b) =>
|
||||
{
|
||||
};
|
||||
|
||||
string serviceDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
|
||||
Directory.SetCurrentDirectory(serviceDirectory);
|
||||
|
||||
ServiceBase[] ServicesToRun;
|
||||
ServicesToRun = new ServiceBase[]
|
||||
{
|
||||
new Service()
|
||||
};
|
||||
ServiceBase.Run(ServicesToRun);
|
||||
}
|
||||
else
|
||||
{
|
||||
Run(args);
|
||||
await Helper.Await().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void Run(string[] args)
|
||||
{
|
||||
Init();
|
||||
|
@@ -1,6 +1,6 @@
|
||||
namespace linker.service
|
||||
namespace linker
|
||||
{
|
||||
partial class LinkerService
|
||||
partial class Service
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
24
linker/Service.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace linker
|
||||
{
|
||||
partial class Service : ServiceBase
|
||||
{
|
||||
public Service()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
Program.Run(args);
|
||||
// TODO: 在此处添加代码以启动服务。
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
// TODO: 在此处添加代码以执行停止服务所需的关闭操作。
|
||||
}
|
||||
}
|
||||
}
|
@@ -25,8 +25,8 @@
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
<PackageReleaseNotes>linker</PackageReleaseNotes>
|
||||
<AssemblyVersion>1.2.0.3</AssemblyVersion>
|
||||
<FileVersion>1.2.0.3</FileVersion>
|
||||
<AssemblyVersion>1.2.0.4</AssemblyVersion>
|
||||
<FileVersion>1.2.0.4</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
@@ -65,5 +65,6 @@
|
||||
<PackageReference Include="LiteDB" Version="5.0.17" />
|
||||
<PackageReference Include="MemoryPack" Version="1.10.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@@ -7,4 +7,9 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Service.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -70,6 +70,15 @@ namespace linker.plugins.signin
|
||||
Payload = MemoryPackSerializer.Serialize(param.Content)
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
public async Task SetIndex(ApiControllerParamsInfo param)
|
||||
{
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
{
|
||||
Connection = clientSignInState.Connection,
|
||||
MessengerId = (ushort)SignInMessengerIds.SetIndex,
|
||||
Payload = MemoryPackSerializer.Serialize(param.Content.DeJson<string[]>())
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
public async Task<SignInListResponseInfo> List(ApiControllerParamsInfo param)
|
||||
{
|
||||
SignInListRequestInfo request = param.Content.DeJson<SignInListRequestInfo>();
|
||||
|
@@ -94,7 +94,6 @@ namespace linker.plugins.signin.messenger
|
||||
public DateTime LastSignIn { get; set; } = DateTime.Now;
|
||||
public Dictionary<string, string> Args { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
|
||||
private IPEndPoint ip = new IPEndPoint(IPAddress.Any, 0);
|
||||
[MemoryPackAllowSerialize]
|
||||
public IPEndPoint IP
|
||||
@@ -132,6 +131,9 @@ namespace linker.plugins.signin.messenger
|
||||
|
||||
[MemoryPackIgnore, JsonIgnore, BsonIgnore]
|
||||
public IConnection Connection { get; set; }
|
||||
|
||||
[MemoryPackIgnore, JsonIgnore, BsonIgnore]
|
||||
public uint Index { get; set; } = 65535;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -44,6 +44,27 @@ namespace linker.plugins.signin.messenger
|
||||
connection.Write(MemoryPackSerializer.Serialize(info.MachineId));
|
||||
}
|
||||
|
||||
[MessengerId((ushort)SignInMessengerIds.SetIndex)]
|
||||
public void SetIndex(IConnection connection)
|
||||
{
|
||||
string[] ids = MemoryPackSerializer.Deserialize<string[]>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache))
|
||||
{
|
||||
IEnumerable<SignCacheInfo> list = signCaching.Get(cache.GroupId);
|
||||
foreach (var item in list)
|
||||
{
|
||||
item.Index = uint.MaxValue;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < ids.Length; i++)
|
||||
{
|
||||
SignCacheInfo item = list.FirstOrDefault(c => c.MachineId == ids[i]);
|
||||
if (item != null)
|
||||
item.Index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[MessengerId((ushort)SignInMessengerIds.List)]
|
||||
public void List(IConnection connection)
|
||||
@@ -51,15 +72,51 @@ namespace linker.plugins.signin.messenger
|
||||
SignInListRequestInfo request = MemoryPackSerializer.Deserialize<SignInListRequestInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
if (signCaching.TryGet(connection.Id, out SignCacheInfo cache))
|
||||
{
|
||||
IEnumerable<SignCacheInfo> list = signCaching.Get(cache.GroupId).OrderByDescending(c => c.MachineName).OrderByDescending(c => c.LastSignIn).OrderByDescending(c => c.Version).ToList();
|
||||
IEnumerable<SignCacheInfo> list = signCaching.Get(cache.GroupId).Where(c => c.MachineId != cache.MachineId);
|
||||
if (string.IsNullOrWhiteSpace(request.Name) == false)
|
||||
{
|
||||
list = list.Where(c => c.Version.Contains(request.Name) || c.IP.ToString().Contains(request.Name) || c.MachineName.Contains(request.Name) || request.Ids.Contains(c.MachineId));
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(request.Prop) == false)
|
||||
{
|
||||
if (request.Asc)
|
||||
{
|
||||
switch (request.Prop)
|
||||
{
|
||||
case "MachineId":
|
||||
list = list.OrderBy(c => c.MachineName);
|
||||
break;
|
||||
case "Version":
|
||||
list = list.OrderBy(c => c.Version);
|
||||
break;
|
||||
default:
|
||||
list = list.OrderBy(c => c.Index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (request.Prop)
|
||||
{
|
||||
case "MachineId":
|
||||
list = list.OrderByDescending(c => c.MachineName);
|
||||
break;
|
||||
case "Version":
|
||||
list = list.OrderByDescending(c => c.Version);
|
||||
break;
|
||||
default:
|
||||
list = list.OrderByDescending(c => c.Index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int count = list.Count();
|
||||
list = list.Skip((request.Page - 1) * request.Size).Take(request.Size);
|
||||
|
||||
SignInListResponseInfo response = new SignInListResponseInfo { Request = request, Count = count, List = list.ToList() };
|
||||
List<SignCacheInfo> result = [cache, .. list];
|
||||
SignInListResponseInfo response = new SignInListResponseInfo { Request = request, Count = count, List = result };
|
||||
|
||||
connection.Write(MemoryPackSerializer.Serialize(response));
|
||||
}
|
||||
@@ -148,10 +205,6 @@ namespace linker.plugins.signin.messenger
|
||||
/// </summary>
|
||||
public int Size { get; set; } = 10;
|
||||
/// <summary>
|
||||
/// 所在分组
|
||||
/// </summary>
|
||||
public string GroupId { get; set; }
|
||||
/// <summary>
|
||||
/// 按名称搜索
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
@@ -159,6 +212,15 @@ namespace linker.plugins.signin.messenger
|
||||
/// 按id获取
|
||||
/// </summary>
|
||||
public string[] Ids { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序
|
||||
/// </summary>
|
||||
public bool Asc { get; set; }
|
||||
/// <summary>
|
||||
/// 排序字段
|
||||
/// </summary>
|
||||
public string Prop { get; set; }
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
|
@@ -14,6 +14,8 @@
|
||||
Ids = 8,
|
||||
Exists = 9,
|
||||
|
||||
SetIndex = 10,
|
||||
|
||||
None = 99
|
||||
}
|
||||
}
|
||||
|
@@ -177,11 +177,20 @@ namespace linker.plugins.tunnel
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (File.Exists("msquic.dll.temp"))
|
||||
{
|
||||
File.Delete("msquic.dll.temp");
|
||||
}
|
||||
if (File.Exists("msquic-openssl.dll"))
|
||||
{
|
||||
File.Delete("msquic-openssl.dll");
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -63,7 +63,7 @@ namespace linker.plugins.tunnel
|
||||
serviceCollection.AddSingleton<ITunnelAdapter, TunnelAdapter>();
|
||||
|
||||
LoggerHelper.Instance.Info($"tunnel route level getting.");
|
||||
config.Data.Client.Tunnel.RouteLevel = NetworkHelper.GetRouteLevel(out List<IPAddress> ips);
|
||||
config.Data.Client.Tunnel.RouteLevel = NetworkHelper.GetRouteLevel(config.Data.Client.Server, out List<IPAddress> ips);
|
||||
config.Data.Client.Tunnel.RouteIPs = ips.ToArray();
|
||||
LoggerHelper.Instance.Warning($"route ips:{string.Join(",", ips.Select(c => c.ToString()))}");
|
||||
config.Data.Client.Tunnel.LocalIPs = NetworkHelper.GetIPV6().Concat(NetworkHelper.GetIPV4()).ToArray();
|
||||
|
@@ -15,6 +15,7 @@ namespace linker.plugins.tuntap
|
||||
//网卡IP,和局域网IP。不参与打洞
|
||||
return new ExcludeIPItem[] { new ExcludeIPItem { IPAddress = runningConfig.Data.Tuntap.IP, Mask = 32 } }
|
||||
.Concat(runningConfig.Data.Tuntap.LanIPs.Select((c, index) => new ExcludeIPItem { IPAddress = c, Mask = (byte)runningConfig.Data.Tuntap.Masks[index] }))
|
||||
.Where(c=>c.IPAddress != null)
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
@@ -117,7 +117,11 @@ namespace linker.plugins.tuntap
|
||||
return true;
|
||||
}
|
||||
|
||||
//更新网卡信息
|
||||
/// <summary>
|
||||
/// 更新网卡信息
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> Update(ApiControllerParamsInfo param)
|
||||
{
|
||||
TuntapInfo info = param.Content.DeJson<TuntapInfo>();
|
||||
|
@@ -12,6 +12,7 @@ using linker.plugins.client;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.tuntap.config;
|
||||
using linker.tun;
|
||||
using linker.libs.extends;
|
||||
|
||||
namespace linker.plugins.tuntap
|
||||
{
|
||||
@@ -56,7 +57,7 @@ namespace linker.plugins.tuntap
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
NetworkHelper.GetRouteLevel(out routeIps);
|
||||
NetworkHelper.GetRouteLevel(config.Data.Client.Server, out routeIps);
|
||||
NotifyConfig();
|
||||
CheckTuntapStatusTask();
|
||||
if (runningConfig.Data.Tuntap.Running)
|
||||
@@ -77,19 +78,17 @@ namespace linker.plugins.tuntap
|
||||
}
|
||||
Task.Run(() =>
|
||||
{
|
||||
NotifyConfig();
|
||||
SetupBefore();
|
||||
try
|
||||
{
|
||||
if (runningConfig.Data.Tuntap.IP.Equals(IPAddress.Any))
|
||||
{
|
||||
return;
|
||||
}
|
||||
linkerTunDeviceAdapter.Setup(runningConfig.Data.Tuntap.IP, 24, 1416);
|
||||
linkerTunDeviceAdapter.Setup(runningConfig.Data.Tuntap.IP, runningConfig.Data.Tuntap.PrefixLength, 1416);
|
||||
if (string.IsNullOrWhiteSpace(linkerTunDeviceAdapter.Error))
|
||||
{
|
||||
linkerTunDeviceAdapter.SetNat();
|
||||
runningConfig.Data.Tuntap.Running = true;
|
||||
runningConfig.Data.Update();
|
||||
SetupSuccess();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -102,11 +101,28 @@ namespace linker.plugins.tuntap
|
||||
}
|
||||
finally
|
||||
{
|
||||
Interlocked.Exchange(ref operating, 0);
|
||||
NotifyConfig();
|
||||
SetupAfter();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void SetupBefore()
|
||||
{
|
||||
NotifyConfig();
|
||||
}
|
||||
private void SetupAfter()
|
||||
{
|
||||
Interlocked.Exchange(ref operating, 0);
|
||||
NotifyConfig();
|
||||
}
|
||||
private void SetupSuccess()
|
||||
{
|
||||
linkerTunDeviceAdapter.SetNat();
|
||||
AddForward();
|
||||
runningConfig.Data.Tuntap.Running = true;
|
||||
runningConfig.Data.Update();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止网卡
|
||||
/// </summary>
|
||||
@@ -118,11 +134,9 @@ namespace linker.plugins.tuntap
|
||||
}
|
||||
try
|
||||
{
|
||||
NotifyConfig();
|
||||
ShutdownBefore();
|
||||
linkerTunDeviceAdapter.Shutdown();
|
||||
|
||||
runningConfig.Data.Tuntap.Running = false;
|
||||
runningConfig.Data.Update();
|
||||
ShutdownSuccess();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -132,12 +146,29 @@ namespace linker.plugins.tuntap
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
ShutdownAfter();
|
||||
}
|
||||
}
|
||||
private void ShutdownBefore()
|
||||
{
|
||||
NotifyConfig();
|
||||
}
|
||||
private void ShutdownAfter()
|
||||
{
|
||||
Interlocked.Exchange(ref operating, 0);
|
||||
NotifyConfig();
|
||||
}
|
||||
private void ShutdownSuccess()
|
||||
{
|
||||
linkerTunDeviceAdapter.RemoveNat();
|
||||
DeleteForward();
|
||||
runningConfig.Data.Tuntap.Running = false;
|
||||
runningConfig.Data.Update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 刷新信息,把自己的网卡配置发给别人,顺便把别人的网卡信息带回来
|
||||
/// </summary>
|
||||
@@ -153,10 +184,14 @@ namespace linker.plugins.tuntap
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
DeleteForward();
|
||||
runningConfig.Data.Tuntap.IP = info.IP;
|
||||
runningConfig.Data.Tuntap.LanIPs = info.LanIPs;
|
||||
runningConfig.Data.Tuntap.Masks = info.Masks;
|
||||
runningConfig.Data.Tuntap.PrefixLength = info.PrefixLength;
|
||||
runningConfig.Data.Tuntap.Gateway = info.Gateway;
|
||||
runningConfig.Data.Tuntap.Upgrade = info.Upgrade;
|
||||
runningConfig.Data.Tuntap.Forwards = info.Forwards;
|
||||
runningConfig.Data.Update();
|
||||
if (Status == TuntapStatus.Running)
|
||||
{
|
||||
@@ -165,6 +200,7 @@ namespace linker.plugins.tuntap
|
||||
}
|
||||
else
|
||||
{
|
||||
AddForward();
|
||||
NotifyConfig();
|
||||
}
|
||||
});
|
||||
@@ -204,9 +240,9 @@ namespace linker.plugins.tuntap
|
||||
{
|
||||
tuntapInfos.AddOrUpdate(item.MachineId, item, (a, b) => item);
|
||||
}
|
||||
Interlocked.Increment(ref infosVersion);
|
||||
AddRoute();
|
||||
}
|
||||
Interlocked.Increment(ref infosVersion);
|
||||
});
|
||||
}
|
||||
/// <summary>
|
||||
@@ -220,11 +256,15 @@ namespace linker.plugins.tuntap
|
||||
IP = runningConfig.Data.Tuntap.IP,
|
||||
LanIPs = runningConfig.Data.Tuntap.LanIPs,
|
||||
Masks = runningConfig.Data.Tuntap.Masks,
|
||||
PrefixLength = runningConfig.Data.Tuntap.PrefixLength,
|
||||
MachineId = config.Data.Client.Id,
|
||||
Status = Status,
|
||||
Error = linkerTunDeviceAdapter.Error,
|
||||
System = $"{System.Runtime.InteropServices.RuntimeInformation.OSDescription} {(string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")) == false ? "Docker" : "")}",
|
||||
Error1 = linkerTunDeviceAdapter.Error1,
|
||||
SystemInfo = $"{System.Runtime.InteropServices.RuntimeInformation.OSDescription} {(string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")) == false ? "Docker" : "")}",
|
||||
Gateway = runningConfig.Data.Tuntap.Gateway,
|
||||
Upgrade = runningConfig.Data.Tuntap.Upgrade,
|
||||
Forwards = runningConfig.Data.Tuntap.Forwards,
|
||||
};
|
||||
if (runningConfig.Data.Tuntap.Masks.Length != runningConfig.Data.Tuntap.LanIPs.Length)
|
||||
{
|
||||
@@ -258,17 +298,39 @@ namespace linker.plugins.tuntap
|
||||
return infos;
|
||||
}
|
||||
|
||||
|
||||
// <summary>
|
||||
/// 添加端口转发
|
||||
/// </summary>
|
||||
private void AddForward()
|
||||
{
|
||||
linkerTunDeviceAdapter.AddForward(runningConfig.Data.Tuntap.Forwards.Select(c => new LinkerTunDeviceForwardItem { ListenAddr = c.ListenAddr, ListenPort = c.ListenPort, ConnectAddr = c.ConnectAddr, ConnectPort = c.ConnectPort }).ToList());
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除端口转发
|
||||
/// </summary>
|
||||
private void DeleteForward()
|
||||
{
|
||||
linkerTunDeviceAdapter.RemoveForward(runningConfig.Data.Tuntap.Forwards.Select(c => new LinkerTunDeviceForwardItem { ListenAddr = c.ListenAddr, ListenPort = c.ListenPort, ConnectAddr = c.ConnectAddr, ConnectPort = c.ConnectPort }).ToList());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除路由
|
||||
/// </summary>
|
||||
private void DelRoute()
|
||||
{
|
||||
try
|
||||
{
|
||||
List<TuntapVeaLanIPAddressList> ipsList = ParseIPs(tuntapInfos.Values.ToList());
|
||||
TuntapVeaLanIPAddress[] ips = ipsList.SelectMany(c => c.IPS).ToArray();
|
||||
|
||||
var items = ipsList.SelectMany(c => c.IPS).Select(c => new LinkerTunDeviceRouteItem { Address = c.OriginIPAddress, PrefixLength = c.MaskLength }).ToArray();
|
||||
linkerTunDeviceAdapter.DelRoute(items, runningConfig.Data.Tuntap.Gateway);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加路由
|
||||
/// </summary>
|
||||
@@ -291,7 +353,7 @@ namespace linker.plugins.tuntap
|
||||
{
|
||||
uint[] localIps = NetworkHelper.GetIPV4()
|
||||
.Concat(new IPAddress[] { runningConfig.Data.Tuntap.IP })
|
||||
.Concat(runningConfig.Data.Tuntap.LanIPs)
|
||||
.Concat(runningConfig.Data.Tuntap.LanIPs.Where(c => c != null))
|
||||
.Concat(routeIps)
|
||||
.Select(c => BinaryPrimitives.ReadUInt32BigEndian(c.GetAddressBytes()))
|
||||
.ToArray();
|
||||
@@ -313,7 +375,7 @@ namespace linker.plugins.tuntap
|
||||
private List<TuntapVeaLanIPAddress> ParseIPs(IPAddress[] lanIPs, int[] masks)
|
||||
{
|
||||
if (masks.Length != lanIPs.Length) masks = lanIPs.Select(c => 24).ToArray();
|
||||
return lanIPs.Where(c => c.Equals(IPAddress.Any) == false).Select((c, index) =>
|
||||
return lanIPs.Where(c => c.Equals(IPAddress.Any) == false && c != null).Select((c, index) =>
|
||||
{
|
||||
return ParseIPAddress(c, (byte)masks[index]);
|
||||
|
||||
|
@@ -1,25 +1,15 @@
|
||||
using linker.plugins.tuntap.config;
|
||||
using MemoryPack;
|
||||
using System.Buffers.Binary;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.plugins.tuntap.config
|
||||
{
|
||||
public sealed class TuntapConfigInfo
|
||||
{
|
||||
private IPAddress ip = IPAddress.Any;
|
||||
/// <summary>
|
||||
/// 网卡IP
|
||||
/// </summary>
|
||||
public IPAddress IP
|
||||
{
|
||||
get => ip; set
|
||||
{
|
||||
ip = value;
|
||||
IpInt = BinaryPrimitives.ReadUInt32BigEndian(ip.GetAddressBytes());
|
||||
}
|
||||
}
|
||||
public uint IpInt { get; private set; }
|
||||
public IPAddress IP { get; set; } = IPAddress.Any;
|
||||
/// <summary>
|
||||
/// 局域网IP列表
|
||||
/// </summary>
|
||||
@@ -28,12 +18,28 @@ namespace linker.plugins.tuntap.config
|
||||
/// 局域网掩码列表,与IP列表一一对应
|
||||
/// </summary>
|
||||
public int[] Masks { get; set; } = Array.Empty<int>();
|
||||
|
||||
/// <summary>
|
||||
/// 前缀长度
|
||||
/// </summary>
|
||||
public byte PrefixLength { get; set; } = 24;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在运行中
|
||||
/// </summary>
|
||||
public bool Running { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否网关
|
||||
/// </summary>
|
||||
public bool Gateway { get; set; }
|
||||
/// <summary>
|
||||
/// 使用高级功能
|
||||
/// </summary>
|
||||
public bool Upgrade { get; set; }
|
||||
/// <summary>
|
||||
/// 端口转发列表
|
||||
/// </summary>
|
||||
public List<TuntapForwardInfo> Forwards { get; set; } = new List<TuntapForwardInfo>();
|
||||
}
|
||||
|
||||
|
||||
@@ -65,31 +71,93 @@ namespace linker.plugins.tuntap.config
|
||||
|
||||
public enum TuntapStatus : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// 无
|
||||
/// </summary>
|
||||
Normal = 0,
|
||||
/// <summary>
|
||||
/// 操作中
|
||||
/// </summary>
|
||||
Operating = 1,
|
||||
/// <summary>
|
||||
/// 运行中
|
||||
/// </summary>
|
||||
Running = 2
|
||||
}
|
||||
|
||||
[MemoryPackable]
|
||||
public sealed partial class TuntapInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备id
|
||||
/// </summary>
|
||||
public string MachineId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 虚拟网卡状态
|
||||
/// </summary>
|
||||
public TuntapStatus Status { get; set; }
|
||||
/// <summary>
|
||||
/// 虚拟网卡IP
|
||||
/// </summary>
|
||||
|
||||
[MemoryPackAllowSerialize]
|
||||
public IPAddress IP { get; set; }
|
||||
/// <summary>
|
||||
/// 局域网IP
|
||||
/// </summary>
|
||||
|
||||
[MemoryPackAllowSerialize]
|
||||
public IPAddress[] LanIPs { get; set; } = Array.Empty<IPAddress>();
|
||||
/// <summary>
|
||||
/// 局域网IP掩码
|
||||
/// </summary>
|
||||
public int[] Masks { get; set; } = Array.Empty<int>();
|
||||
|
||||
public string Error { get; set; }
|
||||
public string System { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 前缀长度
|
||||
/// </summary>
|
||||
public byte PrefixLength { get; set; } = 24;
|
||||
|
||||
/// <summary>
|
||||
/// 网卡安装错误
|
||||
/// </summary>
|
||||
public string Error { get; set; }
|
||||
/// <summary>
|
||||
/// NAT设置错误
|
||||
/// </summary>
|
||||
public string Error1 { get; set; }
|
||||
/// <summary>
|
||||
/// 系统信息
|
||||
/// </summary>
|
||||
public string SystemInfo { get; set; }
|
||||
/// <summary>
|
||||
/// 是否网关
|
||||
/// </summary>
|
||||
public bool Gateway { get; set; }
|
||||
/// <summary>
|
||||
/// 使用高级功能
|
||||
/// </summary>
|
||||
public bool Upgrade { get; set; }
|
||||
/// <summary>
|
||||
/// 端口转发列表
|
||||
/// </summary>
|
||||
public List<TuntapForwardInfo> Forwards { get; set; } = new List<TuntapForwardInfo>();
|
||||
}
|
||||
|
||||
|
||||
[MemoryPackable]
|
||||
public sealed partial class TuntapForwardInfo
|
||||
{
|
||||
[MemoryPackAllowSerialize]
|
||||
public IPAddress ListenAddr { get; set; } = IPAddress.Any;
|
||||
public int ListenPort { get; set; }
|
||||
|
||||
[MemoryPackAllowSerialize]
|
||||
public IPAddress ConnectAddr { get; set; } = IPAddress.Any;
|
||||
public int ConnectPort { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -156,6 +156,8 @@ namespace linker.plugins.tuntap.messenger
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Task.WhenAll(tasks).ContinueWith(async (result) =>
|
||||
{
|
||||
List<TuntapInfo> results = tasks.Where(c => c.Result.Code == MessageResponeCodes.OK)
|
||||
|
@@ -12,7 +12,6 @@ call npm run build
|
||||
cd ../
|
||||
|
||||
for %%r in (win-x64,win-arm64) do (
|
||||
dotnet publish ./linker.service -c release -f net8.0 -o public/extends/%%r/linker-%%r/ -r %%r -p:PublishAot=true -p:PublishTrimmed=true --self-contained true -p:TieredPGO=true -p:DebugType=none -p:DebugSymbols=false -p:EnableCompressionInSingleFile=true -p:DebuggerSupport=false -p:EnableUnsafeBinaryFormatterSerialization=false -p:EnableUnsafeUTF7Encoding=false -p:HttpActivityPropagationSupport=false -p:InvariantGlobalization=true -p:MetadataUpdaterSupport=false -p:UseSystemResourceKeys=true
|
||||
echo F|xcopy "linker.tray.win\\dist\\*" "public\\extends\\%%r\\linker-%%r\\*" /s /f /h /y
|
||||
echo F|xcopy "linker\\msquic.dll" "public\\extends\\%%r\\linker-%%r\\msquic.dll" /s /f /h /y
|
||||
echo F|xcopy "linker\\msquic-%%r.dll" "public\\extends\\%%r\\linker-%%r\\msquic.dll" /s /f /h /y
|
||||
|