一些常规优化

This commit is contained in:
snltty
2024-11-29 00:49:22 +08:00
parent 75e66acebb
commit fb7e2d4f4e
34 changed files with 322 additions and 235 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.5.9 snltty/linker-musl:amd64 snltty/linker-musl:arm64 snltty/linker-musl:arm && \
docker manifest create snltty/linker-musl:v1.6.0 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.5.9 && \
docker manifest push snltty/linker-musl:v1.6.0 && \
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.5.9 snltty/linker-debian:amd64 snltty/linker-debian:arm64 snltty/linker-debian:arm && \
docker manifest create snltty/linker-debian:v1.6.0 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.5.9
docker manifest push snltty/linker-debian:v1.6.0

View File

@@ -33,11 +33,11 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.ACTIONS_TOKEN }}
with:
tag_name: v1.5.9
release_name: v1.5.9.${{ steps.date.outputs.today }}
tag_name: v1.6.0
release_name: v1.6.0.${{ steps.date.outputs.today }}
draft: false
prerelease: false
body: "1. 优化UI\r\n2. 优化网卡\r\n3. 修复网卡禁用自动重启\r\n4. 增加一键安装脚本"
body: "1. 优化websocket(某些代理环境下可能请求头key名称不规范)\r\n2. 尝试解决UDP获取外网IP端口失败的问题\r\n3. 测试中"
- name: upload-win-x86-oss
id: upload-win-x86-oss
uses: tvrcgo/oss-action@v0.1.1
@@ -47,7 +47,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-x86.zip
target-path: /downloads/linker/v1.5.9/linker-win-x86.zip
target-path: /downloads/linker/v1.6.0/linker-win-x86.zip
- name: upload-win-x86
id: upload-win-x86
uses: actions/upload-release-asset@master
@@ -67,7 +67,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-x64.zip
target-path: /downloads/linker/v1.5.9/linker-win-x64.zip
target-path: /downloads/linker/v1.6.0/linker-win-x64.zip
- name: upload-win-x64
id: upload-win-x64
uses: actions/upload-release-asset@master
@@ -87,7 +87,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-win-arm64.zip
target-path: /downloads/linker/v1.5.9/linker-win-arm64.zip
target-path: /downloads/linker/v1.6.0/linker-win-arm64.zip
- name: upload-win-arm64
id: upload-win-arm64
uses: actions/upload-release-asset@master
@@ -107,7 +107,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-x64.zip
target-path: /downloads/linker/v1.5.9/linker-linux-x64.zip
target-path: /downloads/linker/v1.6.0/linker-linux-x64.zip
- name: upload-linux-x64
id: upload-linux-x64
uses: actions/upload-release-asset@master
@@ -127,7 +127,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-arm.zip
target-path: /downloads/linker/v1.5.9/linker-linux-arm.zip
target-path: /downloads/linker/v1.6.0/linker-linux-arm.zip
- name: upload-linux-arm
id: upload-linux-arm
uses: actions/upload-release-asset@master
@@ -147,7 +147,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-arm64.zip
target-path: /downloads/linker/v1.5.9/linker-linux-arm64.zip
target-path: /downloads/linker/v1.6.0/linker-linux-arm64.zip
- name: upload-linux-arm64
id: upload-linux-arm64
uses: actions/upload-release-asset@master
@@ -167,7 +167,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-x64.zip
target-path: /downloads/linker/v1.5.9/linker-linux-musl-x64.zip
target-path: /downloads/linker/v1.6.0/linker-linux-musl-x64.zip
- name: upload-linux-musl-x64
id: upload-linux-musl-x64
uses: actions/upload-release-asset@master
@@ -187,7 +187,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-arm.zip
target-path: /downloads/linker/v1.5.9/linker-linux-musl-arm.zip
target-path: /downloads/linker/v1.6.0/linker-linux-musl-arm.zip
- name: upload-linux-musl-arm
id: upload-linux-musl-arm
uses: actions/upload-release-asset@master
@@ -207,7 +207,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-linux-musl-arm64.zip
target-path: /downloads/linker/v1.5.9/linker-linux-musl-arm64.zip
target-path: /downloads/linker/v1.6.0/linker-linux-musl-arm64.zip
- name: upload-linux-musl-arm64
id: upload-linux-musl-arm64
uses: actions/upload-release-asset@master
@@ -227,7 +227,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-osx-x64.zip
target-path: /downloads/linker/v1.5.9/linker-osx-x64.zip
target-path: /downloads/linker/v1.6.0/linker-osx-x64.zip
- name: upload-osx-x64
id: upload-osx-x64
uses: actions/upload-release-asset@master
@@ -247,7 +247,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-osx-arm64.zip
target-path: /downloads/linker/v1.5.9/linker-osx-arm64.zip
target-path: /downloads/linker/v1.6.0/linker-osx-arm64.zip
- name: upload-osx-arm64
id: upload-osx-arm64
uses: actions/upload-release-asset@master
@@ -277,7 +277,7 @@ jobs:
key-secret: ${{ secrets.ALIYUN_OSS_SECRET }}
bucket: ide-qbcode
asset-path: ./public/publish-zip/linker-windows-route.zip
target-path: /downloads/linker/v1.5.9/linker-windows-route.zip
target-path: /downloads/linker/v1.6.0/linker-windows-route.zip
- name: upload-version-oss
id: upload-version-oss
uses: tvrcgo/oss-action@v0.1.1

View File

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

View File

@@ -3,6 +3,10 @@ sidebar_position: 1
---
# 1、首页
:::danger[特别声明]
1. 因为没有签名,又需要较高的权限,所以可能存在报毒的情况,请手动在安全软件中添加白名单
2. 如有疑问,可右上角移步软件源码,公开透明
:::
:::tip[说明]

View File

