测试UPNP

This commit is contained in:
snltty
2024-10-07 14:13:22 +08:00
parent 1db1f335db
commit 50d4689f57
33 changed files with 259 additions and 122 deletions

View File

@@ -33,11 +33,11 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.ACTIONS_TOKEN }}
with:
tag_name: v1.4.7
release_name: v1.4.7.${{ steps.date.outputs.today }}
tag_name: v1.4.8
release_name: v1.4.8.${{ steps.date.outputs.today }}
draft: false
prerelease: false
body: "1. 优化流量统计\r\n2. 修复可能的获取设备码失败的问题"
body: "1. 优化减少信标流量\r\n2. 增加upnp和NAT-PMP自动添加端口映射在无法进路由器时很有用\r\n3. 可选禁用UDP广播可有效减少中继流量消耗\r\n4. 测试中,请勿更新!请勿更新!请勿更新!"
- name: upload-win-x86-oss
id: upload-win-x86-oss
uses: tvrcgo/oss-action@v0.1.1
@@ -47,7 +47,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-x86.zip
target-path: /downloads/linker/v1.4.7/linker-win-x86.zip
target-path: /downloads/linker/v1.4.8/linker-win-x86.zip
- name: upload-win-x86
id: upload-win-x86
uses: actions/upload-release-asset@master
@@ -67,7 +67,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-x64.zip
target-path: /downloads/linker/v1.4.7/linker-win-x64.zip
target-path: /downloads/linker/v1.4.8/linker-win-x64.zip
- name: upload-win-x64
id: upload-win-x64
uses: actions/upload-release-asset@master
@@ -87,7 +87,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-arm64.zip
target-path: /downloads/linker/v1.4.7/linker-win-arm64.zip
target-path: /downloads/linker/v1.4.8/linker-win-arm64.zip
- name: upload-win-arm64
id: upload-win-arm64
uses: actions/upload-release-asset@master
@@ -107,7 +107,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-x64.zip
target-path: /downloads/linker/v1.4.7/linker-linux-x64.zip
target-path: /downloads/linker/v1.4.8/linker-linux-x64.zip
- name: upload-linux-x64
id: upload-linux-x64
uses: actions/upload-release-asset@master
@@ -127,7 +127,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-arm.zip
target-path: /downloads/linker/v1.4.7/linker-linux-arm.zip
target-path: /downloads/linker/v1.4.8/linker-linux-arm.zip
- name: upload-linux-arm
id: upload-linux-arm
uses: actions/upload-release-asset@master
@@ -147,7 +147,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-arm64.zip
target-path: /downloads/linker/v1.4.7/linker-linux-arm64.zip
target-path: /downloads/linker/v1.4.8/linker-linux-arm64.zip
- name: upload-linux-arm64
id: upload-linux-arm64
uses: actions/upload-release-asset@master
@@ -167,7 +167,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-x64.zip
target-path: /downloads/linker/v1.4.7/linker-linux-musl-x64.zip
target-path: /downloads/linker/v1.4.8/linker-linux-musl-x64.zip
- name: upload-linux-musl-x64
id: upload-linux-musl-x64
uses: actions/upload-release-asset@master
@@ -187,7 +187,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-arm.zip
target-path: /downloads/linker/v1.4.7/linker-linux-musl-arm.zip
target-path: /downloads/linker/v1.4.8/linker-linux-musl-arm.zip
- name: upload-linux-musl-arm
id: upload-linux-musl-arm
uses: actions/upload-release-asset@master
@@ -207,7 +207,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-arm64.zip
target-path: /downloads/linker/v1.4.7/linker-linux-musl-arm64.zip
target-path: /downloads/linker/v1.4.8/linker-linux-musl-arm64.zip
- name: upload-linux-musl-arm64
id: upload-linux-musl-arm64
uses: actions/upload-release-asset@master
@@ -227,7 +227,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-osx-x64.zip
target-path: /downloads/linker/v1.4.7/linker-osx-x64.zip
target-path: /downloads/linker/v1.4.8/linker-osx-x64.zip
- name: upload-osx-x64
id: upload-osx-x64
uses: actions/upload-release-asset@master
@@ -247,7 +247,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-osx-arm64.zip
target-path: /downloads/linker/v1.4.7/linker-osx-arm64.zip
target-path: /downloads/linker/v1.4.8/linker-osx-arm64.zip
- name: upload-osx-arm64
id: upload-osx-arm64
uses: actions/upload-release-asset@master
@@ -277,7 +277,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-windows-route.zip
target-path: /downloads/linker/v1.4.7/linker-windows-route.zip
target-path: /downloads/linker/v1.4.8/linker-windows-route.zip
- name: upload-windows-route
id: upload-windows-route
uses: actions/upload-release-asset@master

