防火墙

This commit is contained in:
snltty
2025-05-11 18:02:02 +08:00
parent 2cf62b5607
commit bf2c3a5050
104 changed files with 1503 additions and 400 deletions

View File

@@ -57,9 +57,9 @@ jobs:
docker tag snltty/linker-musl-x64:latest snltty/linker-musl:amd64 && \
docker push snltty/linker-musl:amd64 && \
docker manifest create snltty/linker-musl:latest snltty/linker-musl:amd64 snltty/linker-musl:arm64 snltty/linker-musl:arm && \
docker manifest create snltty/linker-musl:v1.7.8 snltty/linker-musl:amd64 snltty/linker-musl:arm64 snltty/linker-musl:arm && \
docker manifest create snltty/linker-musl:v1.7.9 snltty/linker-musl:amd64 snltty/linker-musl:arm64 snltty/linker-musl:arm && \
docker manifest push snltty/linker-musl:latest && \
docker manifest push snltty/linker-musl:v1.7.8 && \
docker manifest push snltty/linker-musl:v1.7.9 && \
docker pull --platform linux/arm/v7 snltty/linker-debian-arm:latest && \
docker tag snltty/linker-debian-arm:latest snltty/linker-debian:arm && \
docker push snltty/linker-debian:arm && \
@@ -70,6 +70,6 @@ jobs:
docker tag snltty/linker-debian-x64:latest snltty/linker-debian:amd64 && \
docker push snltty/linker-debian:amd64 && \
docker manifest create snltty/linker-debian:latest snltty/linker-debian:amd64 snltty/linker-debian:arm64 snltty/linker-debian:arm && \
docker manifest create snltty/linker-debian:v1.7.8 snltty/linker-debian:amd64 snltty/linker-debian:arm64 snltty/linker-debian:arm && \
docker manifest create snltty/linker-debian:v1.7.9 snltty/linker-debian:amd64 snltty/linker-debian:arm64 snltty/linker-debian:arm && \
docker manifest push snltty/linker-debian:latest && \
docker manifest push snltty/linker-debian:v1.7.8
docker manifest push snltty/linker-debian:v1.7.9

View File

@@ -33,11 +33,11 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.ACTIONS_TOKEN }}
with:
tag_name: v1.7.8
release_name: v1.7.8.${{ steps.date.outputs.today }}
tag_name: v1.7.9
release_name: v1.7.9.${{ steps.date.outputs.today }}
draft: false
prerelease: false
body: "1. 一些累计更新\r\n2. socks5网段映射请更新所有设备\r\n3. 修复优化入参调用\r\n4. 增加登入在线续期\r\n5. 增加虚拟网卡在线检查IP冲突检查抢占IP时更新映射表\r\n6. 如果你设备很多,请尝试升级其中一个成功重启后再升级其它"
body: "1. 一些累计更新\r\n2. 优化安卓APP\r\n3. 新增防火墙用于网卡、端口转发、和socks5\r\n4. 检测密钥是否正确\r\n5. 如果你设备很多,请尝试升级其中一个成功重启后再升级其它"
- name: publish projects
run: ./publish.bat "C:\\Android\\android-sdk"
- name: upload-win-x86-oss
@@ -49,7 +49,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-x86.zip
target-path: /downloads/linker/v1.7.8/linker-win-x86.zip
target-path: /downloads/linker/v1.7.9/linker-win-x86.zip
- name: upload-win-x86
id: upload-win-x86
uses: actions/upload-release-asset@master
@@ -69,7 +69,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-x64.zip
target-path: /downloads/linker/v1.7.8/linker-win-x64.zip
target-path: /downloads/linker/v1.7.9/linker-win-x64.zip
- name: upload-win-x64
id: upload-win-x64
uses: actions/upload-release-asset@master
@@ -89,7 +89,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-arm64.zip
target-path: /downloads/linker/v1.7.8/linker-win-arm64.zip
target-path: /downloads/linker/v1.7.9/linker-win-arm64.zip
- name: upload-win-arm64
id: upload-win-arm64
uses: actions/upload-release-asset@master
@@ -109,7 +109,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-x64.zip
target-path: /downloads/linker/v1.7.8/linker-linux-x64.zip
target-path: /downloads/linker/v1.7.9/linker-linux-x64.zip
- name: upload-linux-x64
id: upload-linux-x64
uses: actions/upload-release-asset@master
@@ -129,7 +129,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-arm.zip
target-path: /downloads/linker/v1.7.8/linker-linux-arm.zip
target-path: /downloads/linker/v1.7.9/linker-linux-arm.zip
- name: upload-linux-arm
id: upload-linux-arm
uses: actions/upload-release-asset@master
@@ -149,7 +149,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-arm64.zip
target-path: /downloads/linker/v1.7.8/linker-linux-arm64.zip
target-path: /downloads/linker/v1.7.9/linker-linux-arm64.zip
- name: upload-linux-arm64
id: upload-linux-arm64
uses: actions/upload-release-asset@master
@@ -169,7 +169,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-x64.zip
target-path: /downloads/linker/v1.7.8/linker-linux-musl-x64.zip
target-path: /downloads/linker/v1.7.9/linker-linux-musl-x64.zip
- name: upload-linux-musl-x64
id: upload-linux-musl-x64
uses: actions/upload-release-asset@master
@@ -189,7 +189,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-arm.zip
target-path: /downloads/linker/v1.7.8/linker-linux-musl-arm.zip
target-path: /downloads/linker/v1.7.9/linker-linux-musl-arm.zip
- name: upload-linux-musl-arm
id: upload-linux-musl-arm
uses: actions/upload-release-asset@master
@@ -209,7 +209,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-arm64.zip
target-path: /downloads/linker/v1.7.8/linker-linux-musl-arm64.zip
target-path: /downloads/linker/v1.7.9/linker-linux-musl-arm64.zip
- name: upload-linux-musl-arm64
id: upload-linux-musl-arm64
uses: actions/upload-release-asset@master
@@ -259,7 +259,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker.apk
target-path: /downloads/linker/v1.7.8/linker.apk
target-path: /downloads/linker/v1.7.9/linker.apk
- name: upload-apk
id: upload-apk
uses: actions/upload-release-asset@master

View File

@@ -44,7 +44,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-ipk/x64/linker-x64.ipk
target-path: /downloads/linker/v1.7.8/linker-x64.ipk
target-path: /downloads/linker/v1.7.9/linker-x64.ipk
- name: upload-x64
id: upload-x64
uses: actions/upload-release-asset@master
@@ -64,7 +64,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-ipk/arm/linker-arm.ipk
target-path: /downloads/linker/v1.7.8/linker-arm.ipk
target-path: /downloads/linker/v1.7.9/linker-arm.ipk
- name: upload-arm
id: upload-arm
uses: actions/upload-release-asset@master
@@ -84,7 +84,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-ipk/arm64/linker-arm64.ipk
target-path: /downloads/linker/v1.7.8/linker-arm64.ipk
target-path: /downloads/linker/v1.7.9/linker-arm64.ipk
- name: upload-arm64
id: upload-arm64
uses: actions/upload-release-asset@master

View File

@@ -83,31 +83,31 @@ jobs:
- name: Push
run: |
dotnet nuget push ./src/linker.libs/bin/release/linker.libs.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger/bin/release/linker.messenger.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.access/bin/release/linker.messenger.access.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.action/bin/release/linker.messenger.action.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.api/bin/release/linker.messenger.api.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.channel/bin/release/linker.messenger.channel.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.decenter/bin/release/linker.messenger.decenter.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.entry/bin/release/linker.messenger.entry.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.exroute/bin/release/linker.messenger.exroute.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.flow/bin/release/linker.messenger.flow.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.forward/bin/release/linker.messenger.forward.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.listen/bin/release/linker.messenger.listen.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.logger/bin/release/linker.messenger.logger.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.pcp/bin/release/linker.messenger.pcp.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.plan/bin/release/linker.messenger.plan.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.relay/bin/release/linker.messenger.relay.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.serializer.memorypack/bin/release/linker.messenger.serializer.memorypack.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.sforward/bin/release/linker.messenger.sforward.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.signin/bin/release/linker.messenger.signin.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.socks5/bin/release/linker.messenger.socks5.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.store.file/bin/release/linker.messenger.store.file.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.sync/bin/release/linker.messenger.sync.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.tunnel/bin/release/linker.messenger.tunnel.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.tuntap/bin/release/linker.messenger.tuntap.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.updater/bin/release/linker.messenger.updater.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.tun/bin/release/linker.tun.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.snat/bin/release/linker.snat.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.tunnel/bin/release/linker.tunnel.1.7.8.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.libs/bin/release/linker.libs.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger/bin/release/linker.messenger.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.access/bin/release/linker.messenger.access.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.action/bin/release/linker.messenger.action.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.api/bin/release/linker.messenger.api.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.channel/bin/release/linker.messenger.channel.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.decenter/bin/release/linker.messenger.decenter.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.entry/bin/release/linker.messenger.entry.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.exroute/bin/release/linker.messenger.exroute.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.flow/bin/release/linker.messenger.flow.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.forward/bin/release/linker.messenger.forward.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.listen/bin/release/linker.messenger.listen.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.logger/bin/release/linker.messenger.logger.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.pcp/bin/release/linker.messenger.pcp.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.plan/bin/release/linker.messenger.plan.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.relay/bin/release/linker.messenger.relay.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.serializer.memorypack/bin/release/linker.messenger.serializer.memorypack.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.sforward/bin/release/linker.messenger.sforward.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.signin/bin/release/linker.messenger.signin.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.socks5/bin/release/linker.messenger.socks5.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.store.file/bin/release/linker.messenger.store.file.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.sync/bin/release/linker.messenger.sync.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.tunnel/bin/release/linker.messenger.tunnel.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.tuntap/bin/release/linker.messenger.tuntap.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.messenger.updater/bin/release/linker.messenger.updater.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.tun/bin/release/linker.tun.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.snat/bin/release/linker.snat.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols
dotnet nuget push ./src/linker.tunnel/bin/release/linker.tunnel.1.7.9.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key ${{ secrets.NUGET_KEY }} --no-symbols

Binary file not shown.

View File

@@ -0,0 +1,61 @@
# -*- python -*-
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import sys
import gdb
import os
import os.path
pythondir = '/home/lean/Desktop/qsdk12-ng/staging_dir/toolchain-aarch64_cortex-a53_gcc-7.5.0_musl/share/gcc-7.5.0/python'
libdir = '/home/lean/Desktop/qsdk12-ng/staging_dir/toolchain-aarch64_cortex-a53_gcc-7.5.0_musl/aarch64-openwrt-linux-musl/lib'
# This file might be loaded when there is no current objfile. This
# can happen if the user loads it manually. In this case we don't
# update sys.path; instead we just hope the user managed to do that
# beforehand.
if gdb.current_objfile () is not None:
# Update module path. We want to find the relative path from libdir
# to pythondir, and then we want to apply that relative path to the
# directory holding the objfile with which this file is associated.
# This preserves relocatability of the gcc tree.
# Do a simple normalization that removes duplicate separators.
pythondir = os.path.normpath (pythondir)
libdir = os.path.normpath (libdir)
prefix = os.path.commonprefix ([libdir, pythondir])
# In some bizarre configuration we might have found a match in the
# middle of a directory name.
if prefix[-1] != '/':
prefix = os.path.dirname (prefix) + '/'
# Strip off the prefix.
pythondir = pythondir[len (prefix):]
libdir = libdir[len (prefix):]
# Compute the ".."s needed to get from libdir to the prefix.
dotdots = ('..' + os.sep) * len (libdir.split (os.sep))
objfile = gdb.current_objfile ().filename
dir_ = os.path.join (os.path.dirname (objfile), dotdots, pythondir)
if not dir_ in sys.path:
sys.path.insert(0, dir_)
# Call a function as a plain import would not execute body of the included file
# on repeated reloads of this object file.
from libstdcxx.v6 import register_libstdcxx_printers
register_libstdcxx_printers(gdb.current_objfile())

View File

@@ -33,16 +33,16 @@ do
fi
done
cd public/publish/docker/linux-${p}-x64/${f}
docker buildx build -f ${target}/public/publish/docker/linux-${p}-x64/${f}/Dockerfile-${p} --platform="linux/x86_64" --force-rm -t "${image}-${p}-x64:latest" -t "${image}-${p}-x64:v1.7.8" . --push
docker buildx build -f ${target}/public/publish/docker/linux-${p}-x64/${f}/Dockerfile-${p} --platform="linux/x86_64" --force-rm -t "${image}-${p}-x64:latest" -t "${image}-${p}-x64:v1.7.9" . --push
cd ../../../../../
cd public/publish/docker/linux-${p}-arm64/${f}
docker buildx build -f ${target}/public/publish/docker/linux-${p}-arm64/${f}/Dockerfile-${p} --platform="linux/arm64" --force-rm -t "${image}-${p}-arm64:latest" -t "${image}-${p}-arm64:v1.7.8" . --push
docker buildx build -f ${target}/public/publish/docker/linux-${p}-arm64/${f}/Dockerfile-${p} --platform="linux/arm64" --force-rm -t "${image}-${p}-arm64:latest" -t "${image}-${p}-arm64:v1.7.9" . --push
cd ../../../../../
cd public/publish/docker/linux-${p}-arm/${f}
docker buildx build -f ${target}/public/publish/docker/linux-${p}-arm/${f}/Dockerfile-${p} --platform="linux/arm/v7" --force-rm -t "${image}-${p}-arm:latest" -t "${image}-${p}-arm:v1.7.8" . --push
docker buildx build -f ${target}/public/publish/docker/linux-${p}-arm/${f}/Dockerfile-${p} --platform="linux/arm/v7" --force-rm -t "${image}-${p}-arm:latest" -t "${image}-${p}-arm:v1.7.9" . --push
cd ../../../../../
done
done