@@ -15,14 +15,15 @@ sidebar_position: 1
下载安装脚本
```
curl -fsSL https://linker-doc.snltty.com/linker-install.sh -o linker-install.sh
chmod +x linker-install.sh
```
默认安装位置
```
sudo sh linker-install.sh
./linker-install.sh
```
指定安装位置
```
sudo sh linker-install.sh /usr/local/bin
./linker-install.sh /usr/local/bin
```
:::

View File

@@ -17,15 +17,11 @@ plain='\033[0m'
export PATH=$PATH:/usr/local/bin
install_base() {
(command -v git >/dev/null 2>&1 && command -v curl >/dev/null 2>&1 && command -v wget >/dev/null 2>&1 && command -v unzip >/dev/null 2>&1 && command -v getenforce >/dev/null 2>&1) ||
(install_soft curl wget git unzip)
}
install_soft() {
(command -v yum >/dev/null 2>&1 && yum makecache >/dev/null 2>&1 && yum install $* iproute2 dmidecode net-tools curl traceroute iptables ca-certificates -y >/dev/null 2>&1) ||
(command -v apt >/dev/null 2>&1 && apt update >/dev/null 2>&1 && apt install $* iproute2 dmidecode net-tools curl traceroute iptables ca-certificates -y >/dev/null 2>&1) ||
(command -v pacman >/dev/null 2>&1 && pacman -Syu $* base-devel --noconfirm && install_arch) ||
(command -v apt-get >/dev/null 2>&1 && apt-get update >/dev/null 2>&1 && apt-get install $* iproute2 dmidecode net-tools curl traceroute iptables ca-certificates -y >/dev/null 2>&1) ||
(command -v yum >/dev/null 2>&1 && yum makecache >/dev/null 2>&1 && yum install curl wget git unzip iproute dmidecode net-tools curl traceroute iptables ca-certificates -y >/dev/null 2>&1) ||
(command -v apt >/dev/null 2>&1 && apt update >/dev/null 2>&1 && apt install curl wget git unzip iproute2 dmidecode net-tools curl traceroute iptables ca-certificates -y >/dev/null 2>&1) ||
(command -v pacman >/dev/null 2>&1 && pacman -Syu curl wget git unzip base-devel --noconfirm && install_arch) ||
(command -v apt-get >/dev/null 2>&1 && apt-get update >/dev/null 2>&1 && apt-get install curl wget git unzip iproute2 dmidecode net-tools curl traceroute iptables ca-certificates -y >/dev/null 2>&1) ||
(command -v apk >/dev/null 2>&1 && apk update >/dev/null 2>&1 && apk add --no-cache net-tools iproute2 numactl-dev iputils iptables dmidecode -f >/dev/null 2>&1)
}
install_systemd() {
@@ -131,14 +127,20 @@ install_docker() {
os_alpine="0"
[ -e /etc/os-release ] && cat /etc/os-release | grep -i "PRETTY_NAME" | grep -qi "alpine" && os_alpine='1'
command -v docker >/dev/null 2>&1
if [[ $? != 0 ]]; then
echo -e "${yellow}===================================================${plain}\n正在安装 Docker"
if docker --version >/dev/null 2>&1; then
echo -e "${green}已安装docker${plain}"
else
echo -e "${yellow}===================================================${plain}\n正在安装 docker"
if [ "$os_alpine" != 1 ]; then
echo -e "下载docker脚本..."
bash <(curl -sL https://get.docker.com -o get-docker.sh) >/dev/null 2>&1
if [[ $? != 0 ]]; then
echo -e "${red}下载脚本失败,请检查本机能否连接 https://get.docker.com${plain}"
return 0
fi
echo -e "执行docker脚本..."
chmod +x get-docker.sh
./get-docker.sh
systemctl enable docker.service >/dev/null 2>&1
systemctl start docker.service >/dev/null 2>&1
else
@@ -146,7 +148,11 @@ install_docker() {
rc-update add docker
rc-service docker start
fi
echo -e "${green}Docker 安装成功${plain}"
if docker --version >/dev/null 2>&1; then
echo -e "${green}docker 安装成功${plain}"
else
echo -e "${red}docker 安装失败,可以多试几次${plain}" && exit 1
fi
fi
LINKER_IMAGES=$(docker ps | grep -w "linker")
@@ -198,7 +204,7 @@ install_docker() {
select_version() {
if [[ -z $LINKER_IS_DOCKER ]]; then
echo -e "${yellow}===================================================\n${plain}请自行选择您的安装方式:${yellow}\n1. Docker\n2. 独立安装${plain}"
echo -e "${yellow}===================================================\n${plain}请自行选择您的安装方式:${yellow}\n1. docker\n2. 独立安装${plain}"
while true; do
read -e -r -p "请输入选择 [1-2]" option
case "${option}" in
@@ -218,7 +224,7 @@ select_version() {
fi
}
install_base
install_soft
select_version

View File

@@ -4,6 +4,8 @@ using System.Linq;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.Text;
using System.Text;
using System;
using System.Diagnostics;
namespace linker.gen
{
@@ -31,6 +33,8 @@ namespace linker.gen
context.RegisterSourceOutput(compilations, (sourceProductionContext, compilation) =>
{
foreach (GeneratorInfo info in generators)
{
var iFlowSymbol = compilation.GetTypeByMetadataName(info.InterfaceName);

View File

@@ -21,7 +21,7 @@ namespace linker.libs.api
protected readonly Dictionary<string, PluginPathCacheInfo> plugins = new();
protected readonly ConcurrentDictionary<uint, ConnectionTimeInfo> connectionTimes = new();
public uint OnlineNum = 0;
private Memory<byte> password = Helper.EmptyArray;
private string password = string.Empty;
private WebSocketServer server;
@@ -34,7 +34,7 @@ namespace linker.libs.api
/// </summary>
public void Websocket(int port, string password = "")
{
this.password = Encoding.UTF8.GetBytes(password);
this.password = password;
server = new WebSocketServer();
try
{
@@ -46,10 +46,10 @@ namespace linker.libs.api
}
server.OnConnecting = (connection, header) =>
{
bool res = this.password.Length == 0 || this.password.Span.SequenceEqual(header.SecWebSocketProtocol.Span);
bool res = string.IsNullOrWhiteSpace(this.password) || (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketProtocol, out string _password) && _password.Contains(this.password));
if (res)
{
header.SecWebSocketExtensions = Helper.EmptyArray;
header.SetHeaderValue(WebsocketHeaderKey.SecWebSocketExtensions, string.Empty);
}
return res;
};

View File

@@ -1,5 +1,6 @@
using linker.libs.jsonConverters;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Unicode;
namespace linker.libs.extends
@@ -23,15 +24,15 @@ namespace linker.libs.extends
WriteIndented = true,
Converters = { new IPAddressJsonConverter(), new IPEndpointJsonConverter(), new DateTimeConverter() }
};
private static JsonSerializerOptions jsonSerializerOptionsIndented = new JsonSerializerOptions
public static void AddAOT(JsonSerializerContext[] contexts)
{
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(UnicodeRanges.All),
AllowTrailingCommas = true,
ReadCommentHandling = JsonCommentHandling.Skip,
PropertyNameCaseInsensitive = true,
WriteIndented = true,
Converters = { new IPAddressJsonConverter(), new IPEndpointJsonConverter(), new DateTimeConverter() }
};
foreach (var context in contexts)
{
jsonSerializerOptions1.TypeInfoResolverChain.Insert(0, context);
jsonSerializerOptions.TypeInfoResolverChain.Insert(0, context);
}
}
public static string ToJson(this object obj)
{
return JsonSerializer.Serialize(obj, jsonSerializerOptions1);
@@ -45,4 +46,6 @@ namespace linker.libs.extends
return JsonSerializer.Deserialize<T>(json, options: jsonSerializerOptions);
}
}
}

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.5.9</Version>
<AssemblyVersion>1.5.9</AssemblyVersion>
<FileVersion>1.5.9</FileVersion>
<Version>1.6.0</Version>
<AssemblyVersion>1.6.0</AssemblyVersion>
<FileVersion>1.6.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>full</DebugType>

View File

@@ -140,10 +140,9 @@ namespace linker.libs.websocket
{
token.SecWebSocketKey = WebSocketParser.BuildSecWebSocketKey();
byte[] connectData = WebSocketParser.BuildConnectData(new WebsocketHeaderInfo
{
SecWebSocketKey = token.SecWebSocketKey,
});
WebsocketHeaderInfo header = new WebsocketHeaderInfo();
header.SetHeaderValue(WebsocketHeaderKey.SecWebSocketKey, token.SecWebSocketKey);
byte[] connectData = WebSocketParser.BuildConnectData(header);
token.TargetSocket.Send(connectData, SocketFlags.None);
@@ -366,7 +365,7 @@ namespace linker.libs.websocket
private void HandleConnect(AsyncServerUserToken token, Memory<byte> data)
{
WebsocketHeaderInfo header = WebsocketHeaderInfo.Parse(data);
if (!WebSocketParser.VerifySecWebSocketAccept(token.SecWebSocketKey, header.SecWebSocketAccept))
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketAccept, out string accept) == false || WebSocketParser.VerifySecWebSocketAccept(token.SecWebSocketKey, accept) == false)
{
OnConnectFail("Sec-WebSocket-Accept Invalid");
CloseClientSocket();
@@ -471,7 +470,7 @@ namespace linker.libs.websocket
/// 当前帧的数据类型
/// </summary>
public WebSocketFrameInfo.EnumOpcode Opcode { get; set; }
public Memory<byte> SecWebSocketKey { get; set; }
public string SecWebSocketKey { get; set; }
public byte[] PoolBuffer { get; set; }
public void Clear()

View File

@@ -1,6 +1,7 @@
using System;
using System.Buffers;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Net;
using System.Security.Cryptography;
using System.Text;
@@ -13,7 +14,7 @@ namespace linker.libs.websocket
public static class WebSocketParser
{
private readonly static SHA1 sha1 = SHA1.Create();
private readonly static Memory<byte> magicCode = Encoding.ASCII.GetBytes("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
private readonly static Memory<byte> magicCode = Encoding.UTF8.GetBytes("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
/// <summary>
/// 构建连接数据
/// </summary>
@@ -21,21 +22,23 @@ namespace linker.libs.websocket
/// <returns></returns>
public static byte[] BuildConnectData(WebsocketHeaderInfo header)
{
string path = header.Path.Length == 0 ? "/" : Encoding.UTF8.GetString(header.Path.Span);
string path = header.Path.Length == 0 ? "/" : header.Path;
header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketKey,out string key);
StringBuilder sb = new StringBuilder(10);
sb.Append($"GET {path} HTTP/1.1\r\n");
sb.Append($"Upgrade: websocket\r\n");
sb.Append($"Connection: Upgrade\r\n");
sb.Append($"Sec-WebSocket-Version: 13\r\n");
sb.Append($"Sec-WebSocket-Key: {Encoding.UTF8.GetString(header.SecWebSocketKey.Span)}\r\n");
if (header.SecWebSocketProtocol.Length > 0)
sb.Append($"Sec-WebSocket-Key: {key}\r\n");
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketProtocol, out string protocol))
{
sb.Append($"Sec-WebSocket-Protocol: {Encoding.UTF8.GetString(header.SecWebSocketProtocol.Span)}\r\n");
sb.Append($"Sec-WebSocket-Protocol: {protocol}\r\n");
}
if (header.SecWebSocketExtensions.Length > 0)
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketExtensions, out string extensions))
{
sb.Append($"Sec-WebSocket-Extensions: {Encoding.UTF8.GetString(header.SecWebSocketExtensions.Span)}\r\n");
sb.Append($"Sec-WebSocket-Extensions: {extensions}\r\n");
}
sb.Append("\r\n");
@@ -48,30 +51,31 @@ namespace linker.libs.websocket
/// <returns></returns>
public static byte[] BuildConnectResponseData(WebsocketHeaderInfo header)
{
string acceptStr = BuildSecWebSocketAccept(header.SecWebSocketKey);
header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketKey,out string key);
string acceptStr = BuildSecWebSocketAccept(key);
StringBuilder sb = new StringBuilder(10);
sb.Append($"HTTP/1.1 {(int)header.StatusCode} {AddSpace(header.StatusCode)}\r\n");
sb.Append($"Sec-WebSocket-Accept: {acceptStr}\r\n");
if (header.Connection.Length > 0)
if (header.TryGetHeaderValue(WebsocketHeaderKey.Connection, out string str1))
{
sb.Append($"Connection: {Encoding.UTF8.GetString(header.Connection.Span)}\r\n");
sb.Append($"Connection: {str1}\r\n");
}
if (header.Upgrade.Length > 0)
if (header.TryGetHeaderValue(WebsocketHeaderKey.Upgrade, out str1))
{
sb.Append($"Upgrade: {Encoding.UTF8.GetString(header.Upgrade.Span)}\r\n");
sb.Append($"Upgrade: {str1}\r\n");
}
if (header.SecWebSocketVersion.Length > 0)
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketVersion, out str1))
{
sb.Append($"Sec-WebSocket-Version: {Encoding.UTF8.GetString(header.SecWebSocketVersion.Span)}\r\n");
sb.Append($"Sec-Websocket-Version: {str1}\r\n");
}
if (header.SecWebSocketProtocol.Length > 0)
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketProtocol, out str1))
{
sb.Append($"Sec-WebSocket-Protocol: {Encoding.UTF8.GetString(header.SecWebSocketProtocol.Span)}\r\n");
sb.Append($"Sec-WebSocket-Protocol: {str1}\r\n");
}
if (header.SecWebSocketExtensions.Length > 0)
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketExtensions, out str1))
{
sb.Append($"Sec-WebSocket-Extensions: {Encoding.UTF8.GetString(header.SecWebSocketExtensions.Span)}\r\n");
sb.Append($"Sec-WebSocket-Extensions: {str1}\r\n");
}
sb.Append("\r\n");
@@ -81,7 +85,7 @@ namespace linker.libs.websocket
/// 生成随机key
/// </summary>
/// <returns></returns>
public static byte[] BuildSecWebSocketKey()
public static string BuildSecWebSocketKey()
{
byte[] bytes = new byte[16];
Random random = new Random(DateTime.Now.Ticks.GetHashCode());
@@ -89,8 +93,7 @@ namespace linker.libs.websocket
{
bytes[i] = (byte)random.Next(0, 255);
}
byte[] res = Encoding.UTF8.GetBytes(Convert.ToBase64String(bytes));
return res;
return Convert.ToBase64String(bytes);
}
/// <summary>
/// 构建mask数据
@@ -113,12 +116,12 @@ namespace linker.libs.websocket
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private static string BuildSecWebSocketAccept(Memory<byte> key)
private static string BuildSecWebSocketAccept(string key)
{
int keyLength = key.Length + magicCode.Length;
byte[] acceptBytes = new byte[keyLength];
key.CopyTo(acceptBytes);
Encoding.UTF8.GetBytes(key).AsMemory().CopyTo(acceptBytes);
magicCode.CopyTo(acceptBytes.AsMemory(key.Length));
string acceptStr = Convert.ToBase64String(sha1.ComputeHash(acceptBytes, 0, keyLength));
@@ -131,10 +134,10 @@ namespace linker.libs.websocket
/// <param name="key"></param>
/// <param name="accept"></param>
/// <returns></returns>
public static bool VerifySecWebSocketAccept(Memory<byte> key, Memory<byte> accept)
public static bool VerifySecWebSocketAccept(string key, string accept)
{
string acceptStr = BuildSecWebSocketAccept(key);
return acceptStr == Encoding.UTF8.GetString(accept.Span);
return acceptStr == accept;
}
/// <summary>
@@ -536,113 +539,108 @@ namespace linker.libs.websocket
/// </summary>
public sealed class WebsocketHeaderInfo
{
static byte[][] bytes = new byte[][] {
Encoding.ASCII.GetBytes("Connection: "),
Encoding.ASCII.GetBytes("Upgrade: "),
Encoding.ASCII.GetBytes("Origin: "),
Encoding.ASCII.GetBytes("Sec-WebSocket-Version: "),
Encoding.ASCII.GetBytes("Sec-WebSocket-Key: "),
Encoding.ASCII.GetBytes("Sec-WebSocket-Extensions: "),
Encoding.ASCII.GetBytes("Sec-WebSocket-Protocol: "),
Encoding.ASCII.GetBytes("Sec-WebSocket-Accept: ")
};
static byte[] httpBytes = Encoding.UTF8.GetBytes("HTTP/");
static byte[] endBytes = Encoding.UTF8.GetBytes("\r\n");
static byte[] splitBytes = Encoding.UTF8.GetBytes(": ");
/// <summary>
/// 状态码
/// </summary>
public HttpStatusCode StatusCode { get; set; } = HttpStatusCode.SwitchingProtocols;
public Memory<byte> Method { get; private set; }
/// <summary>
/// 方法
/// </summary>
public string Method { get; private set; }
/// <summary>
/// 路径
/// </summary>
public string Path { get; set; }
/// <summary>
/// 请求头
/// </summary>
public Dictionary<string, string> Headers { get; private set; } = new Dictionary<string, string>();
private string _pathSet { get; set; }
/// <summary>
/// 用这个设置path值
/// 获取请求头
/// </summary>
public string PathSet
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool TryGetHeaderValue(string key, out string value)
{
get
{
return _pathSet;
}
set
{
_pathSet = value;
Path = Encoding.UTF8.GetBytes(_pathSet);
}
return Headers.TryGetValue(key, out value) && string.IsNullOrWhiteSpace(value) == false;
}
/// <summary>
/// 如果 仅1个字符那就是 /
/// 设置请求头
/// </summary>
public Memory<byte> Path { get; private set; }
public Memory<byte> Connection { get; private set; }
public Memory<byte> Upgrade { get; private set; }
public Memory<byte> Origin { get; private set; }
public Memory<byte> SecWebSocketVersion { get; private set; }
public Memory<byte> SecWebSocketKey { get; set; }
public Memory<byte> SecWebSocketExtensions { get; set; }
public Memory<byte> SecWebSocketProtocol { get; set; }
public Memory<byte> SecWebSocketAccept { get; set; }
/// <param name="key"></param>
/// <param name="value"></param>
public void SetHeaderValue(string key, string value)
{
Headers[key] = value;
}
/// <summary>
/// 解析websocket请求头
/// </summary>
/// <param name="header"></param>
/// <returns></returns>
public static WebsocketHeaderInfo Parse(Memory<byte> header)
{
Span<byte> span = header.Span;
int flag = 0xff;
int bit = 0x01;
ulong[] res = new ulong[bytes.Length];
Span<byte> temp = span;
WebsocketHeaderInfo headerInfo = new WebsocketHeaderInfo();
for (int i = 0, len = span.Length; i < len; i++)
//跳过头
temp = temp.Slice(temp.IndexOf(endBytes) + 2);
int splitIndex = 0;
//还有分割线
while ((splitIndex = temp.IndexOf(splitBytes)) >= 0)
{
if (span[i] == 13 && span[i + 1] == 10 && span[i + 2] == 13 && span[i + 3] == 10)
{
break;
}
if (span[i] == 13 && span[i + 1] == 10)
{
int startIndex = i + 2;
for (int k = 0; k < bytes.Length; k++)
{
if ((flag >> k & 1) == 1 && span[startIndex] == bytes[k][0])
{
if (span.Slice(startIndex, bytes[k].Length).SequenceEqual(bytes[k]))
{
int index = span.Slice(startIndex).IndexOf((byte)13);
flag &= ~(bit << k);
//取到key
string key = Encoding.UTF8.GetString(temp.Slice(0, splitIndex)).ToLowerInvariant();
//跳过key
temp = temp.Slice(splitIndex + 2);
#pragma warning disable CS0675 // 对进行了带符号扩展的操作数使用了按位或运算符
res[k] = (ulong)(startIndex + bytes[k].Length) << 32 | (ulong)(index - bytes[k].Length);
#pragma warning restore CS0675 // 对进行了带符号扩展的操作数使用了按位或运算符
//取到value
int endIndex = temp.IndexOf(endBytes);
string value = Encoding.UTF8.GetString(temp.Slice(0, endIndex));
//跳过value
temp = temp.Slice(endIndex + 2);
i += index + 1;
break;
headerInfo.Headers[key] = value;
}
}
}
}
}
WebsocketHeaderInfo headerInfo = new WebsocketHeaderInfo
{
Connection = header.Slice((int)(res[0] >> 32), (int)(res[0] & 0xffffffff)),
Upgrade = header.Slice((int)(res[1] >> 32), (int)(res[1] & 0xffffffff)),
Origin = header.Slice((int)(res[2] >> 32), (int)(res[2] & 0xffffffff)),
SecWebSocketVersion = header.Slice((int)(res[3] >> 32), (int)(res[3] & 0xffffffff)),
SecWebSocketKey = header.Slice((int)(res[4] >> 32), (int)(res[4] & 0xffffffff)),
SecWebSocketExtensions = header.Slice((int)(res[5] >> 32), (int)(res[5] & 0xffffffff)),
SecWebSocketProtocol = header.Slice((int)(res[6] >> 32), (int)(res[6] & 0xffffffff)),
SecWebSocketAccept = header.Slice((int)(res[7] >> 32), (int)(res[7] & 0xffffffff)),
};
int pathIndex = span.IndexOf((byte)32);
int pathIndex1 = span.Slice(pathIndex + 1).IndexOf((byte)32);
//响应的,获取状态码
if (header.Slice(0, httpBytes.Length).Span.SequenceEqual(httpBytes))
{
int code = int.Parse(Encoding.UTF8.GetString(header.Slice(pathIndex + 1, pathIndex1).Span));
headerInfo.StatusCode = (HttpStatusCode)code;
}
//请求的,获取路径和方法
else
{
headerInfo.Path = header.Slice(pathIndex + 1, pathIndex1);
headerInfo.Method = header.Slice(0, pathIndex);
headerInfo.Path = Encoding.UTF8.GetString(span.Slice(pathIndex + 1, pathIndex1));
headerInfo.Method = Encoding.UTF8.GetString(span.Slice(0, pathIndex));
}
return headerInfo;
}
}
public sealed class WebsocketHeaderKey
{
public static string Connection = "connection";
public static string Upgrade = "upgrade";
public static string Origin = "origin";
public static string SecWebSocketVersion = "sec-websocket-version";
public static string SecWebSocketKey = "sec-websocket-key";
public static string SecWebSocketExtensions = "sec-websocket-extensions";
public static string SecWebSocketProtocol = "sec-websocket-protocol";
public static string SecWebSocketAccept = "sec-websocket-accept";
}
}