View File

@@ -38,6 +38,6 @@ jobs:
- name: Push
run: |
nuget push ./linker.tunnel/bin/release/linker.tunnel.1.4.7.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol
nuget push ./linker.libs/bin/release/linker.libs.1.4.7.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol
nuget push ./linker.tun/bin/release/linker.tun.1.4.7.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol
nuget push ./linker.tunnel/bin/release/linker.tunnel.1.4.8.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol
nuget push ./linker.libs/bin/release/linker.libs.1.4.8.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol
nuget push ./linker.tun/bin/release/linker.tun.1.4.8.nupkg -Source https://api.nuget.org/v3/index.json -SkipDuplicate -ApiKey ${{ secrets.NUGET_KEY }} -NoSymbol

View File

@@ -10,7 +10,17 @@ namespace linker.libs
public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
public static void FlushMemory()
{
try
{
GC.RefreshMemoryLimit();
}
catch (Exception)
{
}
GC.Collect();
GC.Collect(2, GCCollectionMode.Aggressive);
GC.SuppressFinalize(true);
GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT)

View File

@@ -14,9 +14,9 @@
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<Version>1.4.7</Version>
<AssemblyVersion>1.4.7</AssemblyVersion>
<FileVersion>1.4.7</FileVersion>
<Version>1.4.8</Version>
<AssemblyVersion>1.4.8</AssemblyVersion>
<FileVersion>1.4.8</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>

View File

@@ -15,8 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.tun", "linker.tun\li
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "linker.tun.test", "linker.tun.test\linker.tun.test.csproj", "{4A660D3B-76DE-4E6F-9E90-90BA0DBE906A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linker.upnp", "linker.upnp\linker.upnp.csproj", "{11D9B478-A713-44BD-A702-EA8FC254774D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -99,18 +97,6 @@ Global
{4A660D3B-76DE-4E6F-9E90-90BA0DBE906A}.Release|x64.Build.0 = Release|Any CPU
{4A660D3B-76DE-4E6F-9E90-90BA0DBE906A}.Release|x86.ActiveCfg = Release|Any CPU
{4A660D3B-76DE-4E6F-9E90-90BA0DBE906A}.Release|x86.Build.0 = Release|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Debug|x64.ActiveCfg = Debug|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Debug|x64.Build.0 = Debug|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Debug|x86.ActiveCfg = Debug|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Debug|x86.Build.0 = Debug|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Release|Any CPU.Build.0 = Release|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Release|x64.ActiveCfg = Release|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Release|x64.Build.0 = Release|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Release|x86.ActiveCfg = Release|Any CPU
{11D9B478-A713-44BD-A702-EA8FC254774D}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -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.127" ProductVersion="0.0.0.127" 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.128" ProductVersion="0.0.0.128" 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"/>

Binary file not shown.

View File

