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

View File

@@ -38,6 +38,6 @@ jobs:
- name: Push - name: Push
run: | 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.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.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.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.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.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 extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
public static void FlushMemory() public static void FlushMemory()
{ {
try
{
GC.RefreshMemoryLimit();
}
catch (Exception)
{
}
GC.Collect(); GC.Collect();
GC.Collect(2, GCCollectionMode.Aggressive);
GC.SuppressFinalize(true); GC.SuppressFinalize(true);
GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers();
if (Environment.OSVersion.Platform == PlatformID.Win32NT) if (Environment.OSVersion.Platform == PlatformID.Win32NT)

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?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"/> <file name="main.aardio" path="main.aardio" comment="main.aardio"/>
<folder name="资源文件" path="res" embed="true" local="false" ignored="false"> <folder name="资源文件" path="res" embed="true" local="false" ignored="false">
<file name="favicon.ico" path="res\favicon.ico" comment="res\favicon.ico"/> <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> <PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl> <RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker tun</PackageReleaseNotes> <PackageReleaseNotes>linker tun</PackageReleaseNotes>
<Version>1.4.7</Version> <Version>1.4.8</Version>
<AssemblyVersion>1.4.7</AssemblyVersion> <AssemblyVersion>1.4.8</AssemblyVersion>
<FileVersion>1.4.7</FileVersion> <FileVersion>1.4.8</FileVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <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> <PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl> <RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker tunnel</PackageReleaseNotes> <PackageReleaseNotes>linker tunnel</PackageReleaseNotes>
<Version>1.4.7</Version> <Version>1.4.8</Version>
<AssemblyVersion>1.4.7</AssemblyVersion> <AssemblyVersion>1.4.8</AssemblyVersion>
<FileVersion>1.4.7</FileVersion> <FileVersion>1.4.8</FileVersion>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -30,6 +30,9 @@
<DebugSymbols>false</DebugSymbols> <DebugSymbols>false</DebugSymbols>
<Optimize>True</Optimize> <Optimize>True</Optimize>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Mono.Nat" Version="3.0.4" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\linker.libs\linker.libs.csproj" /> <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) => { export const setRelayServers = (servers) => {
return sendWebsocketMsg('relay/SetServers', servers); return sendWebsocketMsg('relay/SetServers', servers);
} }
export const setRelaySubscribe = () => {
return sendWebsocketMsg('relay/Subscribe');
}

View File

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

View File

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

View File

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

View File

@@ -2,11 +2,9 @@
using linker.plugins.relay.messenger; using linker.plugins.relay.messenger;
using linker.libs.api; using linker.libs.api;
using linker.libs.extends; using linker.libs.extends;
using MemoryPack;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.capi; using linker.plugins.capi;
using linker.plugins.messenger; using linker.plugins.messenger;
using linker.client.config;
namespace linker.plugins.relay namespace linker.plugins.relay
{ {
@@ -48,6 +46,11 @@ namespace linker.plugins.relay
relayTransfer.SetServers(info); relayTransfer.SetServers(info);
return true; 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() private async Task TaskRelay()
{ {
try try
@@ -290,10 +296,13 @@ namespace linker.plugins.relay
private void TestTask() private void TestTask()
{ {
TimerHelper.SetInterval(async () => TimerHelper.SetInterval(async () =>
{
if (lastTicksManager.DiffLessEqual(3000))
{ {
await TaskRelay(); await TaskRelay();
}
return true; return true;
}, 5000); }, 1000);
} }
sealed class TestInfo sealed class TestInfo
{ {

View File

@@ -12,6 +12,7 @@ using System.Buffers.Binary;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.messenger; using linker.plugins.messenger;
using linker.plugins.tunnel.excludeip; using linker.plugins.tunnel.excludeip;
using linker.tunnel;
namespace linker.plugins.tunnel namespace linker.plugins.tunnel
{ {
@@ -21,21 +22,26 @@ namespace linker.plugins.tunnel
? running.Data.Tunnel.Interface : (clientSignInState.Connection?.LocalAddress.Address ?? IPAddress.Any); ? running.Data.Tunnel.Interface : (clientSignInState.Connection?.LocalAddress.Address ?? IPAddress.Any);
public X509Certificate2 Certificate { get; private set; } 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 ClientSignInState clientSignInState;
private readonly MessengerSender messengerSender; private readonly MessengerSender messengerSender;
private readonly FileConfig config; private readonly FileConfig config;
private readonly RunningConfig running; private readonly RunningConfig running;
private readonly TunnelExcludeIPTransfer excludeIPTransfer; 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.clientSignInState = clientSignInState;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.config = config; this.config = config;
this.running = running; this.running = running;
this.excludeIPTransfer = excludeIPTransfer; this.excludeIPTransfer = excludeIPTransfer;
this.upnpTransfer = upnpTransfer;
string path = Path.GetFullPath(config.Data.Client.Certificate); string path = Path.GetFullPath(config.Data.Client.Certificate);
if (File.Exists(path)) if (File.Exists(path))

View File

@@ -4,6 +4,7 @@ using linker.libs;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.messenger; using linker.plugins.messenger;
using linker.plugins.tunnel.messenger; using linker.plugins.tunnel.messenger;
using linker.tunnel;
using linker.tunnel.adapter; using linker.tunnel.adapter;
using linker.tunnel.transport; using linker.tunnel.transport;
using linker.tunnel.wanport; using linker.tunnel.wanport;
@@ -23,11 +24,12 @@ namespace linker.plugins.tunnel
private readonly ITunnelAdapter tunnelAdapter; private readonly ITunnelAdapter tunnelAdapter;
private readonly TransportTcpPortMap transportTcpPortMap; private readonly TransportTcpPortMap transportTcpPortMap;
private readonly TransportUdpPortMap transportUdpPortMap; private readonly TransportUdpPortMap transportUdpPortMap;
private readonly TunnelUpnpTransfer upnpTransfer;
public VersionManager Version { get; } = new VersionManager(); public VersionManager Version { get; } = new VersionManager();
public ConcurrentDictionary<string, TunnelTransportRouteLevelInfo> Config { get; } = new ConcurrentDictionary<string, TunnelTransportRouteLevelInfo>(); 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.config = config;
this.running = running; this.running = running;
@@ -36,6 +38,7 @@ namespace linker.plugins.tunnel
this.tunnelAdapter = tunnelAdapter; this.tunnelAdapter = tunnelAdapter;
this.transportTcpPortMap = transportTcpPortMap; this.transportTcpPortMap = transportTcpPortMap;
this.transportUdpPortMap = transportUdpPortMap; this.transportUdpPortMap = transportUdpPortMap;
this.upnpTransfer = upnpTransfer;
InitRouteLevel(); InitRouteLevel();
@@ -213,9 +216,27 @@ namespace linker.plugins.tunnel
private void RefreshPortMap() 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); _ = transportTcpPortMap.Listen(running.Data.Tunnel.PortMapLan);
_ = transportUdpPortMap.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<TunnelServerMessenger>();
serviceCollection.AddSingleton<ExternalResolver>(); serviceCollection.AddSingleton<ExternalResolver>();
serviceCollection.AddSingleton<TunnelUpnpTransfer>();
} }
public void UseClient(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies) public void UseClient(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies)
@@ -108,6 +111,8 @@ namespace linker.plugins.tunnel
TunnelExcludeIPTransfer excludeIPTransfer = serviceProvider.GetService<TunnelExcludeIPTransfer>(); TunnelExcludeIPTransfer excludeIPTransfer = serviceProvider.GetService<TunnelExcludeIPTransfer>();
excludeIPTransfer.Load(assemblies); excludeIPTransfer.Load(assemblies);
TunnelUpnpTransfer upnpTransfer = serviceProvider.GetService<TunnelUpnpTransfer>();
} }
public void UseServer(ServiceProvider serviceProvider, FileConfig config, Assembly[] assemblies) 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.client;
using linker.plugins.tunnel; using linker.plugins.tunnel;
using System.Buffers; using System.Buffers;
using linker.client.config;
namespace linker.plugins.tuntap namespace linker.plugins.tuntap
{ {
@@ -25,13 +26,15 @@ namespace linker.plugins.tuntap
private string groupid = string.Empty; private string groupid = string.Empty;
private readonly FileConfig config; 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) : base(config, tunnelTransfer, relayTransfer, clientSignInTransfer, clientSignInState)
{ {
this.config = config; this.config = config;
this.runningConfig = runningConfig;
this.linkerTunDeviceAdapter = linkerTunDeviceAdapter; this.linkerTunDeviceAdapter = linkerTunDeviceAdapter;
clientSignInState.NetworkEnabledHandle +=(times) => ClearIPs(); clientSignInState.NetworkEnabledHandle += (times) => ClearIPs();
} }
protected override void Connected(ITunnelConnection connection) protected override void Connected(ITunnelConnection connection)
@@ -86,7 +89,7 @@ namespace linker.plugins.tuntap
//IPV4广播组播 //IPV4广播组播
if (packet.IPV4Broadcast) 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))); 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 多播 //IPV6 多播
else if (packet.IPV6Multicast) 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))); await Task.WhenAll(connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Packet)));
} }
@@ -150,7 +153,7 @@ namespace linker.plugins.tuntap
/// <param name="ip"></param> /// <param name="ip"></param>
public void SetIP(string machineId, uint ip) public void SetIP(string machineId, uint ip)
{ {
if (ip2MachineDic.TryGetValue(ip,out List<string> list) == false) if (ip2MachineDic.TryGetValue(ip, out List<string> list) == false)
{ {
list = new List<string>(); list = new List<string>();
ip2MachineDic.AddOrUpdate(ip, list, (a, b) => list); ip2MachineDic.AddOrUpdate(ip, list, (a, b) => list);
@@ -160,7 +163,7 @@ namespace linker.plugins.tuntap
private void ClearIPs() private void ClearIPs()
{ {
if(groupid != config.Data.Client.GroupId) if (groupid != config.Data.Client.GroupId)
{ {
ip2MachineDic.Clear(); ip2MachineDic.Clear();
ipConnections.Clear(); ipConnections.Clear();

View File

@@ -246,7 +246,7 @@ namespace linker.plugins.tuntap
{ {
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) 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 () => TimerHelper.Async(async () =>

View File

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

View File

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