View File

@@ -25,7 +25,7 @@ namespace linker.libs.websocket
/// </summary>
public Func<WebsocketConnection, WebsocketHeaderInfo, bool> OnConnecting = (connection, header) =>
{
header.SecWebSocketExtensions = Helper.EmptyArray; return true;
header.SetHeaderValue(WebsocketHeaderKey.SecWebSocketExtensions, string.Empty); return true;
};
/// <summary>
/// 已断开连接,没有收到关闭帧
@@ -351,7 +351,7 @@ namespace linker.libs.websocket
private void HandleConnect(AsyncUserToken token, Memory<byte> data)
{
WebsocketHeaderInfo header = WebsocketHeaderInfo.Parse(data);
if (header.SecWebSocketKey.Length == 0)
if (header.TryGetHeaderValue(WebsocketHeaderKey.SecWebSocketKey,out string key) == false)
{
header.StatusCode = HttpStatusCode.MethodNotAllowed;
token.Connectrion.ConnectResponse(header);

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<project ver="10" name="linker.tray.win" libEmbed="true" icon="..\linker\favicon.ico" ui="win" output="linker.tray.win.exe" CompanyName="snltty" FileDescription="linker.tray.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="linker.tray.win" InternalName="linker.install.win" FileVersion="0.0.0.175" ProductVersion="0.0.0.175" publishDir="/dist/" dstrip="false" local="false" ignored="false">
<project ver="10" name="linker.tray.win" libEmbed="true" icon="..\linker\favicon.ico" ui="win" output="linker.tray.win.exe" CompanyName="snltty" FileDescription="linker.tray.win" LegalCopyright="Copyright (C) snltty 2024" ProductName="linker.tray.win" InternalName="linker.install.win" FileVersion="0.0.0.178" ProductVersion="0.0.0.178" publishDir="/dist/" dstrip="false" local="false" ignored="false">
<file name="main.aardio" path="main.aardio" comment="main.aardio"/>
<folder name="资源文件" path="res" embed="true" local="false" ignored="false">
<file name="favicon.ico" path="res\favicon.ico" comment="res\favicon.ico"/>

Binary file not shown.

View File

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

View File

@@ -1,4 +1,6 @@
using System.Net;
using linker.libs.extends;
using System.Net;
using System.Text;
namespace linker.tunnel.wanport
{
@@ -16,6 +18,7 @@ namespace linker.tunnel.wanport
/// <param name="server">服务器</param>
/// <returns></returns>
public Task<TunnelWanPortEndPoint> GetAsync(IPAddress inter, IPEndPoint server);
}
public sealed class TunnelWanPortEndPoint

View File

@@ -3,6 +3,7 @@ using linker.libs.extends;
using System.Buffers;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace linker.tunnel.wanport
{
@@ -23,13 +24,19 @@ namespace linker.tunnel.wanport
udpClient.Client.ReuseBind(new IPEndPoint(localIP, 0));
udpClient.Client.WindowsUdpBug();
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024);
try
{
for (int i = 0; i < 5; i++)
await udpClient.SendAsync(BuildSendData(buffer, 0), server).ConfigureAwait(false);
TimerHelper.Async(async () =>
{
try
for (byte i = 1; i < 10; i++)
{
await udpClient.SendAsync(new byte[1] { 0 }, server).ConfigureAwait(false);
await Task.Delay(15);
await udpClient.SendAsync(BuildSendData(buffer, i), server).ConfigureAwait(false);
}
});
UdpReceiveResult result = await udpClient.ReceiveAsync().WaitAsync(TimeSpan.FromMilliseconds(2000)).ConfigureAwait(false);
if (result.Buffer.Length == 0)
{
@@ -49,11 +56,6 @@ namespace linker.tunnel.wanport
return new TunnelWanPortEndPoint { Local = udpClient.Client.LocalEndPoint as IPEndPoint, Remote = remoteEP };
}
catch (Exception)
{
}
}
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
@@ -61,11 +63,21 @@ namespace linker.tunnel.wanport
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
udpClient.Close();
}
return null;
}
private Memory<byte> BuildSendData(byte[] buffer, byte i)
{
byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Md5().SubStr(0, new Random().Next(16, 32)));
temp.AsMemory().CopyTo(buffer);
buffer[0] = 0;
buffer[1] = i;
return buffer.AsMemory(0, temp.Length);
}
}
@@ -82,13 +94,15 @@ namespace linker.tunnel.wanport
public async Task<TunnelWanPortEndPoint> GetAsync(IPAddress localIP, IPEndPoint server)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(20);
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024);
try
{
Socket socket = new Socket(server.AddressFamily, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
socket.ReuseBind(new IPEndPoint(localIP, 0));
await socket.ConnectAsync(server).ConfigureAwait(false);
await socket.SendAsync(new byte[] { 0 });
await socket.SendAsync(BuildSendData(buffer, (byte)new Random().Next(0, 255)));
int length = await socket.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).ConfigureAwait(false);
for (int j = 0; j < length; j++)
{
@@ -118,5 +132,15 @@ namespace linker.tunnel.wanport
return null;
}
private Memory<byte> BuildSendData(byte[] buffer, byte i)
{
byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Md5().SubStr(0, new Random().Next(16, 32)));
temp.AsMemory().CopyTo(buffer);
buffer[0] = 0;
buffer[1] = i;
return buffer.AsMemory(0, temp.Length);
}
}
}