@@ -1 +1 @@
.dropdown[data-v-1e7a30d3]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-1e7a30d3]{vertical-align:middle}.dropdown .badge[data-v-1e7a30d3]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}a[data-v-56d38c60]{color:#666;text-decoration:underline}a.green[data-v-56d38c60]{color:green;font-weight:700}a.download[data-v-56d38c60]{margin-left:.6rem}a.download .el-icon[data-v-56d38c60]{vertical-align:middle;font-weight:700;margin-left:.3rem}a.download .el-icon.loading[data-v-56d38c60]{animation:loading-56d38c60 1s linear infinite}@keyframes loading-56d38c60{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a[data-v-a998806a]{color:#666;text-decoration:underline}a.green[data-v-a998806a]{color:green;font-weight:700}img.system[data-v-a998806a]{height:1.6rem;vertical-align:middle;margin-right:.4rem}.ipaddress span[data-v-358fba0e]{vertical-align:middle}.el-input[data-v-358fba0e]{width:15rem;margin-right:.6rem}.el-col[data-v-bdd023b0]{text-align:left}.el-icon.loading[data-v-3b6dbb12],a.loading[data-v-3b6dbb12]{vertical-align:middle;font-weight:700;animation:loading-3b6dbb12 1s linear infinite}.el-switch.is-disabled[data-v-3b6dbb12]{opacity:1}.el-input[data-v-3b6dbb12]{width:8rem}.gateway[data-v-3b6dbb12]{background:linear-gradient(90deg,#c5b260,#858585,#c5b260,#858585);-webkit-background-clip:text;-webkit-text-fill-color:hsla(0,0%,100%,0)}.gateway.green[data-v-3b6dbb12]{background:linear-gradient(90deg,#e4bb10,green,#e4bb10,green);-webkit-background-clip:text;-webkit-text-fill-color:hsla(0,0%,100%,0)}.delay[data-v-3b6dbb12]{position:absolute;right:0;bottom:0;line-height:normal}.switch-btn[data-v-3b6dbb12]{font-size:1.5rem}@keyframes loading-3b6dbb12{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.el-switch.is-disabled[data-v-7c827302]{opacity:1}.upgrade-wrap[data-v-7c827302]{border:1px solid #ddd;margin-bottom:2rem;padding:0 0 1rem 0}.el-switch.is-disabled[data-v-56597dfc]{opacity:1}.green[data-v-56597dfc]{font-weight:700}.el-switch.is-disabled[data-v-1f7f67a4]{opacity:1}a[data-v-19db1f43]{text-decoration:underline;font-weight:700}.head[data-v-7b79db4a]{padding-bottom:1rem}.green[data-v-7b79db4a]{color:green;font-weight:700}.error[data-v-7b79db4a]{font-weight:700}.error .el-icon[data-v-7b79db4a]{vertical-align:text-bottom}.el-select[data-v-3a13c86f]{width:12rem}.head[data-v-3a13c86f]{padding-bottom:1rem}.foot[data-v-3a13c86f]{padding-top:1rem}.page-wrap[data-v-3a13c86f]{display:inline-block}.head[data-v-48a6af94]{padding-bottom:1rem}.error[data-v-48a6af94]{font-weight:700}.error .el-icon[data-v-48a6af94]{vertical-align:text-bottom}.el-select[data-v-5512121a]{width:12rem}.head[data-v-5512121a]{padding-bottom:1rem}.foot[data-v-5512121a]{padding-top:1rem}.page-wrap[data-v-5512121a]{display:inline-block}.head[data-v-337b0bab]{padding-bottom:1rem}.table-sort.el-table th.el-table__cell.is-leaf{border-bottom:0}.table-sort.el-table .el-table__inner-wrapper:before{height:0}.table-sort th[data-v-137c2b43]{border-bottom:0}.home-list-wrap[data-v-137c2b43]{padding:1rem}.home-list-wrap .page[data-v-137c2b43]{padding-top:1rem}.home-list-wrap .page-wrap[data-v-137c2b43]{display:inline-block}
.dropdown[data-v-1e7a30d3]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-1e7a30d3]{vertical-align:middle}.dropdown .badge[data-v-1e7a30d3]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}a[data-v-56d38c60]{color:#666;text-decoration:underline}a.green[data-v-56d38c60]{color:green;font-weight:700}a.download[data-v-56d38c60]{margin-left:.6rem}a.download .el-icon[data-v-56d38c60]{vertical-align:middle;font-weight:700;margin-left:.3rem}a.download .el-icon.loading[data-v-56d38c60]{animation:loading-56d38c60 1s linear infinite}@keyframes loading-56d38c60{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a[data-v-a998806a]{color:#666;text-decoration:underline}a.green[data-v-a998806a]{color:green;font-weight:700}img.system[data-v-a998806a]{height:1.6rem;vertical-align:middle;margin-right:.4rem}.ipaddress span[data-v-358fba0e]{vertical-align:middle}.el-input[data-v-358fba0e]{width:15rem;margin-right:.6rem}.el-col[data-v-bdd023b0]{text-align:left}.el-icon.loading[data-v-3b6dbb12],a.loading[data-v-3b6dbb12]{vertical-align:middle;font-weight:700;animation:loading-3b6dbb12 1s linear infinite}.el-switch.is-disabled[data-v-3b6dbb12]{opacity:1}.el-input[data-v-3b6dbb12]{width:8rem}.gateway[data-v-3b6dbb12]{background:linear-gradient(90deg,#c5b260,#858585,#c5b260,#858585);-webkit-background-clip:text;-webkit-text-fill-color:hsla(0,0%,100%,0)}.gateway.green[data-v-3b6dbb12]{background:linear-gradient(90deg,#e4bb10,green,#e4bb10,green);-webkit-background-clip:text;-webkit-text-fill-color:hsla(0,0%,100%,0)}.delay[data-v-3b6dbb12]{position:absolute;right:0;bottom:0;line-height:normal}.switch-btn[data-v-3b6dbb12]{font-size:1.5rem}@keyframes loading-3b6dbb12{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.el-switch.is-disabled[data-v-1c4321be]{opacity:1}.upgrade-wrap[data-v-1c4321be]{border:1px solid #ddd;margin-bottom:2rem;padding:0 0 1rem 0}.el-switch.is-disabled[data-v-56597dfc]{opacity:1}.green[data-v-56597dfc]{font-weight:700}.el-switch.is-disabled[data-v-1f7f67a4]{opacity:1}a[data-v-19db1f43]{text-decoration:underline;font-weight:700}.head[data-v-7b79db4a]{padding-bottom:1rem}.green[data-v-7b79db4a]{color:green;font-weight:700}.error[data-v-7b79db4a]{font-weight:700}.error .el-icon[data-v-7b79db4a]{vertical-align:text-bottom}.el-select[data-v-3a13c86f]{width:12rem}.head[data-v-3a13c86f]{padding-bottom:1rem}.foot[data-v-3a13c86f]{padding-top:1rem}.page-wrap[data-v-3a13c86f]{display:inline-block}.head[data-v-48a6af94]{padding-bottom:1rem}.error[data-v-48a6af94]{font-weight:700}.error .el-icon[data-v-48a6af94]{vertical-align:text-bottom}.el-select[data-v-5512121a]{width:12rem}.head[data-v-5512121a]{padding-bottom:1rem}.foot[data-v-5512121a]{padding-top:1rem}.page-wrap[data-v-5512121a]{display:inline-block}.head[data-v-337b0bab]{padding-bottom:1rem}.table-sort.el-table th.el-table__cell.is-leaf{border-bottom:0}.table-sort.el-table .el-table__inner-wrapper:before{height:0}.table-sort th[data-v-137c2b43]{border-bottom:0}.home-list-wrap[data-v-137c2b43]{padding:1rem}.home-list-wrap .page[data-v-137c2b43]{padding-top:1rem}.home-list-wrap .page-wrap[data-v-137c2b43]{display:inline-block}

View File

@@ -1 +1 @@
.green[data-v-2ea70464],.red[data-v-2ea70464]{font-weight:700}.servers-wrap[data-v-74a22754]{padding:1rem;font-size:1.3rem;color:#555}.servers-wrap a[data-v-74a22754]{color:#333}.el-checkbox[data-v-74a22754]{vertical-align:middle;margin-right:1rem}
.green[data-v-482b6000],.red[data-v-482b6000]{font-weight:700}.servers-wrap[data-v-74a22754]{padding:1rem;font-size:1.3rem;color:#555}.servers-wrap a[data-v-74a22754]{color:#333}.el-checkbox[data-v-74a22754]{vertical-align:middle;margin-right:1rem}

View File

@@ -1 +1 @@
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><script defer="defer" src="js/chunk-vendors.ac5be1e1.js"></script><script defer="defer" src="js/app.59f241f7.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.acc92c6f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><script defer="defer" src="js/chunk-vendors.ac5be1e1.js"></script><script defer="defer" src="js/app.4b319136.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.acc92c6f.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -16,9 +16,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker tun</PackageReleaseNotes>
<Version>1.4.7</Version>
<AssemblyVersion>1.4.7</AssemblyVersion>
<FileVersion>1.4.7</FileVersion>
<Version>1.4.8</Version>
<AssemblyVersion>1.4.8</AssemblyVersion>
<FileVersion>1.4.8</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -0,0 +1,105 @@
using linker.libs;
using Mono.Nat;
using System.Collections.Concurrent;
namespace linker.tunnel
{
public sealed class TunnelUpnpTransfer
{
private readonly SemaphoreSlim locker = new SemaphoreSlim(1, 1);
private readonly ConcurrentDictionary<NatProtocol, INatDevice> natDevices = new ConcurrentDictionary<NatProtocol, INatDevice>();
public MapInfo MapInfo { get; private set; }
public TunnelUpnpTransfer()
{
NatUtility.DeviceFound += DeviceFound;
NatUtility.StartDiscovery();
LoopDiscovery();
}
private void LoopDiscovery()
{
TimerHelper.SetInterval(() =>
{
NatUtility.StopDiscovery();
NatUtility.StartDiscovery();
return true;
}, 60 * 1000);
}
private void DeviceFound(object sender, DeviceEventArgs args)
{
INatDevice device = args.Device;
if (natDevices.Count == 0 || natDevices.TryGetValue(device.NatProtocol, out INatDevice _device))
{
natDevices.AddOrUpdate(device.NatProtocol, device, (a, b) => device);
}
AddMap();
}
private void AddMap()
{
if (natDevices.Count == 0 || MapInfo == null) return;
TimerHelper.Async(async () =>
{
await locker.WaitAsync();
INatDevice device = natDevices.FirstOrDefault().Value;
try
{
if (await HasMap(device, Protocol.Tcp, MapInfo.PublicPort) == false)
{
Mapping mapping = new Mapping(Protocol.Tcp, MapInfo.PrivatePort, MapInfo.PublicPort, 720, $"linker-tcp-{MapInfo.PublicPort}-{MapInfo.PrivatePort}");
await device.CreatePortMapAsync(mapping);
Mapping m = await device.GetSpecificMappingAsync(Protocol.Tcp, mapping.PublicPort);
}
}
catch
{
}
try
{
if (await HasMap(device, Protocol.Udp, MapInfo.PublicPort) == false)
{
Mapping mapping = new Mapping(Protocol.Udp, MapInfo.PrivatePort, MapInfo.PublicPort, 720, $"linker-udp-{MapInfo.PublicPort}-{MapInfo.PrivatePort}");
await device.CreatePortMapAsync(mapping);
Mapping m = await device.GetSpecificMappingAsync(Protocol.Udp, mapping.PublicPort);
}
}
catch
{
}
locker.Release();
});
}
private async Task<bool> HasMap(INatDevice device, Protocol protocol, int publicPort)
{
try
{
Mapping m = await device.GetSpecificMappingAsync(protocol, publicPort);
return true;
}
catch (Exception)
{
}
return false;
}
public void SetMap(int privatePort, int publicPort)
{
MapInfo = new MapInfo { PrivatePort = privatePort, PublicPort = publicPort };
}
}
public sealed class MapInfo
{
public int PrivatePort { get; set; }
public int PublicPort { get; set; }
}
}

View File

@@ -16,9 +16,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker tunnel</PackageReleaseNotes>
<Version>1.4.7</Version>
<AssemblyVersion>1.4.7</AssemblyVersion>
<FileVersion>1.4.7</FileVersion>
<Version>1.4.8</Version>
<AssemblyVersion>1.4.8</AssemblyVersion>
<FileVersion>1.4.8</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -30,6 +30,9 @@
<DebugSymbols>false</DebugSymbols>
<Optimize>True</Optimize>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Mono.Nat" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\linker.libs\linker.libs.csproj" />

View File

@@ -1,41 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishAot>false</PublishAot>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<Title>linker upnp</Title>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>linker upnp</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker upnp</PackageReleaseNotes>
<Version>1.4.7</Version>
<AssemblyVersion>1.4.7</AssemblyVersion>
<FileVersion>1.4.7</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="Mono.Nat" Version="3.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\linker.libs\linker.libs.csproj" />
</ItemGroup>
</Project>

View File

@@ -6,3 +6,6 @@ export const getRelayTypes = () => {
export const setRelayServers = (servers) => {
return sendWebsocketMsg('relay/SetServers', servers);
}
export const setRelaySubscribe = () => {
return sendWebsocketMsg('relay/Subscribe');
}

View File

@@ -12,11 +12,7 @@
<span style="width: 2rem;"></span>
<el-checkbox v-model="state.ruleForm.ShowDelay" label="显示延迟" size="large" />
<el-checkbox v-model="state.ruleForm.AutoConnect" label="自动连接" size="large" />
<!-- <el-popover placement="top" title="提示" :width="400" trigger="hover" content="当有大量客户端使用中继是,广播会使用服务器更多流量" >
<template #reference>
<el-checkbox v-model="state.ruleForm.Multicast" label="启用广播" size="large" />
</template>
</el-popover> -->
<el-checkbox v-model="state.ruleForm.Multicast" label="禁用广播" size="large" />
</el-form-item>
<el-form-item prop="upgrade" style="margin-bottom:0">
<el-checkbox v-model="state.ruleForm.Upgrade" label="我很懂,我要使用高级功能(点对网和网对网)" size="large" />

View File

@@ -78,10 +78,10 @@
</el-table>
</template>
<script>
import { setRelayServers,getRelayTypes } from '@/apis/relay';
import { setRelayServers,getRelayTypes, setRelaySubscribe } from '@/apis/relay';
import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus';
import { computed, inject, onMounted, reactive, watch } from 'vue'
import { computed, inject, onMounted, onUnmounted, reactive, watch } from 'vue'
import { Delete,Plus,Top,Bottom } from '@element-plus/icons-vue';
export default {
label:'中继服务器',
@@ -93,7 +93,8 @@ export default {
const state = reactive({
list:globalData.value.config.Client.Relay.Servers.sort((a,b)=>a.Disabled - b.Disabled),
types:[],
height: computed(()=>globalData.value.height-90)
height: computed(()=>globalData.value.height-90),
timer:0
});
watch(()=>globalData.value.config.Client.Relay.Servers,()=>{
if(state.list.filter(c=>c['__editing']).length == 0){
@@ -158,9 +159,20 @@ export default {
});;
}
const _setRelaySubscribe = ()=>{
setRelaySubscribe().then(()=>{
state.timer = setTimeout(_setRelaySubscribe,1000);
}).catch(()=>{
state.timer = setTimeout(_setRelaySubscribe,1000);
});
}
onMounted(()=>{
_getRelayTypes();
_setRelaySubscribe();
});
onUnmounted(()=>{
clearTimeout(state.timer);
})
return {state,handleCellClick,handleEditBlur,handleDel,handleAdd,handleSort}
}

View File

@@ -19,15 +19,17 @@
<Title>linker</Title>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>1. 优化流量统计
2. 修复可能的获取设备码失败的问题</Description>
<Description>1. 优化减少信标流量
2. 增加upnp和NAT-PMP自动添加端口映射在无法进路由器时很有用
3. 可选禁用UDP广播可有效减少中继流量消耗
4. 测试中,请勿更新!请勿更新!请勿更新!</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker</PackageReleaseNotes>
<Version>1.4.7</Version>
<AssemblyVersion>1.4.7</AssemblyVersion>
<FileVersion>1.4.7</FileVersion>
<Version>1.4.8</Version>
<AssemblyVersion>1.4.8</AssemblyVersion>
<FileVersion>1.4.8</FileVersion>
</PropertyGroup>

View File

@@ -2,11 +2,9 @@
using linker.plugins.relay.messenger;
using linker.libs.api;
using linker.libs.extends;
using MemoryPack;
using linker.plugins.client;
using linker.plugins.capi;
using linker.plugins.messenger;
using linker.client.config;
namespace linker.plugins.relay
{
@@ -48,6 +46,11 @@ namespace linker.plugins.relay
relayTransfer.SetServers(info);
return true;
}
public void Subscribe(ApiControllerParamsInfo param)
{
relayTransfer.SubscribeDelayTest();
}
}
}

View File

@@ -263,6 +263,12 @@ namespace linker.plugins.relay
}
private readonly LastTicksManager lastTicksManager = new LastTicksManager();
public void SubscribeDelayTest()
{
lastTicksManager.Update();
}
private async Task TaskRelay()
{
try
@@ -290,10 +296,13 @@ namespace linker.plugins.relay
private void TestTask()
{
TimerHelper.SetInterval(async () =>
{
if (lastTicksManager.DiffLessEqual(3000))
{
await TaskRelay();
}
return true;
}, 5000);
}, 1000);
}
sealed class TestInfo
{

View File

@@ -12,6 +12,7 @@ using System.Buffers.Binary;
using linker.plugins.client;
using linker.plugins.messenger;
using linker.plugins.tunnel.excludeip;
using linker.tunnel;
namespace linker.plugins.tunnel
{
@@ -21,21 +22,26 @@ namespace linker.plugins.tunnel
? running.Data.Tunnel.Interface : (clientSignInState.Connection?.LocalAddress.Address ?? IPAddress.Any);
public X509Certificate2 Certificate { get; private set; }
public PortMapInfo PortMap => new PortMapInfo { WanPort = running.Data.Tunnel.PortMapWan, LanPort = running.Data.Tunnel.PortMapLan };
public PortMapInfo PortMap => running.Data.Tunnel.PortMapWan > 0
? new PortMapInfo { WanPort = running.Data.Tunnel.PortMapWan, LanPort = running.Data.Tunnel.PortMapLan }
: upnpTransfer.MapInfo != null ? new PortMapInfo { WanPort = upnpTransfer.MapInfo.PublicPort, LanPort = upnpTransfer.MapInfo.PrivatePort }
: new PortMapInfo { WanPort = 0, LanPort = 0 };
private readonly ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender;
private readonly FileConfig config;
private readonly RunningConfig running;
private readonly TunnelExcludeIPTransfer excludeIPTransfer;
private readonly TunnelUpnpTransfer upnpTransfer;
public TunnelAdapter(ClientSignInState clientSignInState, MessengerSender messengerSender, FileConfig config, RunningConfig running, TunnelExcludeIPTransfer excludeIPTransfer)
public TunnelAdapter(ClientSignInState clientSignInState, MessengerSender messengerSender, FileConfig config, RunningConfig running, TunnelExcludeIPTransfer excludeIPTransfer, TunnelUpnpTransfer upnpTransfer)
{
this.clientSignInState = clientSignInState;
this.messengerSender = messengerSender;
this.config = config;
this.running = running;
this.excludeIPTransfer = excludeIPTransfer;
this.upnpTransfer = upnpTransfer;
string path = Path.GetFullPath(config.Data.Client.Certificate);
if (File.Exists(path))

View File

@@ -4,6 +4,7 @@ using linker.libs;
using linker.plugins.client;
using linker.plugins.messenger;
using linker.plugins.tunnel.messenger;
using linker.tunnel;
using linker.tunnel.adapter;
using linker.tunnel.transport;
using linker.tunnel.wanport;
@@ -23,11 +24,12 @@ namespace linker.plugins.tunnel
private readonly ITunnelAdapter tunnelAdapter;
private readonly TransportTcpPortMap transportTcpPortMap;
private readonly TransportUdpPortMap transportUdpPortMap;
private readonly TunnelUpnpTransfer upnpTransfer;
public VersionManager Version { get; } = new VersionManager();
public ConcurrentDictionary<string, TunnelTransportRouteLevelInfo> Config { get; } = new ConcurrentDictionary<string, TunnelTransportRouteLevelInfo>();
public TunnelConfigTransfer(FileConfig config, RunningConfig running, ClientSignInState clientSignInState, MessengerSender messengerSender, ITunnelAdapter tunnelAdapter, TransportTcpPortMap transportTcpPortMap, TransportUdpPortMap transportUdpPortMap)
public TunnelConfigTransfer(FileConfig config, RunningConfig running, ClientSignInState clientSignInState, MessengerSender messengerSender, ITunnelAdapter tunnelAdapter, TransportTcpPortMap transportTcpPortMap, TransportUdpPortMap transportUdpPortMap, TunnelUpnpTransfer upnpTransfer)
{
this.config = config;
this.running = running;
@@ -36,6 +38,7 @@ namespace linker.plugins.tunnel
this.tunnelAdapter = tunnelAdapter;
this.transportTcpPortMap = transportTcpPortMap;
this.transportUdpPortMap = transportUdpPortMap;
this.upnpTransfer = upnpTransfer;
InitRouteLevel();
@@ -213,9 +216,27 @@ namespace linker.plugins.tunnel
private void RefreshPortMap()
{
try
{
int port = 18000;
int ip = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(c => c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).GetAddressBytes()[3];
upnpTransfer.SetMap(port + ip, port);
}
catch (Exception)
{
}
if (running.Data.Tunnel.PortMapLan > 0)
{
_ = transportTcpPortMap.Listen(running.Data.Tunnel.PortMapLan);
_ = transportUdpPortMap.Listen(running.Data.Tunnel.PortMapLan);
}
else if (upnpTransfer.MapInfo != null)
{
_ = transportTcpPortMap.Listen(upnpTransfer.MapInfo.PrivatePort);
_ = transportUdpPortMap.Listen(upnpTransfer.MapInfo.PrivatePort);
}
}
}

View File

@@ -85,6 +85,9 @@ namespace linker.plugins.tunnel
serviceCollection.AddSingleton<TunnelServerMessenger>();
serviceCollection.AddSingleton<ExternalResolver>();
serviceCollection.AddSingleton<TunnelUpnpTransfer>();
}
public void UseClient(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
@@ -108,6 +111,8 @@ namespace linker.plugins.tunnel
TunnelExcludeIPTransfer excludeIPTransfer = serviceProvider.GetService<TunnelExcludeIPTransfer>();
excludeIPTransfer.Load(assemblies);
TunnelUpnpTransfer upnpTransfer = serviceProvider.GetService<TunnelUpnpTransfer>();
}
public void UseServer(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)

View File

@@ -10,6 +10,7 @@ using System.Buffers.Binary;
using linker.plugins.client;
using linker.plugins.tunnel;
using System.Buffers;
using linker.client.config;
namespace linker.plugins.tuntap
{
@@ -25,11 +26,13 @@ namespace linker.plugins.tuntap
private string groupid = string.Empty;
private readonly FileConfig config;
private readonly RunningConfig runningConfig;
public TuntapProxy(FileConfig config, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer , LinkerTunDeviceAdapter linkerTunDeviceAdapter, ClientSignInState clientSignInState)
public TuntapProxy(FileConfig config, RunningConfig runningConfig, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer, LinkerTunDeviceAdapter linkerTunDeviceAdapter, ClientSignInState clientSignInState)
: base(config, tunnelTransfer, relayTransfer, clientSignInTransfer, clientSignInState)
{
this.config = config;
this.runningConfig = runningConfig;
this.linkerTunDeviceAdapter = linkerTunDeviceAdapter;
clientSignInState.NetworkEnabledHandle += (times) => ClearIPs();
}
@@ -86,7 +89,7 @@ namespace linker.plugins.tuntap
//IPV4广播组播
if (packet.IPV4Broadcast)
{
if (connections.IsEmpty == false)
if (connections.IsEmpty == false && (runningConfig.Data.Tuntap.Switch & TuntapSwitch.Multicast) == 0)
{
await Task.WhenAll(connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Packet)));
}
@@ -95,7 +98,7 @@ namespace linker.plugins.tuntap
//IPV6 多播
else if (packet.IPV6Multicast)
{
if (connections.IsEmpty == false)
if (connections.IsEmpty == false && (runningConfig.Data.Tuntap.Switch & TuntapSwitch.Multicast) == 0)
{
await Task.WhenAll(connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Packet)));
}

View File

@@ -246,7 +246,7 @@ namespace linker.plugins.tuntap
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Debug($"tuntap got {info.MachineId}->{info.IP}");
LoggerHelper.Instance.Debug($"tuntap got {info.IP}");
}
TimerHelper.Async(async () =>

View File

@@ -286,9 +286,21 @@ namespace linker.plugins.tuntap.config
public enum TuntapSwitch
{
Gateway = 1,
/// <summary>
/// 启用显示延迟
/// </summary>
ShowDelay = 2,
/// <summary>
/// 启用高级功能
/// </summary>
Upgrade = 4,
/// <summary>
/// 启用自动连接
/// </summary>
AutoConnect = 8,
/// <summary>
/// 禁用广播
/// </summary>
Multicast = 16,
}

View File

@@ -1,4 +1,6 @@
v1.4.7
2024-10-01 22:40:51
1. 优化流量统计
2. 修复可能的获取设备码失败的问题
v1.4.8
2024-10-07 14:13:22
1. 优化减少信标流量
2. 增加upnp和NAT-PMP自动添加端口映射在无法进路由器时很有用
3. 可选禁用UDP广播可有效减少中继流量消耗
4. 测试中,请勿更新!请勿更新!请勿更新!