mirror of
https://github.com/snltty/linker.git
synced 2025-10-12 20:40:19 +08:00
测试UPNP
This commit is contained in:
30
.github/workflows/dotnet.yml
vendored
30
.github/workflows/dotnet.yml
vendored
@@ -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
|
||||||
|
6
.github/workflows/nuget.yml
vendored
6
.github/workflows/nuget.yml
vendored
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
@@ -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>
|
||||||
|
14
linker.sln
14
linker.sln
@@ -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
|
||||||
|
@@ -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"/>
|
||||||
|
BIN
linker.tray.win/dist/linker.tray.win.exe
vendored
BIN
linker.tray.win/dist/linker.tray.win.exe
vendored
Binary file not shown.
@@ -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}
|
@@ -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}
|
@@ -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
1
linker.tray.win/web/js/414.d213f338.js
Normal file
1
linker.tray.win/web/js/414.d213f338.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
linker.tray.win/web/js/706.e42611ef.js
Normal file
1
linker.tray.win/web/js/706.e42611ef.js
Normal file
File diff suppressed because one or more lines are too long
1
linker.tray.win/web/js/app.4b319136.js
Normal file
1
linker.tray.win/web/js/app.4b319136.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -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'">
|
||||||
|
105
linker.tunnel/TunnelUpnpTransfer.cs
Normal file
105
linker.tunnel/TunnelUpnpTransfer.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
@@ -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" />
|
||||||
|
@@ -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>
|
|
@@ -5,4 +5,7 @@ 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');
|
||||||
}
|
}
|
@@ -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" />
|
||||||
|
@@ -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}
|
||||||
}
|
}
|
||||||
|
@@ -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>
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
@@ -291,9 +297,12 @@ namespace linker.plugins.relay
|
|||||||
{
|
{
|
||||||
TimerHelper.SetInterval(async () =>
|
TimerHelper.SetInterval(async () =>
|
||||||
{
|
{
|
||||||
await TaskRelay();
|
if (lastTicksManager.DiffLessEqual(3000))
|
||||||
|
{
|
||||||
|
await TaskRelay();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}, 5000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
sealed class TestInfo
|
sealed class TestInfo
|
||||||
{
|
{
|
||||||
|
@@ -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))
|
||||||
|
@@ -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();
|
||||||
|
|
||||||
@@ -214,8 +217,26 @@ namespace linker.plugins.tunnel
|
|||||||
|
|
||||||
private void RefreshPortMap()
|
private void RefreshPortMap()
|
||||||
{
|
{
|
||||||
_ = transportTcpPortMap.Listen(running.Data.Tunnel.PortMapLan);
|
try
|
||||||
_ = transportUdpPortMap.Listen(running.Data.Tunnel.PortMapLan);
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
|
@@ -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();
|
||||||
|
@@ -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 () =>
|
||||||
|
@@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
version.txt
10
version.txt
@@ -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. 测试中,请勿更新!请勿更新!请勿更新!
|
Reference in New Issue
Block a user