View File

@@ -4,7 +4,6 @@ using linker.startup;
using linker.config;
using System.ServiceProcess;
using System.Diagnostics;
using linker.libs.extends;
namespace linker
{

View File

@@ -174,6 +174,7 @@ namespace linker.config
}
}
[JsonAotAttribute]
public sealed partial class ConfigCommonInfo : IConfig
{
public ConfigCommonInfo() { }
@@ -223,4 +224,8 @@ namespace linker.config
return text.DeJson<ConfigCommonInfo>();
}
}
[AttributeUsage(AttributeTargets.Class)]
public class JsonAotAttribute : Attribute { }
}

View File

@@ -21,17 +21,16 @@
<Title>linker</Title>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>1. 优化UI
2. 优化网卡
3. 修复网卡禁用自动重启
4. 增加一键安装脚本</Description>
<Description>1. 优化websocket(某些代理环境下可能请求头key名称不规范)
2. 尝试解决UDP获取外网IP端口失败的问题
3. 测试中</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker</PackageReleaseNotes>
<Version>1.5.9</Version>
<AssemblyVersion>1.5.9</AssemblyVersion>
<FileVersion>1.5.9</FileVersion>
<Version>1.6.0</Version>
<AssemblyVersion>1.6.0</AssemblyVersion>
<FileVersion>1.6.0</FileVersion>
</PropertyGroup>
@@ -76,4 +75,7 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.1" />
</ItemGroup>
<ItemGroup>
<Folder Include="plugins\pcp\" />
</ItemGroup>
</Project>