View File

@@ -22,7 +22,7 @@ do
mkdir -p public/publish-ipk/${r}/data/usr/bin/linker
cp -rf public/publish/${r}/* public/publish-ipk/${r}/data/usr/bin/linker/
sed -i "s|{version}|1.7.8|g" public/publish-ipk/${r}/control/control
sed -i "s|{version}|1.7.9|g" public/publish-ipk/${r}/control/control
sed -i 's/\r$//' public/publish-ipk/${r}/data/etc/init.d/linker
sed -i 's/\r$//' public/publish-ipk/${r}/control/control
sed -i 's/\r$//' public/publish-ipk/${r}/control/postinst

View File

@@ -6,7 +6,6 @@ using Android.Net;
using Android.OS;
using Android.Views;
using AndroidX.Core.App;
using AndroidX.Core.Content;
using AndroidX.Core.View;
using Java.IO;
using linker.app.Services;
@@ -21,7 +20,6 @@ using linker.tunnel.connection;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
namespace linker.app
@@ -29,7 +27,6 @@ namespace linker.app
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
public const int VPN_RESULT_CODE = 0x0F;
Intent intent;
protected override void OnCreate(Bundle savedInstanceState)
@@ -37,7 +34,9 @@ namespace linker.app
SetLightStatusBar();
base.OnCreate(savedInstanceState);
ConfigureVpn();
intent = new Intent(this, typeof(ForegroundService));
StartForegroundService(intent);
}
public void SetLightStatusBar()
{
@@ -57,11 +56,6 @@ namespace linker.app
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == VPN_RESULT_CODE && resultCode == Result.Ok)
{
intent = new Intent(this, typeof(ForegroundService));
StartForegroundService(intent);
}
}
protected override void OnStart()
{
@@ -71,23 +65,6 @@ namespace linker.app
{
base.OnDestroy();
}
private void ConfigureVpn()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.BindVpnService) != Permission.Granted)
{
ActivityCompat.RequestPermissions(this, new string[] { Manifest.Permission.BindVpnService }, 0);
}
var intent = VpnService.Prepare(this);
if (intent != null)
{
StartActivityForResult(intent, VPN_RESULT_CODE);
}
else
{
OnActivityResult(VPN_RESULT_CODE, Result.Ok, null);
}
}
}
/// <summary>
@@ -126,7 +103,7 @@ namespace linker.app
public override void OnDestroy()
{
base.OnDestroy();
tuntapTransfer.Shutdown(false);
tuntapTransfer.Shutdown();
}
public async Task Callback(LinkerTunDevicPacket packet)
@@ -193,9 +170,7 @@ namespace linker.app
StartForeground(SERVICE_ID, CreateNotification());
}
return StartCommandResult.Sticky;
return StartCommandResult.NotSticky;
}
private Notification CreateNotification()
{
@@ -260,10 +235,31 @@ namespace linker.app
{
TuntapTransfer tuntapTransfer = LinkerMessengerEntry.GetService<TuntapTransfer>();
tuntapTransfer.OnSetupBefore += () =>
{
try
{
Intent intent = VpnService.Prepare(Android.App.Application.Context);
if (intent != null)
{
intent.AddFlags(ActivityFlags.NewTask);
StartActivity(intent);
return;
}
}
catch (Exception)
{
return;
}
try
{
vpnIntent = new Intent(Android.App.Application.Context, typeof(VpnServiceLinker));
Android.App.Application.Context.StartService(vpnIntent);
Task.Delay(3000).Wait();
}
catch (Exception)
{
}
};
tuntapTransfer.OnShutdownBefore += () =>
{
@@ -318,6 +314,7 @@ namespace linker.app
{
error = string.Empty;
if (address.Equals(IPAddress.Any)) return false;
if (vpnService == null) return false;
this.name = name;
@@ -484,7 +481,7 @@ namespace linker.app
public byte[] Read(string root, string fileName, out DateTime lastModified)
{
lastModified = DateTime.Now;
fileName = Path.Join("public/web", fileName);
fileName = System.IO.Path.Join("public/web", fileName);
using Stream fileStream = FileSystem.Current.OpenAppPackageFileAsync(fileName).Result;
using MemoryStream memoryStream = new MemoryStream();
fileStream.CopyTo(memoryStream);
@@ -519,7 +516,7 @@ namespace linker.app
}
public override (string, string) DownloadUrlAndSavePath(string version)
{
return ($"{updaterCommonTransfer.UpdateUrl}/{version}/linker.apk", Path.Join(FileSystem.Current.AppDataDirectory, "linker.apk"));
return ($"{updaterCommonTransfer.UpdateUrl}/{version}/linker.apk", System.IO.Path.Join(FileSystem.Current.AppDataDirectory, "linker.apk"));
}
public override async Task Install(Action<long, long> processs)
@@ -540,7 +537,7 @@ namespace linker.app
{
await MainThread.InvokeOnMainThreadAsync(() =>
{
var file = new Java.IO.File(Path.Join(FileSystem.Current.AppDataDirectory, "linker.apk"));
var file = new Java.IO.File(System.IO.Path.Join(FileSystem.Current.AppDataDirectory, "linker.apk"));
if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
{

View File

@@ -28,7 +28,7 @@
<ApplicationId>com.snltty.linker.app</ApplicationId>
<Title>linker.app</Title>
<Version>1.7.8</Version>
<Version>1.7.9</Version>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Copyright>snltty</Copyright>
@@ -38,7 +38,7 @@
<PackageReleaseNotes>linker</PackageReleaseNotes>
<!-- Versions -->
<ApplicationDisplayVersion>1.7.8</ApplicationDisplayVersion>
<ApplicationDisplayVersion>1.7.9</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">11.0</SupportedOSPlatformVersion>

View File

@@ -8,8 +8,12 @@ namespace linker.libs
{
public sealed class IPAddessCidrManager<T>
{
private readonly ConcurrentDictionary<uint, T> ip2value = new ConcurrentDictionary<uint, T>();
private readonly ConcurrentDictionary<uint, CidrAddInfo<T>> ip2value = new ConcurrentDictionary<uint, CidrAddInfo<T>>();
private readonly ConcurrentDictionary<string, T> routes = new ConcurrentDictionary<string, T>();
private HashSet<uint> masks = new HashSet<uint>();
public Dictionary<string, T> Routes => routes.ToDictionary();
public void Add(CidrAddInfo<T>[] items)
{
foreach (CidrAddInfo<T> item in items)
@@ -21,20 +25,23 @@ namespace linker.libs
{
uint maskValue = NetworkHelper.ToPrefixValue(item.PrefixLength);
uint network = item.IPAddress & maskValue;
ip2value.AddOrUpdate(network, item.Value, (a, b) => item.Value);
ip2value.AddOrUpdate(network, item, (a, b) => item);
routes.AddOrUpdate($"{NetworkHelper.ToIP(item.IPAddress)}/{item.PrefixLength}", item.Value, (a, b) => item.Value);
masks.Add(maskValue);
}
public void Delete(T value, Func<T, T, bool> compare)
{
foreach (var item in ip2value.Where(c => compare(c.Value, value)).ToList())
foreach (var item in ip2value.Where(c => compare(c.Value.Value, value)).ToList())
{
ip2value.TryRemove(item.Key, out _);
routes.TryRemove($"{NetworkHelper.ToIP(item.Value.IPAddress)}/{item.Value.PrefixLength}", out _);
}
}
public void Clear()
{
ip2value.Clear();
routes.Clear();
}
public bool FindValue(IPAddress ip, out T value)
@@ -43,15 +50,18 @@ namespace linker.libs
}
public bool FindValue(uint ip, out T value)
{
if (ip2value.TryGetValue(ip, out value))
value = default;
if (ip2value.TryGetValue(ip, out CidrAddInfo<T> item))
{
value = item.Value;
return true;
}
foreach (var item in masks)
foreach (var mask in masks)
{
uint network = ip & item;
if (ip2value.TryGetValue(network, out value))
uint network = ip & mask;
if (ip2value.TryGetValue(network, out item))
{
value = item.Value;
return true;
}
}

View File

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

View File

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

View File

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

View File

@@ -140,9 +140,9 @@
RelayCdkey = (ulong)1 << 43,
[AccessDisplay("管理本机防火墙")]
FirewallSelf = 1 << 44,
FirewallSelf = (ulong)1 << 44,
[AccessDisplay("管理所有设备防火墙")]
FirewallOther = 1 << 45,
FirewallOther = (ulong)1 << 45,
Full = ulong.MaxValue >> 64 - 52,
}

View File

@@ -17,9 +17,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger api</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

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

View File

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

View File

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

View File

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

View File

@@ -30,15 +30,16 @@ namespace linker.messenger.firewall
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<List<FirewallRuleInfo>> Get(ApiControllerParamsInfo param)
public async Task<FirewallListInfo> Get(ApiControllerParamsInfo param)
{
FirewallSearchForwardInfo info = param.Content.DeJson<FirewallSearchForwardInfo>();
info.Data.GroupId = signInClientStore.Group.Id;
if (info.MachineId == signInClientStore.Id)
{
if (accessStore.HasAccess(AccessValue.FirewallSelf) == false) return new List<FirewallRuleInfo>();
return firewallTransfer.Get(info.Data).ToList();
if (accessStore.HasAccess(AccessValue.FirewallSelf) == false) return new FirewallListInfo();
return firewallTransfer.Get(info.Data);
}
if (accessStore.HasAccess(AccessValue.FirewallOther) == false) return new List<FirewallRuleInfo>();
if (accessStore.HasAccess(AccessValue.FirewallOther) == false) return new FirewallListInfo ();
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
@@ -48,9 +49,9 @@ namespace linker.messenger.firewall
}).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK)
{
return serializer.Deserialize<List<FirewallRuleInfo>>(resp.Data.Span);
return serializer.Deserialize<FirewallListInfo>(resp.Data.Span);
}
return new List<FirewallRuleInfo>();
return new FirewallListInfo();
}
/// <summary>

View File

@@ -47,6 +47,10 @@ namespace linker.messenger.firewall
}
});
}
else
{
connection.Write(serializer.Serialize(new FirewallListInfo()));
}
}
/// <summary>
/// 添加对端的记录

View File

@@ -36,9 +36,13 @@ namespace linker.messenger.firewall
return true;
}
public IEnumerable<FirewallRuleInfo> Get(FirewallSearchInfo info)
public FirewallListInfo Get(FirewallSearchInfo info)
{
return firewallClientStore.GetAll(info);
return new FirewallListInfo
{
List = firewallClientStore.GetAll(info).ToList(),
State = firewallClientStore.State
};
}
public bool Add(FirewallRuleInfo info)
{

View File

@@ -20,6 +20,7 @@ namespace linker.messenger.firewall
public string SrcName { get; set; }
public bool Disabled { get; set; }
public int OrderBy { get; set; }
public string Remark { get; set; }
}
@@ -31,14 +32,16 @@ namespace linker.messenger.firewall
public sealed partial class FirewallSearchInfo
{
public string GroupId { get; set; }
public string SrcName { get; set; }
public bool Disabled { get; set; }
public string DstCidr { get; set; }
public string DstPort { get; set; }
public string Str { get; set; }
public int Disabled { get; set; }
public LinkerFirewallProtocolType Protocol { get; set; }
public LinkerFirewallAction Action { get; set; }
}
public sealed partial class FirewallListInfo
{
public LinkerFirewallState State { get; set; } = LinkerFirewallState.Disabled;
public List<FirewallRuleInfo> List { get; set; } = new List<FirewallRuleInfo>();
}
public sealed partial class FirewallAddForwardInfo
{

View File

@@ -17,9 +17,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger firewall</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -59,6 +59,13 @@ namespace linker.messenger.flow
{
onlineFlowInfo.Nets = serializer.Deserialize<List<FlowReportNetInfo>>(memory.Slice(8).Span);
}
long online = (long)servers.Where(c => time - c.Value.Time < 15000).Sum(c => c.Value.Online) << 32;
long total = servers.Where(c => time - c.Value.Time < 15000).Sum(c => c.Value.Total);
ReceiveBytes = online | total;
SendtBytes = servers.Count(c => time - c.Value.Time < 15000);
Version.Increment();
}
catch (Exception)
{
@@ -91,7 +98,6 @@ namespace linker.messenger.flow
{
try
{
Counter();
Report();
}
catch (Exception)
@@ -99,23 +105,6 @@ namespace linker.messenger.flow
}
}, 5000);
}
private void Counter()
{
long time = Environment.TickCount64;
List<IPAddress> keys = servers.Where(c => time - c.Value.Time > 15000).Select(c => c.Key).ToList();
foreach (IPAddress key in keys)
{
servers.TryRemove(key, out _);
}
long online = (long)servers.Sum(c => c.Value.Online) << 32;
long total = servers.Sum(c => c.Value.Total);
ReceiveBytes = online | total;
SendtBytes = servers.Count;
Version.Increment();
}
private void Report()
{
List<FlowReportNetInfo> nets = signCaching.Get().Where(c => c.Args.ContainsKey("tunnelNet")).Select(c => c.Args["tunnelNet"].DeJson<SignInArgsNetInfo>()).GroupBy(c => c.City).Select(c => new FlowReportNetInfo

View File

@@ -17,9 +17,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger flow</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -17,9 +17,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger forward</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -41,6 +41,7 @@
<ProjectReference Include="..\linker.libs\linker.libs.csproj" />
<ProjectReference Include="..\linker.messenger.channel\linker.messenger.channel.csproj" />
<ProjectReference Include="..\linker.messenger.decenter\linker.messenger.decenter.csproj" />
<ProjectReference Include="..\linker.messenger.firewall\linker.messenger.firewall.csproj" />
<ProjectReference Include="..\linker.messenger.signin\linker.messenger.signin.csproj" />
<ProjectReference Include="..\linker.messenger\linker.messenger.csproj" />
</ItemGroup>

View File

@@ -218,6 +218,11 @@ namespace linker.messenger.forward.proxy
{
if (token.Proxy.TargetEP == null) return;
if(linkerFirewall.Check(token.Connection.RemoteMachineId, token.Proxy.TargetEP, ProtocolType.Tcp) == false)
{
return;
}
Socket socket = new Socket(token.Proxy.TargetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.KeepAlive();

View File

@@ -6,6 +6,7 @@ using linker.messenger.relay.client;
using linker.messenger.signin;
using linker.messenger.channel;
using linker.messenger.pcp;
using linker.snat;
namespace linker.messenger.forward.proxy
{
@@ -17,9 +18,13 @@ namespace linker.messenger.forward.proxy
protected override string TransactionId => "forward";
public ForwardProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore)
private readonly LinkerFirewall linkerFirewall;
public ForwardProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore, LinkerFirewall linkerFirewall)
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, relayClientStore)
{
this.linkerFirewall = linkerFirewall;
TaskUdp();
}

View File

@@ -145,16 +145,16 @@ namespace linker.messenger.forward.proxy
ConnectIdUdp connectId = tunnelToken.GetUdpConnectId();
try
{
IPEndPoint target = new IPEndPoint(tunnelToken.Proxy.TargetEP.Address, tunnelToken.Proxy.TargetEP.Port);
if (udpConnections.TryGetValue(connectId, out AsyncUserUdpTokenTarget token))
{
token.Connection = tunnelToken.Connection;
await token.TargetSocket.SendToAsync(tunnelToken.Proxy.Data, target).ConfigureAwait(false);
await token.TargetSocket.SendToAsync(tunnelToken.Proxy.Data, tunnelToken.Proxy.TargetEP).ConfigureAwait(false);
token.LastTicks.Update();
return;
}
_ = ConnectUdp(tunnelToken, target);
_ = ConnectUdp(tunnelToken);
}
catch (Exception ex)
@@ -188,8 +188,14 @@ namespace linker.messenger.forward.proxy
}
}
}
private async Task ConnectUdp(AsyncUserTunnelToken tunnelToken, IPEndPoint target)
private async Task ConnectUdp(AsyncUserTunnelToken tunnelToken)
{
IPEndPoint target = new IPEndPoint(tunnelToken.Proxy.TargetEP.Address, tunnelToken.Proxy.TargetEP.Port);
if (linkerFirewall.Check(tunnelToken.Connection.RemoteMachineId, target, ProtocolType.Udp) == false)
{
return;
}
Socket socket = new Socket(target.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
socket.WindowsUdpBug();
await socket.SendToAsync(tunnelToken.Proxy.Data, target).ConfigureAwait(false);

View File

@@ -17,9 +17,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger listen</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

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

View File

@@ -17,9 +17,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger pcp</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

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

View File

@@ -212,6 +212,18 @@ namespace linker.messenger.relay
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
public async Task<bool> CheckKey(ApiControllerParamsInfo param)
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)RelayMessengerIds.CheckKey,
Payload = serializer.Serialize(param.Content)
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
}
public sealed class RelayConnectInfo

View File

@@ -18,9 +18,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger relay</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -453,5 +453,13 @@ namespace linker.messenger.relay.messenger
string result = await relayServerCdkeyStore.Import(info).ConfigureAwait(false);
connection.Write(serializer.Serialize(result));
}
[MessengerId((ushort)RelayMessengerIds.CheckKey)]
public void CheckKey(IConnection connection)
{
string key = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
connection.Write(relayServerStore.ValidateSecretKey(key) ? Helper.TrueArray : Helper.FalseArray);
}
}
}

View File

@@ -37,6 +37,8 @@
SendLastBytes = 2122,
CheckKey = 2123,
Max = 2199
}
}

View File

@@ -136,6 +136,7 @@ namespace linker.messenger.serializer.memorypack
MemoryPackFormatterProvider.Register(new FirewallRuleInfoFormatter());
MemoryPackFormatterProvider.Register(new FirewallSearchInfoFormatter());
MemoryPackFormatterProvider.Register(new FirewallSearchForwardInfoFormatter());
MemoryPackFormatterProvider.Register(new FirewallListInfoFormatter());
MemoryPackFormatterProvider.Register(new FirewallAddForwardInfoFormatter());
MemoryPackFormatterProvider.Register(new FirewallRemoveForwardInfoFormatter());
MemoryPackFormatterProvider.Register(new FirewallStateForwardInfoFormatter());

View File

@@ -40,8 +40,12 @@ namespace linker.messenger.serializer.memorypack
[MemoryPackInclude]
int OrderBy => info.OrderBy;
[MemoryPackInclude]
string Remark => info.Remark;
[MemoryPackConstructor]
SerializableFirewallRuleInfo(string id, string srcId, string srcName, string groupId, string dstCIDR, string dstPort, snat.LinkerFirewallProtocolType protocol, snat.LinkerFirewallAction action, bool disabled, int orderby)
SerializableFirewallRuleInfo(string id, string srcId, string srcName, string groupId, string dstCIDR, string dstPort,
snat.LinkerFirewallProtocolType protocol, snat.LinkerFirewallAction action, bool disabled, int orderby, string remark)
{
var info = new FirewallRuleInfo
{
@@ -54,7 +58,8 @@ namespace linker.messenger.serializer.memorypack
Protocol = protocol,
Action = action,
Disabled = disabled,
OrderBy = orderby
OrderBy = orderby,
Remark = remark
};
this.info = info;
}
@@ -98,17 +103,16 @@ namespace linker.messenger.serializer.memorypack
[MemoryPackIgnore]
public readonly FirewallSearchInfo info;
[MemoryPackInclude]
string SrcName => info.SrcName;
[MemoryPackInclude]
string GroupId => info.GroupId;
[MemoryPackInclude]
string DstCidr => info.DstCidr;
string Str => info.Str;
[MemoryPackInclude]
string DstPort => info.DstPort;
int Disabled => info.Disabled;
[MemoryPackInclude]
snat.LinkerFirewallProtocolType Protocol => info.Protocol;
@@ -116,18 +120,14 @@ namespace linker.messenger.serializer.memorypack
[MemoryPackInclude]
snat.LinkerFirewallAction Action => info.Action;
[MemoryPackInclude]
bool Disabled => info.Disabled;
[MemoryPackConstructor]
SerializableFirewallSearchInfo(string srcName, string groupId, string dstCIDR, string dstPort, snat.LinkerFirewallProtocolType protocol, snat.LinkerFirewallAction action, bool disabled)
SerializableFirewallSearchInfo(string groupId, string str, snat.LinkerFirewallProtocolType protocol,
snat.LinkerFirewallAction action, int disabled)
{
var info = new FirewallSearchInfo
{
SrcName = srcName,
GroupId = groupId,
DstCidr = dstCIDR,
DstPort = dstPort,
Str = str,
Protocol = protocol,
Action = action,
Disabled = disabled,
@@ -222,6 +222,61 @@ namespace linker.messenger.serializer.memorypack
}
[MemoryPackable]
public readonly partial struct SerializableFirewallListInfo
{
[MemoryPackIgnore]
public readonly FirewallListInfo info;
[MemoryPackInclude, MemoryPackAllowSerialize]
LinkerFirewallState State => info.State;
[MemoryPackInclude]
List<FirewallRuleInfo> List => info.List;
[MemoryPackConstructor]
SerializableFirewallListInfo(LinkerFirewallState state, List<FirewallRuleInfo> list)
{
this.info = new FirewallListInfo
{
List = list,
State = state
};
}
public SerializableFirewallListInfo(FirewallListInfo info)
{
this.info = info;
}
}
public class FirewallListInfoFormatter : MemoryPackFormatter<FirewallListInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref FirewallListInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableFirewallListInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref FirewallListInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
var wrapped = reader.ReadPackable<SerializableFirewallListInfo>();
value = wrapped.info;
}
}
[MemoryPackable]
public readonly partial struct SerializableFirewallAddForwardInfo
{

View File

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

View File

@@ -206,6 +206,18 @@ namespace linker.messenger.sforward.client
return true;
}
public async Task<bool> CheckKey(ApiControllerParamsInfo param)
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)SForwardMessengerIds.CheckKey,
Payload = serializer.Serialize(param.Content)
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
}
public sealed class SForwardListInfo

View File

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

View File

@@ -419,6 +419,15 @@ namespace linker.plugins.sforward.messenger
string[] arr = str.Split('/');
return arr.Length == 2 && int.TryParse(arr[0], out min) && int.TryParse(arr[1], out max);
}
[MessengerId((ushort)SForwardMessengerIds.CheckKey)]
public void CheckKey(IConnection connection)
{
string key = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
connection.Write(sForwardServerStore.ValidateSecretKey(key) ? Helper.TrueArray : Helper.FalseArray);
}
}
/// <summary>

View File

@@ -26,6 +26,8 @@
StopClient = 2315,
StopClientForward = 2316,
CheckKey = 2317,
Max = 2399
}
}

View File

@@ -136,6 +136,18 @@ namespace linker.messenger.signin
}
return new List<SignInNamesResponseItemInfo>();
}
public async Task<bool> CheckKey(ApiControllerParamsInfo param)
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)SignInMessengerIds.CheckKey,
Payload = serializer.Serialize(param.Content)
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
}
public sealed class ConfigSetInfo

View File

@@ -37,12 +37,14 @@ namespace linker.messenger.signin
private readonly SignInServerCaching signCaching;
private readonly IMessengerSender messengerSender;
private readonly ISerializer serializer;
private readonly ISignInServerStore signInServerStore;
public SignInServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer)
public SignInServerMessenger(IMessengerSender messengerSender, SignInServerCaching signCaching, ISerializer serializer, ISignInServerStore signInServerStore)
{
this.signCaching = signCaching;
this.messengerSender = messengerSender;
this.serializer = serializer;
this.signInServerStore = signInServerStore;
}
[MessengerId((ushort)SignInMessengerIds.SignIn)]
@@ -291,6 +293,13 @@ namespace linker.messenger.signin
{
signCaching.Exp(connection.Id);
}
[MessengerId((ushort)SignInMessengerIds.CheckKey)]
public void CheckKey(IConnection connection)
{
string key = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
connection.Write(signInServerStore.ValidateSecretKey(key) ? Helper.TrueArray : Helper.FalseArray);
}
}
/// <summary>

View File

@@ -30,6 +30,8 @@
Offlines = 16,
Exp = 17,
CheckKey = 18,
None = 99
}
}

View File

@@ -17,9 +17,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger signin</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -25,11 +25,16 @@ namespace linker.messenger.socks5
protected override string TransactionId => "socks5";
public TunnelProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer, SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore)
private readonly LinkerFirewall linkerFirewall;
public TunnelProxy(ISignInClientStore signInClientStore, TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore, LinkerFirewall linkerFirewall)
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, relayClientStore)
{
this.signInClientTransfer = signInClientTransfer;
this.linkerFirewall = linkerFirewall;
TaskUdp();
}
/// <summary>

View File

@@ -205,15 +205,20 @@ namespace linker.messenger.socks5
{
if (token.Proxy.TargetEP == null) return;
IPAddress ip = mapping.GetRealDst(token.Proxy.TargetEP.Address);
IPEndPoint target = new IPEndPoint(ip, token.Proxy.TargetEP.Port);
if(linkerFirewall.Check(token.Connection.RemoteMachineId, target, ProtocolType.Tcp) == false)
{
return;
}
Socket socket = new Socket(token.Proxy.TargetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.KeepAlive();
ConnectState state = new ConnectState { BufferSize = token.Proxy.BufferSize, Connection = token.Connection, ConnectId = token.Proxy.ConnectId, Socket = socket, IPEndPoint = token.Proxy.TargetEP };
state.CopyData(token.Proxy.Data);
IPAddress ip = mapping.GetRealDst(token.Proxy.TargetEP.Address);
IPEndPoint target = new IPEndPoint(ip, token.Proxy.TargetEP.Port);
socket.BeginConnect(target, ConnectCallback, state);
}

View File

@@ -173,6 +173,12 @@ namespace linker.messenger.socks5
IPAddress ip = mapping.GetRealDst(tunnelToken.Proxy.TargetEP.Address);
IPEndPoint target = new IPEndPoint(ip, tunnelToken.Proxy.TargetEP.Port);
if (linkerFirewall.Check(tunnelToken.Connection.RemoteMachineId, target, ProtocolType.Udp) == false)
{
return;
}
Socket socket = new Socket(target.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
socket.WindowsUdpBug();
await socket.SendToAsync(tunnelToken.Proxy.Data, target).ConfigureAwait(false);

View File

@@ -16,9 +16,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger socks5</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -41,6 +41,7 @@
<ProjectReference Include="..\linker.messenger.api\linker.messenger.api.csproj" />
<ProjectReference Include="..\linker.messenger.channel\linker.messenger.channel.csproj" />
<ProjectReference Include="..\linker.messenger.exroute\linker.messenger.exroute.csproj" />
<ProjectReference Include="..\linker.messenger.firewall\linker.messenger.firewall.csproj" />
<ProjectReference Include="..\linker.messenger.signin\linker.messenger.signin.csproj" />
<ProjectReference Include="..\linker.messenger\linker.messenger.csproj" />
<ProjectReference Include="..\linker.snat\linker.snat.csproj" />

View File

@@ -26,21 +26,23 @@ namespace linker.messenger.store.file.firewall
public IEnumerable<FirewallRuleInfo> GetAll(FirewallSearchInfo info)
{
IEnumerable<FirewallRuleInfo> list = liteCollection.FindAll()
.Where(c => c.GroupId == info.GroupId && c.Disabled == info.Disabled)
.Where(c => c.GroupId == info.GroupId)
.Where(c => (c.Protocol & info.Protocol) > 0)
.Where(c => (c.Action & info.Action) > 0);
if (string.IsNullOrWhiteSpace(info.SrcName) == false)
if (info.Disabled != -1)
{
list = list.Where(c => c.SrcName.Contains(info.SrcName));
list = list.Where(c => c.Disabled == Convert.ToBoolean(info.Disabled));
}
if (string.IsNullOrWhiteSpace(info.DstCidr) == false)
if (string.IsNullOrWhiteSpace(info.Str) == false)
{
list = list.Where(c => c.DstCIDR.Contains(info.DstCidr));
}
if (string.IsNullOrWhiteSpace(info.DstPort) == false)
{
list = list.Where(c => c.DstPort.Contains(info.DstPort));
list = list.Where(c =>
(c.SrcName != null && c.SrcName.Contains(info.Str)) ||
(c.DstCIDR != null && c.DstCIDR.Contains(info.Str)) ||
(c.DstPort != null && c.DstPort.Contains(info.Str)) ||
(c.Remark != null && c.Remark.Contains(info.Str))
);
}
return list.OrderBy(c => c.OrderBy);
@@ -55,6 +57,7 @@ namespace linker.messenger.store.file.firewall
{
if (string.IsNullOrWhiteSpace(rule.Id))
{
rule.Id = ObjectId.NewObjectId().ToString();
return liteCollection.Insert(rule) != null;
}
else
@@ -69,7 +72,8 @@ namespace linker.messenger.store.file.firewall
Protocol = rule.Protocol,
Action = rule.Action,
OrderBy = rule.OrderBy,
Disabled = rule.Disabled
Disabled = rule.Disabled,
Remark = rule.Remark
}, c => c.Id == rule.Id) > 0;
}
}

View File

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

View File

@@ -8,6 +8,8 @@ namespace linker.messenger.store.file
{
public bool OnlyNode { get; set; }
public string ImportKey { get; set; } = string.Empty;
private SignInClientServerInfo[] servers = new SignInClientServerInfo[] {
#if DEBUG

View File

@@ -18,9 +18,9 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker messenger sync</PackageReleaseNotes>
<Version>1.7.8</Version>
<AssemblyVersion>1.7.8</AssemblyVersion>
<FileVersion>1.7.8</FileVersion>
<Version>1.7.9</Version>
<AssemblyVersion>1.7.9</AssemblyVersion>
<FileVersion>1.7.9</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

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

View File

@@ -35,7 +35,10 @@ namespace linker.messenger.tuntap
this.exRouteTransfer = exRouteTransfer;
//与服务器连接刷新一下IP
signInClientState.OnSignInSuccess += (times) => tuntapConfigTransfer.RefreshIP();
signInClientState.OnSignInSuccess += (times) =>
{
_ = CheckDevice();
};
//初始化网卡
tuntapTransfer.Initialize(this);
@@ -70,7 +73,6 @@ namespace linker.messenger.tuntap
tuntapDecenter.Refresh(); DeleteForward();
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Warning("tuntap shutdown after");
tuntapConfigTransfer.SetRunning(false);
};
//配置有更新,去同步一下
@@ -87,6 +89,19 @@ namespace linker.messenger.tuntap
tuntapProxy.Callback = this;
CheckDeviceTask();
}
public async Task Callback(LinkerTunDevicPacket packet)
{
await tuntapProxy.InputPacket(packet).ConfigureAwait(false);
}
public async ValueTask Close(ITunnelConnection connection)
{
tuntapDecenter.Refresh();
await ValueTask.CompletedTask.ConfigureAwait(false);
}
public void Receive(ITunnelConnection connection, ReadOnlyMemory<byte> buffer)
{
tuntapTransfer.Write(connection.RemoteMachineId, buffer);
}
private OperatingManager checking = new OperatingManager();
@@ -120,21 +135,6 @@ namespace linker.messenger.tuntap
checking.StopOperation();
}
}
public async Task Callback(LinkerTunDevicPacket packet)
{
await tuntapProxy.InputPacket(packet).ConfigureAwait(false);
}
public async ValueTask Close(ITunnelConnection connection)
{
tuntapDecenter.Refresh();
await ValueTask.CompletedTask.ConfigureAwait(false);
}
public void Receive(ITunnelConnection connection, ReadOnlyMemory<byte> buffer)
{
tuntapTransfer.Write(connection.RemoteMachineId, buffer);
}
/// <summary>
/// 重启网卡
/// </summary>
@@ -154,7 +154,10 @@ namespace linker.messenger.tuntap
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Warning($"stop device");
tuntapTransfer.Shutdown();
if (tuntapTransfer.Shutdown())
{
tuntapConfigTransfer.SetRunning(false);
}
}
/// <summary>

View File

@@ -43,6 +43,11 @@ namespace linker.messenger.tuntap
this.serializer = serializer;
}
/// <summary>
/// 连接
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public ConnectionListInfo Connections(ApiControllerParamsInfo param)
{
ulong hashCode = ulong.Parse(param.Content);
@@ -57,12 +62,45 @@ namespace linker.messenger.tuntap
return new ConnectionListInfo { HashCode = version };
}
/// <summary>
/// 删除连接
/// </summary>
/// <param name="param"></param>
[Access(AccessValue.TunnelRemove)]
public void RemoveConnection(ApiControllerParamsInfo param)
{
tuntapProxy.RemoveConnection(param.Content);
}
/// <summary>
/// 路由表
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public async Task<Dictionary<string, string>> Routes(ApiControllerParamsInfo param)
{
if (param.Content == signInClientStore.Id)
{
return tuntapProxy.GetRoutes();
}
else
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)TuntapMessengerIds.RoutesForward,
Payload = serializer.Serialize(param.Content)
}).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK && resp.Data.Length > 0)
{
return serializer.Deserialize<Dictionary<string, string>>(resp.Data.Span);
}
}
return new Dictionary<string, string>();
}
/// <summary>
/// 获取所有客户端的网卡信息
/// </summary>

View File

@@ -152,7 +152,6 @@ namespace linker.messenger.tuntap
LoggerHelper.Instance.Debug($"tuntap cache clear");
}
}
/// <summary>
/// 设置IP等下有连接进来用IP匹配才能知道这个连接是要连谁
/// </summary>
@@ -199,5 +198,13 @@ namespace linker.messenger.tuntap
}
}
/// <summary>
/// 获取路由表
/// </summary>
/// <returns></returns>
public Dictionary<string, string> GetRoutes()
{
return cidrManager.Routes;
}
}
}

View File

@@ -31,14 +31,14 @@ namespace linker.messenger.tuntap
Helper.OnAppExit += Helper_OnAppExit;
if (OperatingSystem.IsAndroid() == false)
{
AppDomain.CurrentDomain.ProcessExit += (s, e) => linkerTunDeviceAdapter.Shutdown();
Console.CancelKeyPress += (s, e) => linkerTunDeviceAdapter.Shutdown();
AppDomain.CurrentDomain.ProcessExit += (s, e) => Shutdown();
Console.CancelKeyPress += (s, e) => Shutdown();
}
}
private void Helper_OnAppExit(object sender, EventArgs e)
{
linkerTunDeviceAdapter.Shutdown();
Shutdown();
}
public void Initialize(ILinkerTunDeviceCallback linkerTunDeviceCallback)
@@ -110,17 +110,17 @@ namespace linker.messenger.tuntap
/// <summary>
/// 停止网卡
/// </summary>
public void Shutdown(bool notify = true)
public bool Shutdown()
{
if (operatingManager.StartOperation() == false)
{
return;
return false;
}
try
{
if (notify) OnShutdownBefore();
OnShutdownBefore();
linkerTunDeviceAdapter.Shutdown();
if (notify) OnShutdownSuccess();
OnShutdownSuccess();
}
catch (Exception ex)
{
@@ -131,10 +131,10 @@ namespace linker.messenger.tuntap
}
finally
{
if (notify)
OnShutdownAfter();
operatingManager.StopOperation();
}
return true;
}
/// <summary>
/// 刷新网卡

View File

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

View File

@@ -90,6 +90,13 @@ namespace linker.messenger.tuntap.messenger
}, (ushort)TuntapMessengerIds.SubscribeForwardTest);
});
}
[MessengerId((ushort)TuntapMessengerIds.Routes)]
public void Routes(IConnection connection)
{
connection.Write(serializer.Serialize(tuntapProxy.GetRoutes()));
}
}
@@ -285,5 +292,41 @@ namespace linker.messenger.tuntap.messenger
}
}
[MessengerId((ushort)TuntapMessengerIds.RoutesForward)]
public void RoutesForward(IConnection connection)
{
uint requestid = connection.ReceiveRequestWrap.RequestId;
string machineid = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
if (signCaching.TryGet(machineid, out SignCacheInfo cache) && signCaching.TryGet(connection.Id, out SignCacheInfo cache1) && cache.GroupId == cache1.GroupId)
{
messengerSender.SendReply(new MessageRequestWrap
{
Connection = cache.Connection,
MessengerId = (ushort)TuntapMessengerIds.Routes,
}).ContinueWith((result) =>
{
messengerSender.ReplyOnly(new MessageResponseWrap
{
Connection = connection,
RequestId = requestid,
Code = MessageResponeCodes.OK,
Payload = result.Result.Data
}, (ushort)TuntapMessengerIds.RoutesForward);
});
}
else
{
messengerSender.ReplyOnly(new MessageResponseWrap
{
Connection = connection,
RequestId = requestid,
Code = MessageResponeCodes.OK,
Payload = Helper.EmptyArray
}, (ushort)TuntapMessengerIds.RoutesForward);
}
}
}
}

View File

@@ -22,6 +22,10 @@
SubscribeForwardTest = 2214,
SubscribeForwardTestForward = 2215,
Routes = 2216,
RoutesForward = 2217,
None = 2299
}
}

View File

@@ -177,6 +177,17 @@ namespace linker.messenger.updater
updaterTransfer.Check();
}
}
public async Task<bool> CheckKey(ApiControllerParamsInfo param)
{
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = signInClientState.Connection,
MessengerId = (ushort)UpdaterMessengerIds.CheckKey,
Payload = serializer.Serialize(param.Content)
}).ConfigureAwait(false);
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
}
}

View File

@@ -8,6 +8,7 @@ namespace linker.messenger.updater
{
private readonly UpdaterClientTransfer updaterTransfer;
private readonly ISerializer serializer;
public UpdaterClientMessenger(UpdaterClientTransfer updaterTransfer, ISerializer serializer)
{
this.updaterTransfer = updaterTransfer;
@@ -86,6 +87,8 @@ namespace linker.messenger.updater
{
updaterTransfer.Check();
}
}
@@ -347,5 +350,13 @@ namespace linker.messenger.updater
}
}
}
[MessengerId((ushort)UpdaterMessengerIds.CheckKey)]
public void CheckKey(IConnection connection)
{
string key = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
connection.Write(updaterServerStore.ValidateSecretKey(key) ? Helper.TrueArray : Helper.FalseArray);
}
}
}

View File

@@ -30,6 +30,8 @@
Update170 = 2616,
UpdateServer170 = 2617,
CheckKey = 2618,
Max = 2299
}
}

View File

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

View File

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

View File

@@ -1,10 +1,14 @@
using linker.libs;
using System.Collections.Concurrent;
using System.Collections.Frozen;
using System.Net;
using System.Net.Sockets;
using static linker.snat.LinkerSrcNat;
namespace linker.snat
{
/// <summary>
/// 开启后默认阻止
/// </summary>
public sealed class LinkerFirewall
{
private ConcurrentDictionary<(string srcId, uint dst, ushort dstPort, ProtocolType pro), bool> cacheMap = new ConcurrentDictionary<(string srcId, uint dst, ushort dstPort, ProtocolType pro), bool>();
@@ -14,7 +18,6 @@ namespace linker.snat
public LinkerFirewall()
{
}
/// <summary>
@@ -39,6 +42,7 @@ namespace linker.snat
}
//末尾有一条默认允许所有的规则
/*
rules.Add(new LinkerFirewallRuleInfo
{
SrcId = string.Empty,
@@ -47,27 +51,44 @@ namespace linker.snat
Protocol = LinkerFirewallProtocolType.All,
Action = LinkerFirewallAction.Allow,
});
*/
buildedRules = rules.Select(c =>
{
string[] ports = c.DstPort.Split('-');
int portStart = int.Parse(ports[0]), portEnd = portStart;
if (ports.Length == 2)
try
{
portEnd = int.Parse(ports[1]);
int portStart = 0, portEnd = 65535;
HashSet<int> ports = new HashSet<int>();
if (c.DstPort != "0" && c.DstPort != "*")
{
if (c.DstPort.Contains('-'))
{
string[] arr = c.DstPort.Split('-');
portStart = int.Parse(arr[0]);
portEnd = int.Parse(arr[1]);
}
else if (portStart == 0)
else if (c.DstPort.Contains(','))
{
portEnd = 65535;
ports = c.DstPort.Split(',').Select(c => int.Parse(c)).ToHashSet();
}
else
{
portEnd = portStart = int.Parse(c.DstPort);
}
}
IPAddress ip = IPAddress.Any;
byte prefixLength = 0;
if (c.DstCIDR != "0" && c.DstCIDR != "*")
{
string[] cidr = c.DstCIDR.Split('/');
IPAddress ip = IPAddress.Parse(cidr[0]);
byte prefixLength = 32;
ip = IPAddress.Parse(cidr[0]);
prefixLength = 32;
if (cidr.Length == 2)
{
prefixLength = byte.Parse(cidr[1]);
}
}
return new LinkerFirewallRuleBuildInfo
{
@@ -76,10 +97,17 @@ namespace linker.snat
DstPrefixLength = NetworkHelper.ToPrefixValue(prefixLength),
DstPortStart = portStart,
DstPortEnd = portEnd,
DstPorts = ports,
Protocol = c.Protocol,
Action = c.Action
};
}).ToList();
}
catch (Exception)
{
}
return null;
}).Where(c => c != null).ToList();
cacheMap.Clear();
}
@@ -93,9 +121,12 @@ namespace linker.snat
/// <returns></returns>
public bool Check(string srcId, IPEndPoint dstEP, ProtocolType protocol)
{
if (this.state != LinkerFirewallState.Enabled) return true;
if (dstEP.AddressFamily != AddressFamily.InterNetwork) return false;
uint dst = NetworkHelper.ToValue(dstEP.Address);
ushort dstPort = (ushort)dstEP.Port;
return Check(srcId, dst, dstPort, (byte)(dstEP.AddressFamily == AddressFamily.InterNetwork ? 4 : 6), protocol);
return Check(srcId, dst, dstPort, protocol);
}
/// <summary>
/// 检查数据包是否符合规则
@@ -105,7 +136,11 @@ namespace linker.snat
/// <returns></returns>
public bool Check(string srcId, ReadOnlyMemory<byte> packet)
{
if (this.state != LinkerFirewallState.Enabled) return true;
IPV4Packet ipv4 = new IPV4Packet(packet.Span);
if (ipv4.Version != 4) return true;
uint dst = ipv4.DstAddr;
ushort dstPort = ipv4.Protocol switch
{
@@ -113,39 +148,18 @@ namespace linker.snat
ProtocolType.Tcp => ipv4.DstPort,
_ => 0,
};
return Check(srcId, dst, dstPort, ipv4.Version, ipv4.Protocol);
return Check(srcId, dst, dstPort, ipv4.Protocol);
}
private bool Check(string srcId, uint ip, ushort port, byte version, ProtocolType protocol)
private bool Check(string srcId, uint ip, ushort port, ProtocolType protocol)
{
//防火墙未启用
if (this.state != LinkerFirewallState.Enabled)
{
return true;
}
//没有配置规则
if (buildedRules.Count == 0)
{
return true;
}
//仅IPV4
if (version != 4)
{
return true;
}
LinkerFirewallProtocolType _rotocol = protocol switch
{
ProtocolType.Icmp => LinkerFirewallProtocolType.ICMP,
ProtocolType.Tcp => LinkerFirewallProtocolType.TCP,
ProtocolType.Udp => LinkerFirewallProtocolType.UDP,
_ => LinkerFirewallProtocolType.None,
};
//不在协议列表内
if (_rotocol == LinkerFirewallProtocolType.None)
{
return true;
}
if (_rotocol == LinkerFirewallProtocolType.None) return true; //不支持的协议
//之前已经检查过
(string srcId, uint dst, ushort dstPort, ProtocolType pro) key = (srcId, ip, port, protocol);
@@ -157,9 +171,9 @@ namespace linker.snat
//按顺序匹配规则
foreach (LinkerFirewallRuleBuildInfo item in buildedRules)
{
bool match = (string.IsNullOrWhiteSpace(item.SrcId) || item.SrcId == srcId)
bool match = (item.SrcId == "*" || item.SrcId == srcId)
&& ((ip & item.DstPrefixLength) == item.DstNetwork)
&& (port >= item.DstPortStart && port <= item.DstPortEnd)
&& ((port >= item.DstPortStart && port <= item.DstPortEnd) || item.DstPorts.Contains(port))
&& item.Protocol.HasFlag(_rotocol);
if (match)
{
@@ -168,10 +182,9 @@ namespace linker.snat
return value;
}
}
return true;
return false;
}
sealed class LinkerFirewallRuleBuildInfo
{
public string SrcId { get; set; } = string.Empty;
@@ -181,6 +194,8 @@ namespace linker.snat
public int DstPortStart { get; set; }
public int DstPortEnd { get; set; }
public HashSet<int> DstPorts { get; set; }
public LinkerFirewallProtocolType Protocol { get; set; }
public LinkerFirewallAction Action { get; set; }
}
@@ -201,9 +216,7 @@ namespace linker.snat
None = 0,
TCP = 1,
UDP = 2,
ICMP = 4,
All = TCP | UDP | ICMP
All = TCP | UDP
}
public enum LinkerFirewallAction
{

View File

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

View File

@@ -279,7 +279,7 @@ namespace linker.tun
if (ProtocolType == ProtocolType.Tcp || ProtocolType == ProtocolType.Udp)
{
SourcePort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(42, 2).ToUInt16());
DistPort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(24, 2).ToUInt16());
DistPort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(44, 2).ToUInt16());
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace linker.tun
{
@@ -202,12 +203,11 @@ namespace linker.tun
error = "NetNat need CIDR,like 10.18.18.0/24";
return;
}
CommandHelper.PowerShell($"start-service WinNat", [], out error);
CommandHelper.PowerShell($"Install-WindowsFeature -Name Routing -IncludeManagementTools", [], out error);
CommandHelper.PowerShell($"Set-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\" -Name \"IPEnableRouter\" -Value 1", [], out error);
CommandHelper.PowerShell($"Remove-NetNat -Name {Name} -Confirm:$false", [], out error);
SetupNat();
IPAddress network = NetworkHelper.ToNetworkIP(this.address, NetworkHelper.ToPrefixValue(prefixLength));
RemoveOldNat($"{network}/{prefixLength}");
CommandHelper.PowerShell($"New-NetNat -Name {Name} -InternalIPInterfaceAddressPrefix {network}/{prefixLength}", [], out error);
string result = CommandHelper.PowerShell($"Get-NetNat", [], out string e);
@@ -222,6 +222,40 @@ namespace linker.tun
error = ex.Message;
}
}
private void SetupNat()
{
CommandHelper.PowerShell($"start-service WinNat", [], out string error);
CommandHelper.PowerShell($"Install-WindowsFeature -Name Routing -IncludeManagementTools", [], out error);
CommandHelper.PowerShell($"Set-ItemProperty -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\" -Name \"IPEnableRouter\" -Value 1", [], out error);
}
private void RemoveOldNat(string addressPrefix)
{
try
{
string netnats = CommandHelper.PowerShell($"Get-NetNat", [], out string e);
IEnumerable<string> names = netnats
.Split("\r\n\r\n")
.Where(c => string.IsNullOrWhiteSpace(c) == false)
.Select(c =>
{
return c.Split("\r\n")
.Where(c => string.IsNullOrWhiteSpace(c) == false)
.Select(c => c.Split(':')).Where(c => c.Length == 2).Select(c => { c[0] = c[0].Trim(); c[1] = c[1].Trim(); return c; })
.ToDictionary(c => c[0], c => c[1]);
})
.Where(c => (c.TryGetValue("Name", out string name) && name == Name) || (c.TryGetValue("InternalIPInterfaceAddressPrefix", out string ip) && ip == addressPrefix))
.Select(c => c["Name"]);
foreach (var name in names)
{
CommandHelper.PowerShell($"Remove-NetNat -Name {name} -Confirm:$false", [], out string error);
}
}
catch (Exception)
{
}
}
public void RemoveNat(out string error)
{

View File

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

View File

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

View File

@@ -0,0 +1,14 @@
import { sendWebsocketMsg } from './request'
export const getFirewall = (data) => {
return sendWebsocketMsg('firewall/get', data);
}
export const addFirewall = (data) => {
return sendWebsocketMsg('firewall/add', data);
}
export const removeFirewall = (data) => {
return sendWebsocketMsg('firewall/remove', data);
}
export const stateFirewall = (data) => {
return sendWebsocketMsg('firewall/state', data);
}

View File

@@ -36,3 +36,6 @@ export const relayCdkeyImport = (data) => {
export const relayUpdateNode = (data) => {
return sendWebsocketMsg('relay/UpdateNode', data);
}
export const checkRelayKey = (key) => {
return sendWebsocketMsg('relay/checkkey',key);
}

View File

@@ -32,3 +32,6 @@ export const startSForwardInfo = (data) => {
export const stopSForwardInfo = (data) => {
return sendWebsocketMsg('sforward/stop', data);
}
export const checkSForwardKey = (key) => {
return sendWebsocketMsg('sforward/checkkey',key);
}

View File

@@ -35,3 +35,6 @@ export const setSignInGroups = (data) => {
export const getSignInNames = () => {
return sendWebsocketMsg('signIn/names');
}
export const checkSignInKey = (key) => {
return sendWebsocketMsg('signIn/checkkey',key);
}

View File

@@ -8,6 +8,10 @@ export const removeTuntapConnection = (id) => {
return sendWebsocketMsg('tuntap/removeconnection', id);
}
export const getTuntapRoutes = (machineid) => {
return sendWebsocketMsg('tuntap/routes', machineid);
}
export const getTuntapInfo = (hashcode = '0') => {
return sendWebsocketMsg('tuntap/get', hashcode);
}

View File

@@ -42,3 +42,6 @@ export const subscribeUpdater = () => {
export const checkUpdater = (data) => {
return sendWebsocketMsg('updater/check', data);
}
export const checkUpdaterKey = (key) => {
return sendWebsocketMsg('updater/checkkey',key);
}

View File

@@ -1 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1727193027445" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="105724" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512"><path d="M0 0m512 0l0 0q512 0 512 512l0 0q0 512-512 512l0 0q-512 0-512-512l0 0q0-512 512-512Z" fill="#818BA4" p-id="105725" data-spm-anchor-id="a313x.search_index.0.i18.1c553a81zI5OvT" class=""></path><path d="M800 617.472L752.128 288.8A75.936 75.936 0 0 0 677.312 224H346.72a76.096 76.096 0 0 0-74.88 64.736L224 618.144v106.112A75.68 75.68 0 0 0 299.68 800h424.576A75.936 75.936 0 0 0 800 724.256v-106.784z m-46.144-4.16H270.336l46.208-318.016a30.528 30.528 0 0 1 30.176-26.176h330.528c15.168 0 28.032 11.168 30.24 26.176l46.368 318.016zM269.12 658.432H754.88v65.92a30.592 30.592 0 0 1-30.528 30.496H299.68a30.592 30.592 0 0 1-30.528-30.528v-65.888z m442.496 25.728h-45.184v44.96h45.12V684.16h0.064z m-115.936 0h45.056v45.12h-45.184v-45.12h0.128z m-283.136 0h44.96v45.12H312.48v-45.12h0.096z m70.688 0h45.12v45.12h-45.12v-45.12z m141.568 0h45.12v45.12h-45.12v-45.12z m-70.72 0H499.2v45.12H454.08v-45.12h0.064z m158.816-276.48h-67.296l-7.456-44.928h47.68l-73.28-56-73.12 56h47.712l-8.768 44.928h-67.264v-33.696l-67.264 56.096 67.264 44.8v-33.6h67.264v67.296h-67.264l100.864 67.2 100.864-67.232h-67.232v-67.232h67.232v33.6l67.264-44.8-67.264-56.128v33.696h0.064z" fill="#FFFFFF" p-id="105726"></path></svg>
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746858069918" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="37587" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512"><path d="M22.022887 304.77077C56.710445 137.220906 163.281886 43.858897 329.526167 15.673656c122.904033-20.863734 245.859265-21.119731 368.532901 0.563193 171.185017 30.258814 274.070106 129.047955 306.863287 299.157786 25.343677 131.479924 25.727672 264.34223-0.383995 395.694155-35.071553 166.423478-144.382159 269.154968-310.012047 297.23781-122.904033 20.863734-245.859265 21.119731-368.532901-0.563193C154.782795 977.504593 51.436912 873.774715 18.64373 703.664884c-26.623661-132.350313-24.063693-266.057408 3.404757-398.894114z" fill="#2FC25B" p-id="37588"></path><path d="M526.336457 557.925942a23.193304 23.193304 0 0 0 22.604512-22.604511 23.193304 23.193304 0 0 0-22.604512-22.630112 23.193304 23.193304 0 0 0-22.604511 22.630112c0 12.031847 10.547066 22.604512 22.604511 22.604511z m0-75.365439a23.193304 23.193304 0 0 0 22.604512-22.604511 23.193304 23.193304 0 0 0-22.604512-22.604512 23.193304 23.193304 0 0 0-22.604511 22.604512c0 12.031847 10.547066 22.604512 22.604511 22.604511z m7.526304 120.574463h-15.052608a23.193304 23.193304 0 0 0-22.604512 22.604512c0 12.057446 10.547066 22.604512 22.604512 22.604512h15.052608a23.193304 23.193304 0 0 0 22.630112-22.604512 23.193304 23.193304 0 0 0-22.630112-22.604512z m186.903217-203.466206c-10.547066-81.406962-79.870982-143.204574-164.273105-143.204574a166.26988 166.26988 0 0 0-155.262021 105.521855h-10.547065a105.08666 105.08666 0 0 0-102.475494 81.406962c-63.307993 18.07337-108.542616 76.85022-108.542616 144.663755 0 82.917343 67.839135 150.730878 150.730879 150.730878h346.670779c91.928428-4.531142 165.783486-79.870982 165.783487-173.30979 0-78.386201-51.250547-143.204574-122.084844-165.809086z m-284.873168 248.67523c0 16.588588-13.567827 30.156416-30.130815 30.156415h-15.078208c-16.562989 0-30.130816-13.567827-30.130816-30.156415V497.664311c0-16.588588 13.567827-30.156416 30.130816-30.156416h15.078208c16.588588 0 30.130816 13.567827 30.130815 30.156416v150.705278z m150.730879 0c0 16.588588-13.567827 30.156416-30.130816 30.156415h-60.287232c-16.588588 0-30.156416-13.567827-30.156415-30.156415v-210.99251c0-16.588588 13.567827-30.156416 30.156415-30.156416h60.287232c16.562989 0 30.130816 13.567827 30.130816 30.156416v210.99251z m105.521854 0c0 16.588588-13.567827 30.156416-30.156415 30.156415h-15.078208c-16.562989 0-30.130816-13.567827-30.130816-30.156415V497.664311c0-16.588588 13.567827-30.156416 30.130816-30.156416h15.078208c16.588588 0 30.156416 13.567827 30.156415 30.156416v150.705278z" fill="#FFFFFF" p-id="37589"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1746857930595" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="26327" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512"><path d="M0 0m512 0l0 0q512 0 512 512l0 0q0 512-512 512l0 0q-512 0-512-512l0 0q0-512 512-512Z" fill="#6F5EA9" p-id="26328"></path><path d="M717.5168 469.333333h-34.6112v-83.899733c0-78.9504-69.188267-143.1552-154.146133-143.1552-84.992 0-154.146133 64.2048-154.146134 143.1552v83.8656h-33.9968c-27.8528 0-50.4832 20.957867-50.4832 46.8992v225.348267c0 25.9072 22.6304 46.865067 50.4832 46.865066h376.900267c27.8528 0 50.4832-20.957867 50.4832-46.865066v-225.348267c0-25.941333-22.6304-46.8992-50.4832-46.8992z m-278.528-83.797333c0-46.011733 40.311467-83.421867 89.770667-83.421867 49.4592 0 89.770667 37.410133 89.770666 83.421867v83.8656h-179.541333v-83.8656z m123.118933 295.253333c0 17.8176-15.598933 32.290133-34.7136 32.290134-19.182933 0-34.679467-14.472533-34.679466-32.256v-97.5872c0-17.749333 15.598933-32.221867 34.679466-32.221867 19.217067 0 34.7136 14.4384 34.7136 32.221867v97.5872z" fill="#FFFFFF" p-id="26329"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -484,6 +484,12 @@ h3.title {
.el-input__inner {
font-size: 13px;
}
.el-input.success .el-input__wrapper{
box-shadow: 0 0 0 1px #008000 inset;
}
.el-input.error .el-input__wrapper{
box-shadow: 0 0 0 1px #ff6600 inset;
}
.el-dialog--center .el-dialog__body {
padding-top: 1rem !important;

View File

@@ -10,11 +10,13 @@ export default {
'common.access': 'No access',
'common.relay': 'Relay',
'common.p2p': 'P2P',
'common.refresh': 'Refresh',
'head.home': 'Home',
'head.server': 'Server',
'head.protocol': 'P2P Protocol',
'head.action': 'Action',
'head.firewall': 'Firewall',
'head.logger': 'Logs',
'head.refresh': 'Refresh',
@@ -246,4 +248,26 @@ export default {
'server.asyncTunnelTransports': 'Tunnel transports',
'server.asyncSignInUserId': 'User Id',
'firewall.rule': 'Firewall rule',
'firewall.srcName': 'Src Device',
'firewall.dstCidr': 'IP',
'firewall.dstPort': 'Port',
'firewall.protocol': 'Protocol',
'firewall.protocolall': 'Protocol all',
'firewall.actionall': 'Action all',
'firewall.action': 'Action',
'firewall.actionAllow': 'Allow',
'firewall.actionAllowAll': 'Allow all',
'firewall.actionDeny': 'Deny',
'firewall.actionDenyAll': 'Deny all',
'firewall.orderby': 'Order',
'firewall.enabled': 'Enable',
'firewall.disabled': 'Disable',
'firewall.disabledAll': 'All state',
'firewall.del': 'Del',
'firewall.edit': 'Edit',
'firewall.delConfirm': 'Are you sure to delete this rule?',
'firewall.switch': 'Firewall switch,open or close',
'firewall.remark': 'Remark',
}

View File

@@ -10,12 +10,14 @@ export default {
'common.access': '无权限',
'common.relay': '中继',
'common.p2p': '打洞',
'common.refresh': '刷新',
'head.home': '首页',
'head.server': '服务器',
'head.group': '分组',
'head.protocol': '打洞协议',
'head.action': '自定义验证',
'head.action': '验证',
'head.firewall': '防火墙',
'head.logger': '日志',
'head.refresh': '刷新',
@@ -341,4 +343,28 @@ export default {
'server.asyncUpdaterSecretKey': '更新密钥',
'server.asyncTunnelTransports': '打洞协议',
'server.asyncSignInUserId': '用户唯一标识',
'firewall.rule': '防火墙协议',
'firewall.srcName': '源设备',
'firewall.dstCidr': 'IP',
'firewall.dstPort': '端口',
'firewall.protocolall': '全部协议',
'firewall.protocol': '协议',
'firewall.actionall': '全部操作',
'firewall.action': '操作',
'firewall.actionAllow': '允许',
'firewall.actionAllowAll': '允许全部',
'firewall.actionDeny': '阻止',
'firewall.actionDenyAll': '阻止全部',
'firewall.orderby': '顺序',
'firewall.enabled': '启用',
'firewall.disabled': '禁用',
'firewall.disabledAll': '全部状态',
'firewall.del': '删除',
'firewall.edit': '修改',
'firewall.delConfirm': '确认删除规则?',
'firewall.switch': '防火墙开关,是否开启防火墙',
'firewall.remark': '备注',
}

View File

@@ -26,6 +26,11 @@ const routes = [
name: 'FullAction',
component: () => import('@/views/full/action/Index.vue')
},
{
path: '/full/firewall.html',
name: 'FullFirewall',
component: () => import('@/views/full/firewall/Index.vue')
},
{
path: '/full/logger.html',
name: 'FullLogger',

View File

@@ -18,7 +18,10 @@
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg"/><span>{{$t('head.protocol')}}</span></router-link>
</li>
<li v-if="hasAction">
<router-link :to="{name:'FullAction'}"><img src="@/assets/anquan.svg"/><span>{{$t('head.action')}}</span></router-link>
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg"/><span>{{$t('head.action')}}</span></router-link>
</li>
<li v-if="hasFirewall">
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg"/><span>{{$t('head.firewall')}}</span></router-link>
</li>
<li v-if="hasLogger">
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg"/><span>{{$t('head.logger')}}</span></router-link>
@@ -35,7 +38,10 @@
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg"/><span>{{$t('head.protocol')}}</span></router-link>
</li>
<li v-if="hasAction && route.name == 'FullAction'">
<router-link :to="{name:'FullAction'}"><img src="@/assets/anquan.svg"/><span>{{$t('head.action')}}</span></router-link>
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg"/><span>{{$t('head.action')}}</span></router-link>
</li>
<li v-if="hasFirewall && route.name == 'FullFirewall'">
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg"/><span>{{$t('head.firewall')}}</span></router-link>
</li>
<li v-if="hasLogger && route.name == 'FullLogger'">
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg"/> <span>{{$t('head.logger')}}</span></router-link>
@@ -53,16 +59,19 @@
<el-dropdown-item>
<router-link :to="{name:'FullIndex'}"><img src="@/assets/shouye.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.home')}}</router-link>
</el-dropdown-item>
<el-dropdown-item>
<el-dropdown-item v-if="hasConfig">
<router-link :to="{name:'FullServers'}"><img src="@/assets/fuwuqi.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.server')}}</router-link>
</el-dropdown-item>
<el-dropdown-item>
<el-dropdown-item v-if="hasTransport">
<router-link :to="{name:'FullTransport'}"><img src="@/assets/dadong.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.protocol')}}</router-link>
</el-dropdown-item>
<el-dropdown-item>
<router-link :to="{name:'FullAction'}"><img src="@/assets/anquan.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.action')}}</router-link>
<el-dropdown-item v-if="hasAction">
<router-link :to="{name:'FullAction'}"><img src="@/assets/login.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.action')}}</router-link>
</el-dropdown-item>
<el-dropdown-item>
<el-dropdown-item v-if="hasFirewall">
<router-link :to="{name:'FullFirewall'}"><img src="@/assets/anquan.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.action')}}</router-link>
</el-dropdown-item>
<el-dropdown-item v-if="hasLogger">
<router-link :to="{name:'FullLogger'}"><img src="@/assets/rizhi.svg" height="20" style="vertical-align: text-top;"/> {{$t('head.logger')}}</router-link>
</el-dropdown-item>
</el-dropdown-menu>
@@ -73,8 +82,8 @@
<el-dropdown>
<span class="el-dropdown-link">
{{localeOptions[locale]}}
<el-icon class="el-icon--right">
<arrow-down />
<el-icon>
<ArrowDown />
</el-icon>
</span>
<template #dropdown>
@@ -92,7 +101,7 @@
</template>
<script>
import {Operation} from '@element-plus/icons-vue'
import {Operation,ArrowDown} from '@element-plus/icons-vue'
import { injectGlobalData } from '@/provide';
import { computed, ref} from 'vue';
import Background from './Background.vue';
@@ -100,7 +109,7 @@ import { LOCALE_OPTIONS } from '@/lang'
import useLocale from '@/lang/provide'
import { useRoute } from 'vue-router';
export default {
components:{Background,Operation},
components:{Background,Operation,ArrowDown},
setup() {
const route = useRoute();
@@ -110,6 +119,8 @@ export default {
const hasTransport = computed(()=>globalData.value.hasAccess('Transport'));
const hasAction = computed(()=>globalData.value.hasAccess('Action'));
const hasGroup = computed(()=>globalData.value.hasAccess('Group'));
const hasFirewall = computed(()=>globalData.value.hasAccess('FirewallSelf'));
const localeOptions = ref(LOCALE_OPTIONS);
const { changeLocale, currentLocale } = useLocale()
@@ -131,7 +142,7 @@ export default {
return {
route,globalData,hasConfig,hasGroup,
hasLogger,hasTransport,hasAction,localeOptions,locale,handleLocale,refresh
hasLogger,hasTransport,hasAction,hasFirewall,localeOptions,locale,handleLocale,refresh
}
}
}

View File

@@ -1,5 +1,5 @@
<template>
<div class="connect-point" @click="handleShow">
<div class="connect-point" @click="handleShow" v-if="state.isSelf == false">
<template v-if="state.connection && state.connection.Connected">
<template v-if="state.connection.Type == 0">
<span class="connect-point p2p" title="打洞直连" v-loading="state.connecting"></span>
@@ -30,7 +30,8 @@ export default {
const state = reactive({
connection:props.data,
transitionId:props.transitionId,
connecting:computed(()=>tunnel.value.p2pOperatings[props.row.MachineId] || tunnel.value.relayOperatings[props.row.MachineId])
connecting:computed(()=>tunnel.value.p2pOperatings[props.row.MachineId] || tunnel.value.relayOperatings[props.row.MachineId]),
isSelf:props.row.isSelf
});
watch(()=>props.data,()=>{
state.connection = props.data

View File

@@ -24,6 +24,7 @@
<TunnelEdit v-if="tunnel.showEdit" v-model="tunnel.showEdit" @change="handleTunnelRefresh"></TunnelEdit>
<ConnectionsEdit v-if="connections.showEdit" v-model="connections.showEdit" ></ConnectionsEdit>
<TuntapEdit v-if="tuntap.showEdit" v-model="tuntap.showEdit" @change="handleTuntapRefresh"></TuntapEdit>
<TuntapRoutes v-if="tuntap.showRoutes" v-model="tuntap.showRoutes" ></TuntapRoutes>
<Socks5Edit v-if="socks5.showEdit" v-model="socks5.showEdit" @change="handleSocks5Refresh"></Socks5Edit>
<TuntapLease v-if="tuntap.showLease" v-model="tuntap.showLease" @change="handleTuntapRefresh"></TuntapLease>
<ForwardEdit v-if="forward.showEdit" v-model="forward.showEdit" ></ForwardEdit>
@@ -51,6 +52,7 @@ import Tuntap from './Tuntap.vue'
import TuntapEdit from './TuntapEdit.vue'
import TuntapLease from './TuntapLease.vue'
import { provideTuntap } from './tuntap'
import TuntapRoutes from './TuntapRoutes.vue'
import Socks5 from './Socks5.vue'
import Socks5Edit from './Socks5Edit.vue'
@@ -76,13 +78,15 @@ import UpdaterConfirm from './UpdaterConfirm.vue'
import { provideFlow } from './flow'
import Stopwatch from './Stopwatch.vue'
export default {
components: {Sort,Oper,
Device,DeviceEdit,
AccessEdit,
Tunnel,TunnelEdit,
ConnectionsEdit,
Tuntap,TuntapEdit,TuntapLease,
Tuntap,TuntapEdit,TuntapLease,TuntapRoutes,
Socks5, Socks5Edit,
Forward,ForwardEdit,
SForwardEdit ,UpdaterConfirm,

View File

@@ -17,6 +17,7 @@
<el-dropdown-item v-else-if="hasApiPasswordOther" @click="handleApiPassword(scope.row)"><el-icon><HelpFilled /></el-icon> 管理接口</el-dropdown-item>
<el-dropdown-item @click="handleStopwatch(scope.row.MachineId,scope.row.MachineName)"><el-icon><Platform /></el-icon>它的信标</el-dropdown-item>
<el-dropdown-item @click="handleStopwatch('',$t('status.messenger'))"><el-icon><Platform /></el-icon>服务器信标</el-dropdown-item>
<el-dropdown-item @click="handleRoutes(scope.row.MachineId,scope.row.MachineName)"><el-icon><Paperclip /></el-icon>网卡路由</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@@ -29,16 +30,17 @@
import { signInDel } from '@/apis/signin';
import { exit } from '@/apis/updater';
import { injectGlobalData } from '@/provide';
import { Delete,SwitchButton,ArrowDown, Flag,HelpFilled,Platform } from '@element-plus/icons-vue'
import { Delete,SwitchButton,ArrowDown, Flag,HelpFilled,Platform,Paperclip } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus';
import { computed } from 'vue';
import { useAccess } from './access';
import { setApiPassword } from '@/apis/access';
import { useFlow } from './flow';
import { useTuntap } from './tuntap';
export default {
emits:['refresh','access'],
components:{Delete,SwitchButton,ArrowDown,Flag,HelpFilled,Platform},
components:{Delete,SwitchButton,ArrowDown,Flag,HelpFilled,Platform,Paperclip},
setup (props,{emit}) {
const globalData = injectGlobalData();
@@ -55,6 +57,7 @@ export default {
const hasApiPasswordOther = computed(()=>globalData.value.hasAccess('SetApiPasswordOther'));
const flow = useFlow();
const tuntap = useTuntap();
const handleDel = (machineId,machineName)=>{
@@ -113,9 +116,14 @@ export default {
flow.value.device.name = name;
flow.value.show = true;
}
const handleRoutes = (id,name)=>{
tuntap.value.device.id = id;
tuntap.value.device.name = name;
tuntap.value.showRoutes = true;
}
return {accessList,handleDel,handleExit,hasReboot,hasRemove,hasAccess,handleShowAccess,handleAccess,
hasApiPassword,hasApiPasswordOther,handleApiPassword,handleStopwatch
hasApiPassword,hasApiPasswordOther,handleApiPassword,handleStopwatch,handleRoutes
}
}
}

View File

@@ -0,0 +1,67 @@
<template>
<el-dialog v-model="state.show" append-to=".app-wrap" :title="`[${state.machineName}]上的路由`" top="1vh" >
<div>
<el-table :data="state.data" size="small" border height="500">
<el-table-column property="Ip" label="IP"></el-table-column>
<el-table-column property="Id" label="目标">
<template #default="scope">
<span>{{ state.names[scope.row.Id] }}</span>
</template>
</el-table-column>
</el-table>
</div>
</el-dialog>
</template>
<script>
import { reactive, watch,onMounted, onUnmounted } from 'vue';
import { useTuntap } from './tuntap';
import { getSignInNames } from '@/apis/signin';
import { getTuntapRoutes } from '@/apis/tuntap';
export default {
props: ['modelValue'],
emits: ['update:modelValue'],
setup(props, { emit }) {
const tuntap = useTuntap();
const state = reactive({
show: true,
machineId: tuntap.value.device.id,
machineName: tuntap.value.device.name,
data:[],
names: {},
timer: 0
});
watch(() => state.show, (val) => {
if (!val) {
setTimeout(() => {
emit('update:modelValue', val);
emit('change')
}, 300);
}
});
onMounted(() => {
getSignInNames().then((res)=>{
state.names = res.reduce((json,value)=>{ json[value.MachineId]=value.MachineName; return json; },{});
}).catch(()=>{});
getTuntapRoutes(state.machineId).then((res)=>{
state.data = Object.keys(res).map((value)=>{
return {
Ip: value,
Id: res[value]
}
});
}).catch(()=>{})
});
onUnmounted(() => {
})
return {
state
}
}
}
</script>
<style lang="stylus" scoped>
</style>

View File

@@ -48,7 +48,7 @@
<template v-if="tuntap.list[item.MachineId].Available == false">
<div class="flex disable" title="IP不生效可能是设备不在线">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
</template>
<template v-if="item1.Disabled">
<template v-else-if="item1.Disabled">
<div class="flex disable" title="已禁用">{{ item1.IP }} / {{ item1.PrefixLength }}</div>
</template>
<template v-else-if="item1.Exists">
@@ -125,14 +125,17 @@ export default {
}
const handleTuntapIP = (tuntap) => {
if(!props.config && machineId.value != tuntap.MachineId){
ElMessage.success('无权限1');
return;
}
if(machineId.value === tuntap.MachineId){
if(!hasTuntapChangeSelf.value){
ElMessage.success('无权限2');
return;
}
}else{
if(!hasTuntapChangeOther.value){
ElMessage.success('无权限3');
return;
}
}

View File

@@ -12,6 +12,9 @@ export const provideTuntap = () => {
hashcode: 0,
showLease: false,
device: {id:'',name:''},
showRoutes:false,
});
provide(tuntapSymbol, tuntap);

View File

@@ -0,0 +1,219 @@
<template>
<el-dialog class="options-center" :title="$t('firewall.rule')" destroy-on-close v-model="state.show" width="50rem" top="2vh">
<div>
<el-form ref="ruleFormRef" :model="state.ruleForm.Data" :rules="state.rules" label-width="auto">
<el-form-item :label="$t('firewall.srcName')" prop="SrcId">
<el-row class="w-100">
<el-col :span="12">
<el-select v-model="state.ruleForm.Data.SrcId" @change="handleMachineChange()"
filterable remote :loading="state.loading" :remote-method="handleMachineSearch">
<template #header>
<div class="t-c">
<div class="page-wrap">
<el-pagination small background layout="prev, pager, next"
:page-size="state.machineIds.Request.Size"
:total="state.machineIds.Count"
:pager-count="5"
:current-page="state.machineIds.Request.Page" @current-change="handleMachinePageChange" />
</div>
</div>
</template>
<el-option v-for="(item, index) in state.machineIds.List" :key="index" :label="item.MachineName" :value="item.MachineId">
</el-option>
</el-select>
</el-col>
<el-col :span="12"></el-col>
</el-row>
</el-form-item>
<el-form-item></el-form-item>
<el-form-item :label="$t('firewall.dstCidr')" prop="DstCIDR">
<el-row class="w-100">
<el-col :span="12">
<el-input v-model="state.ruleForm.Data.DstCIDR" />
</el-col>
<el-col :span="12">
10.18.1.1/2410.18.1.10*
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('firewall.dstPort')" prop="DstPort">
<el-row class="w-100">
<el-col :span="12">
<el-input v-model="state.ruleForm.Data.DstPort" />
</el-col>
<el-col :span="12">
8080-8880,4430*
</el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('firewall.protocol')" prop="Protocol">
<el-row class="w-100">
<el-col :span="12">
<el-select v-model="state.protocolChecks" multiple >
<el-option :value="item.value" :label="item.label" v-for="(item,index) in state.protocols"></el-option>
</el-select>
</el-col>
<el-col :span="12"></el-col>
</el-row>
</el-form-item>
<el-form-item :label="$t('firewall.action')" prop="Action">
<el-row class="w-100">
<el-col :span="12">
<el-select v-model="state.ruleForm.Data.Action" >
<el-option :value="item.value" :label="item.label" v-for="(item,index) in state.actions"></el-option>
</el-select>
</el-col>
<el-col :span="12"></el-col>
</el-row>
</el-form-item>
<el-form-item></el-form-item>
<el-form-item :label="$t('firewall.orderby')" prop="OrderBy">
<el-input-number v-model="state.ruleForm.Data.OrderBy" :min="0" :max="65535" style="width:13rem" />
</el-form-item>
<el-form-item :label="$t('firewall.disabled')" prop="Disabled">
<div class="flex">
<el-switch v-model="state.ruleForm.Data.Disabled"
active-text="😀" inactive-text="😣" inline-prompt />
</div>
</el-form-item>
<el-form-item :label="$t('firewall.remark')" prop="Remark">
<el-input v-model="state.ruleForm.Data.Remark" />
</el-form-item>
<el-form-item label="" prop="Btns">
<div class="t-c w-100">
<el-button @click="state.show = false">{{$t('common.cancel')}}</el-button>
<el-button type="primary" @click="handleSave">{{$t('common.confirm')}}</el-button>
</div>
</el-form-item>
</el-form>
</div>
</el-dialog>
</template>
<script>
import { ElMessage } from 'element-plus';
import { inject, reactive, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n';
import { addFirewall } from '@/apis/firewall';
import { getSignInIds } from '@/apis/signin';
export default {
props: ['modelValue'],
emits: ['update:modelValue','success'],
setup(props,{emit}) {
const {t} = useI18n();
const add = inject('add');
const state = reactive({
show:true,
loading:false,
machineIds:{
Request: {
Page: 1, Size:10, Name: ''
},
Count: 0,
List: []
},
protocolChecks:[
(add.value.Data.Protocol & 1) ,
(add.value.Data.Protocol & 2)
].filter(c=>c > 0),
ruleForm:{
MachineId:add.value.MachineId,
Data:{
Id:add.value.Data.Id,
GroupId:add.value.Data.GroupId,
SrcName:add.value.Data.SrcName,
Disabled:add.value.Data.Disabled,
OrderBy:add.value.Data.OrderBy,
SrcId:add.value.Data.SrcId,
DstCIDR:add.value.Data.DstCIDR,
DstPort:add.value.Data.DstPort,
Protocol:add.value.Data.Protocol,
Action:add.value.Data.Action,
Remark:add.value.Data.Remark,
}
},
rules:{
SrcId: [{ required: true, message: "required", trigger: "blur" }],
DstCIDR: [{ required: true, message: "required", trigger: "blur" }],
DstPort: [{ required: true, message: "required", trigger: "blur" }]
},
protocols: [
{label:'TCP',value:1},
{label:'UDP',value:2}
],
actions: [
{label:t('firewall.actionAllow'),value:1},
{label:t('firewall.actionDeny'),value:2},
],
});
watch(() => state.show, (val) => {
if (!val) {
setTimeout(() => {
emit('update:modelValue', val);
}, 300);
}
});
const ruleFormRef = ref(null);
const handleSave = ()=>{
ruleFormRef.value.validate((valid) => {
if (!valid) return;
const json = JSON.parse(JSON.stringify(state.ruleForm));
json.Data.Protocol = state.protocolChecks.reduce((a,b)=>a|b,0);
addFirewall(json).then(()=>{
ElMessage.success(t('common.oper'));
state.show = false;
emit('success');
}).catch(()=>{
ElMessage.error(t('common.operFail'));
});
});
}
const handleMachineChange = () => {
const machine = state.machineIds.List.find(c=>c.MachineId == state.ruleForm.Data.SrcId);
if(machine){
state.ruleForm.Data.SrcName = machine.MachineName;
}
}
const handleMachinePageChange = (page)=>{
state.machineIds.Request.Page = page;
_getMachineIds();
}
const handleMachineSearch = (name)=>{
state.machineIds.Request.Name = name;
_getMachineIds();
}
const _getMachineIds = ()=>{
state.loading = true;
getSignInIds(state.machineIds.Request).then((res)=>{
state.loading = false;
state.machineIds.Request = res.Request;
state.machineIds.Count = res.Count;
res.List.splice(0,0,{MachineId:'*',MachineName:'*'});
if(state.ruleForm.Data.SrcId){
if(res.List.filter(c=>c.MachineId == state.ruleForm.Data.SrcId).length == 0){
res.List.splice(1,0,{MachineId:state.ruleForm.Data.SrcId,MachineName:state.ruleForm.Data.SrcName});
}
}
state.machineIds.List = res.List;
}).catch((e)=>{
state.loading = false;
});
}
return {state,ruleFormRef,handleSave,handleMachineSearch,handleMachinePageChange,handleMachineChange}
}
}
</script>
<style lang="stylus" scoped>
.el-form-item{margin-bottom:1rem}
.el-input-number--small{width:10rem !important}
</style>

View File

@@ -0,0 +1,261 @@
<template>
<div class="firewall-setting-wrap flex flex-column h-100">
<div class="inner">
<div class="head">
<div class="flex">
<div>
<el-select v-model="state.search.Data.Action" @change="loadData" size="small" class="mgr-1" style="width: 9rem;">
<el-option :value="item.value" :label="item.label" v-for="(item,index) in state.actions"></el-option>
</el-select>
</div>
<div>
<el-select v-model="state.search.Data.Protocol" @change="loadData" size="small" class="mgr-1" style="width: 9rem;">
<el-option :value="item.value" :label="item.label" v-for="(item,index) in state.protocols"></el-option>
</el-select>
</div>
<div>
<el-select v-model="state.search.Data.Disabled" @change="loadData" size="small" class="mgr-1" style="width: 9rem;">
<el-option :value="item.value" :label="item.label" v-for="(item,index) in state.states"></el-option>
</el-select>
</div>
<div>
<span>{{$t('firewall.srcName')}}/{{$t('firewall.dstCidr')}}/{{$t('firewall.dstPort')}}/{{$t('firewall.remark')}}</span>
<el-input v-model="state.search.Data.Str" @change="loadData" size="small" style="width:7rem"></el-input>
</div>
<div class="mgl-1">
<el-button size="small" :loading="state.loading" @click="loadData">{{$t('common.refresh')}}</el-button>
</div>
<div class="mgl-1">
<el-button type="success" size="small" :loading="state.loading" @click="handleAdd()">+</el-button>
</div>
<div class="flex-1"></div>
</div>
</div>
<div class="body flex-1 relative">
<el-table stripe border :data="state.data" size="small" :height="`${state.height}px`" width="100%" :row-class-name="tableRowClassName">
<el-table-column prop="SrcName" :label="$t('firewall.srcName')" >
<template v-slot="scope">
<div class="ellipsis" :title="scope.row.SrcName">{{ scope.row.SrcName }}</div>
</template>
</el-table-column>
<el-table-column prop="DstCIDR" :label="$t('firewall.dstCidr')" width="130"></el-table-column>
<el-table-column prop="DstPort" :label="$t('firewall.dstPort')"></el-table-column>
<el-table-column prop="Protocol" :label="$t('firewall.protocol')" width="70">
<template v-slot="scope">{{handleShowProtocol(scope.row.Protocol)}}</template>
</el-table-column>
<el-table-column prop="Action" :label="$t('firewall.action')" width="50">
<template v-slot="scope">{{handleShowAction(scope.row.Action)}}</template>
</el-table-column>
<el-table-column prop="OrderBy" :label="$t('firewall.orderby')" width="60"></el-table-column>
<el-table-column prop="Disabled" :label="$t('firewall.disabled')" width="70">
<template v-slot="scope">
<div>
<el-switch v-model="scope.row.Disabled" size="small"
active-text="😀" inactive-text="😣" inline-prompt @change="handleDsiabled(scope.row)"
style="--el-switch-on-color: red;" />
</div>
</template>
</el-table-column>
<el-table-column prop="Remark" :label="$t('firewall.remark')" >
<template v-slot="scope">
<div class="ellipsis" :title="scope.row.Remark">{{ scope.row.Remark }}</div>
</template>
</el-table-column>
<el-table-column width="80" fixed="right">
<template #header>
<div class="flex">
<el-switch v-model="state.state" size="small" :title="$t('firewall.switch')"
:active-value="0" :inactive-value="1"
active-text="😀" inactive-text="😣" inline-prompt @change="handleSetState" />
</div>
</template>
<template #default="scope">
<div>
<a href="javascript:void(0);" class="a-line mgr-1" @click="handleAdd(scope.row)">{{$t('firewall.edit')}}</a>
<el-popconfirm
:confirm-button-text="$t('common.confirm')" :cancel-button-text="$t('common.cancel')"
:title="$t('firewall.delConfirm')" @confirm="handleDel(scope.row)">
<template #reference>
<a href="javascript:void(0);" class="a-line">{{$t('firewall.del')}}</a>
</template>
</el-popconfirm>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<Add v-if="state.showAdd" v-model="state.showAdd" @success="loadData"></Add>
</template>
<script>
import { reactive,computed, ref } from '@vue/reactivity'
import { onMounted, provide } from '@vue/runtime-core'
import { injectGlobalData } from '@/provide'
import { addFirewall, getFirewall, removeFirewall, stateFirewall } from '@/apis/firewall';
import { useI18n } from 'vue-i18n';
import { ElMessage } from 'element-plus';
import Add from './Add.vue';
export default {
props: ['machineId','machineName'],
components:{Add},
setup(props,{emit}) {
const {t} = useI18n();
const globalData = injectGlobalData();
const state = reactive({
loading: true,
search:{
MachineId:props.machineId || globalData.value.config.Client.Id,
Data:{
Str:'',
Disabled:-1,
Protocol: 3,
Action:3,
}
},
protocols: [
{label:t('firewall.protocolall'),value:3},
{label:'TCP',value:1},
{label:'UDP',value:2}
],
actions: [
{label:t('firewall.actionall'),value:3},
{label:t('firewall.actionAllow'),value:1},
{label:t('firewall.actionDeny'),value:2},
],
states: [
{label:t('firewall.disabledAll'),value:-1},
{label:t('firewall.enabled'),value:0},
{label:t('firewall.disabled'),value:1},
],
data:[],
state:1,
height:computed(()=>globalData.value.height - 120),
showAdd:false
})
const loadData = () => {
state.loading = true;
getFirewall(state.search).then((res) => {
state.loading = false;
state.data = res.List;
state.state = res.State;
}).catch((err) => {
console.log(err);
state.loading = false;
});
}
const handleSetState = ()=>{
state.loading = true;
stateFirewall({
MachineId:state.search.MachineId,
State:state.state
}).then(()=>{
state.loading = false;
ElMessage.success(t('common.oper'));
}).catch((err)=>{
state.loading = false;
console.log(err);
ElMessage.error(t('common.operFail'));
});
}
const handleDel = (row) => {
state.loading = true;
removeFirewall({
MachineId:state.search.MachineId,
Id:row.Id
}).then(()=>{loadData(); state.loading = false;}).catch(()=>{state.loading = false;});
}
const handleDsiabled = (row)=>{
state.loading = true;
addFirewall({
MachineId:state.search.MachineId,
Data:row,
}).then(()=>{loadData(); state.loading = false;}).catch(()=>{state.loading = false;});
}
const addState = ref({});
provide('add',addState);
const handleAdd = (row)=>{
addState.value = {
MachineId:state.search.MachineId,
Data: row || {
Id:'',
GroupId:globalData.value.config.Client.Group.Id,
SrcName:'',
Disabled:false,
OrderBy:0,
SrcId:'',
DstCIDR:'0.0.0.0/0',
DstPort:'0',
Protocol:3,
Action:1,
Remark:t('firewall.actionAllowAll')
}
};
state.showAdd = true;
}
const protocolArr = ['','TCP','UDP'];
const handleShowProtocol = (protocol)=>{
return [
protocolArr[(protocol & 1)] ,
protocolArr[(protocol & 2)]
].filter(c=>!!c).join('/');
}
const actionArr = ['','✔','✘'];
const handleShowAction = (action)=>{
return actionArr[action];
}
const tableRowClassName = ({ row, rowIndex }) => {
return `action-${row.Action}`;
}
onMounted(()=>{
loadData();
});
return {
state, loadData, tableRowClassName,handleSetState,handleAdd,handleDel,
handleShowProtocol,handleShowAction,handleDsiabled
}
}
}
</script>
<style lang="stylus" scoped>
.firewall-setting-wrap {
padding: 1rem;
box-sizing: border-box;
font-size:1.3rem
.inner {
padding: 1rem;
}
.head {
margin-bottom: 1rem;
color:#555;
border:1px solid #eee;
padding: 1rem;
}
}
</style>
<style lang="stylus">
.firewall-setting-wrap {
.el-table {
.action-1 {
color: green;
}
.action-2 {
color: #c83f08;
}
}
}
</style>

View File

@@ -2,7 +2,7 @@
<el-form-item :label="$t('server.relaySecretKey')">
<div >
<div class="flex">
<el-input class="flex-1" type="password" show-password v-model="state.list.SecretKey" maxlength="36" @change="handleSave" />
<el-input :class="{success:state.keyState,error:state.keyState==false}" class="flex-1" type="password" show-password v-model="state.list.SecretKey" maxlength="36" @change="handleSave" />
<Sync class="mgl-1" name="RelaySecretKey"></Sync>
</div>
<div class="flex">
@@ -79,7 +79,7 @@
<EditNode v-if="state.showEdit" v-model="state.showEdit" :data="state.current"></EditNode>
</template>
<script>
import { relayCdkeyAccess, setRelayServers, setRelaySubscribe } from '@/apis/relay';
import { checkRelayKey, relayCdkeyAccess, setRelayServers, setRelaySubscribe } from '@/apis/relay';
import { injectGlobalData } from '@/provide';
import { ElMessage } from 'element-plus';
import { onMounted, onUnmounted, reactive, watch } from 'vue'
@@ -100,7 +100,8 @@ export default {
timer:0,
showEdit:false,
current:{},
hasRelayCdkey:false
hasRelayCdkey:false,
keyState:false,
});
watch(()=>globalData.value.config.Client.Relay.Server,()=>{
state.list.Delay = globalData.value.config.Client.Relay.Server.Delay;
@@ -117,7 +118,8 @@ export default {
}).catch((err)=>{
console.log(err);
ElMessage.error(t('common.operFail'));
});;
});
handleCheckKey();
}
const _setRelaySubscribe = ()=>{
clearTimeout(state.timer);
@@ -128,15 +130,22 @@ export default {
state.timer = setTimeout(_setRelaySubscribe,1000);
});
}
const handleCheckKey = ()=>{
checkRelayKey(state.list.SecretKey).then((res)=>{
state.keyState = res;
}).catch(()=>{});
}
onMounted(()=>{
_setRelaySubscribe();
relayCdkeyAccess().then(res=>{
state.hasRelayCdkey = res;
}).catch(()=>{})
}).catch(()=>{});
handleCheckKey();
});
onUnmounted(()=>{
clearTimeout(state.timer);
})
});
return {globalData,state,handleSave,handleEdit}
}

View File

@@ -1,7 +1,7 @@
<template>
<el-form-item :label="$t('server.sforwardSecretKey')">
<div class="flex">
<el-input class="flex-1" type="password" show-password v-model="state.SForwardSecretKey" maxlength="36" @blur="handleChange" />
<el-input :class="{success:state.keyState,error:state.keyState==false}" class="flex-1" type="password" show-password v-model="state.SForwardSecretKey" maxlength="36" @blur="handleChange" />
<Sync class="mgl-1" name="SForwardSecretKey"></Sync>
<span class="mgl-1" v-if="globalData.isPc">{{$t('server.sforwardText')}}</span>
</div>
@@ -9,7 +9,7 @@
</el-form-item>
</template>
<script>
import { getSForwardSecretKey,setSForwardSecretKey } from '@/apis/sforward';
import { checkSForwardKey, getSForwardSecretKey,setSForwardSecretKey } from '@/apis/sforward';
import { ElMessage } from 'element-plus';
import {onMounted, reactive } from 'vue'
import { useI18n } from 'vue-i18n';
@@ -21,12 +21,14 @@ export default {
const {t} = useI18n();
const globalData = injectGlobalData();
const state = reactive({
SForwardSecretKey:''
SForwardSecretKey:'',
keyState:false
});
const _getSForwardSecretKey = ()=>{
getSForwardSecretKey().then((res)=>{
state.SForwardSecretKey = res;
handleCheckKey();
});
}
@@ -41,12 +43,19 @@ export default {
}
const handleChange = ()=>{
_setSForwardSecretKey();
handleCheckKey();
}
const handleCheckKey = ()=>{
checkSForwardKey(state.SForwardSecretKey).then((res)=>{
state.keyState = res;
});
}
onMounted(()=>{
_getSForwardSecretKey();
});
return {globalData,state,handleChange}
}
}

Some files were not shown because too many files have changed in this diff Show More