View File

@@ -7,6 +7,7 @@ using linker.plugins.client;
using linker.plugins.tunnel;
using linker.plugins.messenger;
using linker.plugins.relay.client;
using linker.client.config;
namespace linker.plugins.forward.proxy
{
@@ -18,8 +19,8 @@ namespace linker.plugins.forward.proxy
protected override string TransactionId => "forward";
public ForwardProxy(FileConfig config, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState)
: base(config, tunnelTransfer, relayTransfer, clientSignInTransfer, clientSignInState)
public ForwardProxy(FileConfig config, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, RunningConfig runningConfig)
: base(config, tunnelTransfer, relayTransfer, clientSignInTransfer, clientSignInState, runningConfig)
{
TaskUdp();
}

View File

@@ -52,6 +52,8 @@ namespace linker.plugins.relay.client.transport
relayInfo.FlowingId = relayAskResultInfo.FlowingId;
if (relayInfo.FlowingId == 0 || relayAskResultInfo.Nodes.Count == 0)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"relay ask fail,flowid:{relayInfo.FlowingId},nodes:{relayAskResultInfo.Nodes.Count}");
return null;
}
@@ -65,12 +67,16 @@ namespace linker.plugins.relay.client.transport
Socket socket = await ConnectNodeServer(relayInfo, relayAskResultInfo.Nodes);
if (socket == null)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"relay connect server fail,flowid:{relayInfo.FlowingId},nodes:{relayAskResultInfo.Nodes.Count}");
return null;
}
//让对方确认中继
if (await RelayConfirm(relayInfo) == false)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error($"relay confirm fail,flowid:{relayInfo.FlowingId},nodes:{relayAskResultInfo.Nodes.Count}");
return null;
}
@@ -212,9 +218,8 @@ namespace linker.plugins.relay.client.transport
}
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Debug($"connect relay server {ep}");
}
//连接中继服务器
Socket socket = new Socket(ep.AddressFamily, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
socket.KeepAlive();
@@ -232,8 +237,13 @@ namespace linker.plugins.relay.client.transport
await socket.SendAsync(new byte[] { (byte)ResolverType.Relay });
await socket.SendAsync(MemoryPackSerializer.Serialize(relayMessage));
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"relay connected {ep}");
//是否允许连接
int length = await socket.ReceiveAsync(buffer);
int length = await socket.ReceiveAsync(buffer.AsMemory(0, 1));
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay connected {ep}->{buffer[0]}");
if (buffer[0] == 0)
{
relayInfo.Server = node.EndPoint;

View File

@@ -5,6 +5,8 @@ using System.Collections.Concurrent;
using linker.plugins.resolver;
using System.Net;
using MemoryPack;
using linker.config;
using linker.libs;
namespace linker.plugins.relay.server
{
@@ -51,10 +53,12 @@ namespace linker.plugins.relay.server
int length = await socket.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).ConfigureAwait(false);
RelayMessage relayMessage = MemoryPackSerializer.Deserialize<RelayMessage>(buffer.AsMemory(0, length).Span);
if (relayMessage.Type == RelayMessengerType.Ask)
if (relayMessage.Type == RelayMessengerType.Ask && relayMessage.NodeId != RelayNodeInfo.MASTER_NODE_ID)
{
if (relayServerNodeTransfer.Invalid())
if (relayServerNodeTransfer.Validate() == false)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay Validate false,flowid:{relayMessage.FlowId}");
await socket.SendAsync(new byte[] { 1 });
socket.SafeClose();
return;

View File

@@ -75,9 +75,9 @@ namespace linker.plugins.relay.server
/// 无效请求
/// </summary>
/// <returns></returns>
public bool Invalid()
public bool Validate()
{
return ValidateConnection() == false || ValidateBytes() == false;
return ValidateConnection() && ValidateBytes();
}
/// <summary>
@@ -100,7 +100,11 @@ namespace linker.plugins.relay.server
/// <returns></returns>
public bool ValidateConnection()
{
return fileConfig.Data.Server.Relay.Distributed.Node.MaxConnection == 0 || fileConfig.Data.Server.Relay.Distributed.Node.MaxConnection * 2 > connectionNum;
bool res = fileConfig.Data.Server.Relay.Distributed.Node.MaxConnection == 0 || fileConfig.Data.Server.Relay.Distributed.Node.MaxConnection * 2 > connectionNum;
if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay ValidateConnection false,{connectionNum}/{fileConfig.Data.Server.Relay.Distributed.Node.MaxConnection*2}");
return res;
}
/// <summary>
@@ -109,8 +113,13 @@ namespace linker.plugins.relay.server
/// <returns></returns>
public bool ValidateBytes()
{
return fileConfig.Data.Server.Relay.Distributed.Node.MaxGbTotal == 0
bool res= fileConfig.Data.Server.Relay.Distributed.Node.MaxGbTotal == 0
|| (fileConfig.Data.Server.Relay.Distributed.Node.MaxGbTotal > 0 && fileConfig.Data.Server.Relay.Distributed.Node.MaxGbTotalLastBytes > 0);
if (res == false && LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Debug($"relay ValidateBytes false,{fileConfig.Data.Server.Relay.Distributed.Node.MaxGbTotalLastBytes}bytes/{fileConfig.Data.Server.Relay.Distributed.Node.MaxGbTotal}gb");
return res;
}
/// <summary>
/// 添加流量

View File

@@ -13,6 +13,7 @@ using linker.plugins.socks5.config;
using System.Text;
using System.Collections.Generic;
using linker.plugins.relay.client;
using linker.client.config;
namespace linker.plugins.socks5
{
@@ -25,8 +26,8 @@ namespace linker.plugins.socks5
protected override string TransactionId => "socks5";
public TunnelProxy(FileConfig config, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState)
: base(config, tunnelTransfer, relayTransfer, clientSignInTransfer, clientSignInState)
public TunnelProxy(FileConfig config, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, RunningConfig runningConfig)
: base(config, tunnelTransfer, relayTransfer, clientSignInTransfer, clientSignInState, runningConfig)
{
TaskUdp();
}

View File

@@ -3,6 +3,9 @@ using System.Net;
using System.Buffers;
using linker.libs.extends;
using linker.plugins.resolver;
using linker.libs;
using System.Text;
using System;
namespace linker.plugins.tunnel
{
@@ -28,6 +31,8 @@ namespace linker.plugins.tunnel
/// <returns></returns>
public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{ep} get udp external port");
AddReceive((ulong)memory.Length);
byte[] sendData = ArrayPool<byte>.Shared.Rent(20);
try
@@ -36,8 +41,9 @@ namespace linker.plugins.tunnel
AddSendt((ulong)send.Length);
await socket.SendToAsync(send, SocketFlags.None, ep).ConfigureAwait(false);
}
catch (Exception)
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Error(ex);
}
finally
{
@@ -51,15 +57,17 @@ namespace linker.plugins.tunnel
/// <returns></returns>
public async Task Resolve(Socket socket, Memory<byte> memory)
{
byte[] sendData = ArrayPool<byte>.Shared.Rent(20);
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Debug($"{socket.RemoteEndPoint} get tcp external port");
byte[] sendData = ArrayPool<byte>.Shared.Rent(1024);
try
{
memory = BuildSendData(sendData, socket.RemoteEndPoint as IPEndPoint);
AddSendt((ulong)memory.Length);
await socket.SendAsync(memory, SocketFlags.None).ConfigureAwait(false);
}
catch (Exception)
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) LoggerHelper.Instance.Error(ex);
}
finally
{
@@ -78,7 +86,11 @@ namespace linker.plugins.tunnel
{
data[i] = (byte)(data[i] ^ byte.MaxValue);
}
return data.AsMemory(0, 1 + length + 2);
byte[] temp = Encoding.UTF8.GetBytes(Environment.TickCount64.ToString().Md5().SubStr(0, new Random().Next(16, 32)));
temp.AsMemory().CopyTo(data.AsMemory(1 + length + 2));
return data.AsMemory(0, 1 + length + 2 + temp.Length);
}
}

View File

@@ -6,6 +6,7 @@ using linker.tunnel;
using linker.tunnel.connection;
using System.Collections.Concurrent;
using linker.plugins.relay.client;
using linker.client.config;
namespace linker.plugins.tunnel
{
@@ -21,16 +22,18 @@ namespace linker.plugins.tunnel
private readonly RelayTransfer relayTransfer;
private readonly ClientSignInTransfer clientSignInTransfer;
private readonly ClientSignInState clientSignInState;
private readonly RunningConfig runningConfig;
private uint maxTimes = 3;
public TunnelBase(FileConfig config, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState)
public TunnelBase(FileConfig config, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer, ClientSignInState clientSignInState, RunningConfig runningConfig)
{
this.config = config;
this.tunnelTransfer = tunnelTransfer;
this.relayTransfer = relayTransfer;
this.clientSignInTransfer = clientSignInTransfer;
this.clientSignInState = clientSignInState;
this.runningConfig = runningConfig;
//监听打洞成功
tunnelTransfer.SetConnectedCallback(TransactionId, OnConnected);

View File

@@ -4,7 +4,6 @@ using linker.libs;
using linker.plugins.client;
using linker.plugins.decenter;
using linker.plugins.messenger;
using linker.plugins.tunnel.messenger;
using linker.tunnel;
using linker.tunnel.adapter;
using MemoryPack;

View File

@@ -29,6 +29,7 @@ namespace linker.client.config
public int PortMapWan { get; set; }
public int PortMapLan { get; set; }
}
[MemoryPackable]

View File

@@ -32,7 +32,7 @@ namespace linker.plugins.tuntap
private readonly ClientSignInState clientSignInState;
public TuntapProxy(FileConfig config, RunningConfig runningConfig, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, ClientSignInTransfer clientSignInTransfer, LinkerTunDeviceAdapter linkerTunDeviceAdapter, ClientSignInState clientSignInState)
: base(config, tunnelTransfer, relayTransfer, clientSignInTransfer, clientSignInState)
: base(config, tunnelTransfer, relayTransfer, clientSignInTransfer, clientSignInState, runningConfig)
{
this.config = config;
this.runningConfig = runningConfig;

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.5.9" . --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.6.0" . --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.5.9" . --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.6.0" . --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.5.9" . --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.6.0" . --push
cd ../../../../../
done
done

View File

@@ -1,6 +1,5 @@
v1.5.9
2024-11-22 17:23:21
1. 优化UI
2. 优化网卡
3. 修复网卡禁用自动重启
4. 增加一键安装脚本
v1.6.0
2024-11-29 00:49:22
1. 优化websocket(某些代理环境下可能请求头key名称不规范)
2. 尝试解决UDP获取外网IP端口失败的问题
3. 测试中