mirror of
https://github.com/snltty/linker.git
synced 2025-12-18 01:16:46 +08:00
171
This commit is contained in:
2
.github/workflows/dotnet.yml
vendored
2
.github/workflows/dotnet.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
release_name: v1.7.1.${{ steps.date.outputs.today }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
body: "1. 优化数据同步\r\n2. 优化linux网卡,我感觉网卡速度比较正常了\r\n3. 建议更新"
|
||||
body: "1. 优化数据同步\r\n2. 优化linux的tun网卡网卡,读写分离,提高性能\r\n3. 优化windows网卡的禁用自动启用\r\n4. 增加TCP包合并。网卡IP包多个合并一起发送\r\n5. 建议更新"
|
||||
- name: publish projects
|
||||
run: ./publish.bat
|
||||
- name: upload-win-x86-oss
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace linker.app
|
||||
{
|
||||
base.OnCreate();
|
||||
string name = string.IsNullOrWhiteSpace(tuntapConfigTransfer.Info.Name) ? "linker" : tuntapConfigTransfer.Info.Name;
|
||||
adapter.Setup(name, tuntapConfigTransfer.Info.IP, tuntapConfigTransfer.Info.PrefixLength, 1420);
|
||||
tuntapTransfer.Setup(name, tuntapConfigTransfer.Info.IP, tuntapConfigTransfer.Info.PrefixLength);
|
||||
}
|
||||
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
|
||||
{
|
||||
@@ -112,13 +112,6 @@ namespace linker.app
|
||||
|
||||
public async Task Callback(LinkerTunDevicPacket packet)
|
||||
{
|
||||
if (packet.IPV4Broadcast || packet.IPV6Multicast)
|
||||
{
|
||||
if ((tuntapConfigTransfer.Switch & TuntapSwitch.Multicast) == TuntapSwitch.Multicast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
await tuntapProxy.InputPacket(packet).ConfigureAwait(false);
|
||||
}
|
||||
public async ValueTask Close(ITunnelConnection connection)
|
||||
@@ -366,7 +359,7 @@ namespace linker.app
|
||||
}
|
||||
*/
|
||||
}
|
||||
public async Task<bool> CheckAvailable()
|
||||
public async Task<bool> CheckAvailable(bool order = false)
|
||||
{
|
||||
return await Task.FromResult(fd > 0);
|
||||
}
|
||||
|
||||
7
src/linker.doc.web/docs/12、在线讨论咨询.md
Normal file
7
src/linker.doc.web/docs/12、在线讨论咨询.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
# 12、在线讨论咨询
|
||||
|
||||
<a href="https://jq.qq.com/?_wv=1027&k=ucoIVfz4" target="_blank">你可以加入QQ群:1121552990</a>
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
sidebar_position: 12
|
||||
sidebar_position: 13
|
||||
---
|
||||
|
||||
# 12、公益赞助
|
||||
# 13、公益赞助
|
||||
|
||||

|
||||
@@ -18,7 +18,6 @@ using linker.messenger.updater;
|
||||
using linker.messenger.store.file;
|
||||
using linker.messenger.serializer.memorypack;
|
||||
using linker.libs;
|
||||
using System;
|
||||
|
||||
namespace linker.messenger.entry
|
||||
{
|
||||
|
||||
@@ -93,6 +93,7 @@ namespace linker.messenger.store.file
|
||||
|
||||
serviceCollection.AddSingleton<ITuntapClientStore, TuntapClientStore>();
|
||||
serviceCollection.AddSingleton<ILeaseServerStore, LeaseServerStore>();
|
||||
serviceCollection.AddSingleton<ILeaseClientStore, LeaseClientStore>();
|
||||
|
||||
return serviceCollection;
|
||||
}
|
||||
|
||||
@@ -27,18 +27,18 @@ namespace linker.messenger.store.file
|
||||
|
||||
database = new LiteDatabase(new ConnectionString($"Filename={db}; Password={Helper.GlobalString}; journal=false"), bsonMapper);
|
||||
|
||||
CheckpointTask();
|
||||
if (OperatingSystem.IsAndroid() == false)
|
||||
{
|
||||
AppDomain.CurrentDomain.ProcessExit += (s, e) => { database.Checkpoint(); database.Dispose(); };
|
||||
Console.CancelKeyPress += (s, e) => { database.Checkpoint(); database.Dispose(); };
|
||||
}
|
||||
TimerHelper.SetIntervalLong(database.Checkpoint, 3000);
|
||||
}
|
||||
|
||||
public ILiteCollection<T> GetCollection<T>(string name)
|
||||
{
|
||||
return database.GetCollection<T>(name);
|
||||
}
|
||||
|
||||
private void CheckpointTask()
|
||||
{
|
||||
TimerHelper.SetIntervalLong(database.Checkpoint, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using linker.messenger.tuntap;
|
||||
using linker.messenger.tuntap.lease;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace linker.messenger.store.file
|
||||
{
|
||||
@@ -8,5 +10,6 @@ namespace linker.messenger.store.file
|
||||
/// 虚拟网卡配置
|
||||
/// </summary>
|
||||
public TuntapConfigInfo Tuntap { get; set; } = new TuntapConfigInfo();
|
||||
public ConcurrentDictionary<string, LeaseInfo> Leases { get; set; } = new ConcurrentDictionary<string, LeaseInfo>();
|
||||
}
|
||||
}
|
||||
37
src/linker.messenger.store.file/tuntap/LeaseClientStore.cs
Normal file
37
src/linker.messenger.store.file/tuntap/LeaseClientStore.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using linker.messenger.tuntap;
|
||||
using linker.messenger.tuntap.lease;
|
||||
|
||||
namespace linker.messenger.store.file.tuntap
|
||||
{
|
||||
public sealed class LeaseClientStore : ILeaseClientStore
|
||||
{
|
||||
public TuntapConfigInfo Info => runningConfig.Data.Tuntap;
|
||||
|
||||
private readonly RunningConfig runningConfig;
|
||||
public LeaseClientStore(RunningConfig runningConfig)
|
||||
{
|
||||
this.runningConfig = runningConfig;
|
||||
}
|
||||
|
||||
public LeaseInfo Get(string key)
|
||||
{
|
||||
if (runningConfig.Data.Leases.TryGetValue(key, out LeaseInfo info))
|
||||
{
|
||||
return info;
|
||||
}
|
||||
return new LeaseInfo();
|
||||
}
|
||||
|
||||
public bool Set(string key, LeaseInfo info)
|
||||
{
|
||||
runningConfig.Data.Leases.AddOrUpdate(key, info, (a, b) => info);
|
||||
return true;
|
||||
}
|
||||
public void Confirm()
|
||||
{
|
||||
runningConfig.Data.Update();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using linker.libs;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.messenger.tuntap
|
||||
@@ -41,7 +40,18 @@ namespace linker.messenger.tuntap
|
||||
|
||||
public ConcurrentDictionary<string, TuntapGroup2IPInfo> Group2IP { get; set; } = new ConcurrentDictionary<string, TuntapGroup2IPInfo>();
|
||||
|
||||
public bool DisableNat => (Switch & TuntapSwitch.DisableNat) == TuntapSwitch.DisableNat;
|
||||
/// <summary>
|
||||
/// 禁用nat
|
||||
/// </summary>
|
||||
public bool DisableNat => Switch.HasFlag(TuntapSwitch.DisableNat);
|
||||
/// <summary>
|
||||
/// tcp包合并
|
||||
/// </summary>
|
||||
public bool TcpMerge => Switch.HasFlag(TuntapSwitch.TcpMerge);
|
||||
/// <summary>
|
||||
/// 调整网卡顺序
|
||||
/// </summary>
|
||||
public bool InterfaceOrder => Switch.HasFlag(TuntapSwitch.InterfaceOrder);
|
||||
}
|
||||
|
||||
public sealed class TuntapGroup2IPInfo
|
||||
@@ -258,6 +268,48 @@ namespace linker.messenger.tuntap
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// tcp包合并
|
||||
/// </summary>
|
||||
public bool TcpMerge
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Switch & TuntapSwitch.TcpMerge) == TuntapSwitch.TcpMerge;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Switch |= TuntapSwitch.TcpMerge;
|
||||
}
|
||||
else
|
||||
{
|
||||
Switch &= ~TuntapSwitch.TcpMerge;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 调整网卡顺序
|
||||
/// </summary>
|
||||
public bool InterfaceOrder
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Switch & TuntapSwitch.InterfaceOrder) == TuntapSwitch.InterfaceOrder;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
Switch |= TuntapSwitch.InterfaceOrder;
|
||||
}
|
||||
else
|
||||
{
|
||||
Switch &= ~TuntapSwitch.InterfaceOrder;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed partial class TuntapForwardInfo
|
||||
@@ -335,6 +387,14 @@ namespace linker.messenger.tuntap
|
||||
/// 禁用Nat
|
||||
/// </summary>
|
||||
DisableNat = 32,
|
||||
/// <summary>
|
||||
/// 启用小包合并
|
||||
/// </summary>
|
||||
TcpMerge = 64,
|
||||
/// <summary>
|
||||
/// 调整网卡顺序
|
||||
/// </summary>
|
||||
InterfaceOrder = 128,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace linker.messenger.tuntap
|
||||
await RetstartDevice().ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (await tuntapTransfer.CheckAvailable().ConfigureAwait(false) == false)
|
||||
if (await tuntapTransfer.CheckAvailable(tuntapConfigTransfer.Info.InterfaceOrder).ConfigureAwait(false) == false)
|
||||
{
|
||||
tuntapTransfer.Refresh();
|
||||
}
|
||||
@@ -112,13 +112,6 @@ namespace linker.messenger.tuntap
|
||||
|
||||
public async Task Callback(LinkerTunDevicPacket packet)
|
||||
{
|
||||
if (packet.IPV4Broadcast || packet.IPV6Multicast)
|
||||
{
|
||||
if ((tuntapConfigTransfer.Switch & TuntapSwitch.Multicast) == TuntapSwitch.Multicast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
await tuntapProxy.InputPacket(packet).ConfigureAwait(false);
|
||||
}
|
||||
public async ValueTask Close(ITunnelConnection connection)
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace linker.messenger.tuntap
|
||||
if (tuntapTransfer.Status == TuntapStatus.Running && tuntapConfigTransfer.Switch.HasFlag(TuntapSwitch.ShowDelay))
|
||||
{
|
||||
var items = tuntapDecenter.Infos.Values.Where(c => c.IP != null && c.IP.Equals(IPAddress.Any) == false && (c.Status & TuntapStatus.Running) == TuntapStatus.Running);
|
||||
if ((tuntapConfigTransfer.Switch & TuntapSwitch.AutoConnect) != TuntapSwitch.AutoConnect)
|
||||
if (tuntapConfigTransfer.Switch.HasFlag(TuntapSwitch.AutoConnect) == false)
|
||||
{
|
||||
var connections = tuntapProxy.GetConnections();
|
||||
items = items.Where(c => connections.TryGetValue(c.MachineId, out ITunnelConnection connection) && connection.Connected || c.MachineId == signInClientStore.Id);
|
||||
|
||||
@@ -27,16 +27,21 @@ namespace linker.messenger.tuntap
|
||||
private readonly OperatingMultipleManager operatingMultipleManager = new OperatingMultipleManager();
|
||||
protected override string TransactionId => "tuntap";
|
||||
|
||||
|
||||
private readonly TuntapConfigTransfer tuntapConfigTransfer;
|
||||
public TuntapProxy(ISignInClientStore signInClientStore,
|
||||
TunnelTransfer tunnelTransfer, RelayClientTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore)
|
||||
SignInClientTransfer signInClientTransfer, IRelayClientStore relayClientStore, TuntapConfigTransfer tuntapConfigTransfer)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, signInClientTransfer, signInClientStore, relayClientStore)
|
||||
{
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
}
|
||||
|
||||
protected override void Connected(ITunnelConnection connection)
|
||||
{
|
||||
connection.BeginReceive(this, null);
|
||||
if (tuntapConfigTransfer.Info.TcpMerge)
|
||||
connection.StartPacketMerge();
|
||||
//有哪些目标IP用了相同目标隧道,更新一下
|
||||
List<uint> keys = ipConnections.Where(c => c.Value.RemoteMachineId == connection.RemoteMachineId).Select(c => c.Key).ToList();
|
||||
foreach (uint ip in keys)
|
||||
@@ -80,7 +85,7 @@ namespace linker.messenger.tuntap
|
||||
//IPV4广播组播、IPV6 多播
|
||||
if (packet.IPV4Broadcast || packet.IPV6Multicast)
|
||||
{
|
||||
if (connections.IsEmpty == false)
|
||||
if (tuntapConfigTransfer.Switch.HasFlag(TuntapSwitch.Multicast) == false && connections.IsEmpty == false)
|
||||
{
|
||||
await Task.WhenAll(connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Buffer, packet.Offset, packet.Length)));
|
||||
}
|
||||
@@ -119,6 +124,12 @@ namespace linker.messenger.tuntap
|
||||
/// <returns></returns>
|
||||
private async Task<ITunnelConnection> ConnectTunnel(uint ip)
|
||||
{
|
||||
/*
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
Console.WriteLine($"tuntap connect to {NetworkHelper.ToIP(ip)}");
|
||||
}
|
||||
*/
|
||||
if (cidrManager.FindValue(ip, out string machineId))
|
||||
{
|
||||
return await ConnectTunnel(machineId, TunnelProtocolType.Quic).ConfigureAwait(false);
|
||||
|
||||
@@ -181,9 +181,9 @@ namespace linker.messenger.tuntap
|
||||
{
|
||||
linkerTunDeviceAdapter.DelRoute(ips);
|
||||
}
|
||||
public async Task<bool> CheckAvailable()
|
||||
public async Task<bool> CheckAvailable(bool order = false)
|
||||
{
|
||||
return await linkerTunDeviceAdapter.CheckAvailable().ConfigureAwait(false);
|
||||
return await linkerTunDeviceAdapter.CheckAvailable(order).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
src/linker.messenger.tuntap/lease/ILeaseClientStore.cs
Normal file
9
src/linker.messenger.tuntap/lease/ILeaseClientStore.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace linker.messenger.tuntap.lease
|
||||
{
|
||||
public interface ILeaseClientStore
|
||||
{
|
||||
public LeaseInfo Get(string key);
|
||||
public bool Set(string key,LeaseInfo info);
|
||||
public void Confirm();
|
||||
}
|
||||
}
|
||||
@@ -11,16 +11,23 @@ namespace linker.messenger.tuntap.lease
|
||||
private readonly IMessengerSender messengerSender;
|
||||
private readonly SignInClientState signInClientState;
|
||||
private readonly ISerializer serializer;
|
||||
public LeaseClientTreansfer(IMessengerSender messengerSender, SignInClientState signInClientState, ISerializer serializer)
|
||||
private readonly ILeaseClientStore leaseClientStore;
|
||||
private readonly ISignInClientStore signInClientStore;
|
||||
public LeaseClientTreansfer(IMessengerSender messengerSender, SignInClientState signInClientState, ISerializer serializer, ILeaseClientStore leaseClientStore, ISignInClientStore signInClientStore)
|
||||
{
|
||||
this.messengerSender = messengerSender;
|
||||
this.signInClientState = signInClientState;
|
||||
this.serializer = serializer;
|
||||
this.leaseClientStore = leaseClientStore;
|
||||
this.signInClientStore = signInClientStore;
|
||||
LeaseExpTask();
|
||||
|
||||
}
|
||||
|
||||
public async Task AddNetwork(LeaseInfo info)
|
||||
{
|
||||
leaseClientStore.Set(signInClientStore.Group.Id, info);
|
||||
leaseClientStore.Confirm();
|
||||
await messengerSender.SendOnly(new MessageRequestWrap
|
||||
{
|
||||
Connection = signInClientState.Connection,
|
||||
@@ -39,6 +46,8 @@ namespace linker.messenger.tuntap.lease
|
||||
if (resp.Code == MessageResponeCodes.OK)
|
||||
{
|
||||
LeaseInfo info = serializer.Deserialize<LeaseInfo>(resp.Data.Span);
|
||||
leaseClientStore.Set(signInClientStore.Group.Id, info);
|
||||
leaseClientStore.Confirm();
|
||||
return info;
|
||||
}
|
||||
return new LeaseInfo { IP = IPAddress.Any, PrefixLength = 24 };
|
||||
@@ -74,6 +83,25 @@ namespace linker.messenger.tuntap.lease
|
||||
|
||||
private void LeaseExpTask()
|
||||
{
|
||||
signInClientState.OnSignInSuccess += async (times) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await GetNetwork().ConfigureAwait(false);
|
||||
LeaseInfo info = leaseClientStore.Get(signInClientStore.Group.Id);
|
||||
if (info != null && info.IP.Equals(IPAddress.Any) == false)
|
||||
{
|
||||
await AddNetwork(info);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if(LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Error(ex);
|
||||
}
|
||||
}
|
||||
};
|
||||
TimerHelper.SetIntervalLong(async () =>
|
||||
{
|
||||
await messengerSender.SendReply(new MessageRequestWrap
|
||||
@@ -81,7 +109,7 @@ namespace linker.messenger.tuntap.lease
|
||||
Connection = signInClientState.Connection,
|
||||
MessengerId = (ushort)TuntapMessengerIds.LeaseExp,
|
||||
}).ConfigureAwait(false);
|
||||
}, 60000);
|
||||
}, 60000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.230" ProductVersion="0.0.0.230" 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.231" ProductVersion="0.0.0.231" 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"/>
|
||||
|
||||
BIN
src/linker.tray.win/dist/linker.tray.win.exe
vendored
BIN
src/linker.tray.win/dist/linker.tray.win.exe
vendored
Binary file not shown.
@@ -1 +1 @@
|
||||
.table-sort th[data-v-754b053a]{border-bottom:0}.dropdown[data-v-2f0ed5e0]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-2f0ed5e0]{vertical-align:middle}.dropdown .badge[data-v-2f0ed5e0]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}a[data-v-56c0e8be]{color:#666;text-decoration:underline}a.green[data-v-56c0e8be]{color:green;font-weight:700}a.download[data-v-56c0e8be]{margin-left:.6rem}a.download .el-icon[data-v-56c0e8be]{vertical-align:middle;font-weight:700;margin-left:.3rem}a.download .el-icon.loading[data-v-56c0e8be]{animation:loading-56c0e8be 1s linear infinite}a.download+a.download[data-v-56c0e8be]{margin-left:.2rem}@keyframes loading-56c0e8be{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}img.system[data-v-9f58a72e]{height:1.6rem;vertical-align:middle;margin-right:.4rem}.self[data-v-9f58a72e]{color:#d400ff}.self .el-icon[data-v-9f58a72e]{vertical-align:text-bottom}.ipaddress span[data-v-5db71b03]{vertical-align:middle}.el-input[data-v-5db71b03]{width:12rem;margin-right:.6rem}.el-col[data-v-7a697708]{text-align:left}div.point[data-v-41d1beca]{margin:-.2rem .3rem 0 -1.3rem;position:absolute}span.point[data-v-41d1beca]{width:.8rem;height:.8rem;border-radius:50%;display:inline-block;vertical-align:middle;background-color:#eee;border:1px solid #ddd;cursor:pointer;transition:.3s}span.point[data-v-41d1beca]:hover{transform:scale(2)}span.point.p2p[data-v-41d1beca]{background-color:#01c901;border:1px solid #049538}span.point.relay[data-v-41d1beca]{background-color:#e3e811;border:1px solid #b3c410}span.point.node[data-v-41d1beca]{background-color:#09dda9;border:1px solid #0cac90}.el-icon.loading[data-v-5ce8d590],a.loading[data-v-5ce8d590]{vertical-align:middle;font-weight:700;animation:loading-5ce8d590 1s linear infinite}.el-switch.is-disabled[data-v-5ce8d590]{opacity:1}.el-input[data-v-5ce8d590]{width:8rem}.delay[data-v-5ce8d590]{position:absolute;right:0;bottom:0;line-height:normal}.switch-btn[data-v-5ce8d590]{font-size:1.5rem}.any[data-v-5ce8d590]{position:absolute;left:-7px;top:-2px;line-height:normal}.any.green[data-v-5ce8d590]{background:linear-gradient(270deg,#caff00,green,#0d6d23,#e38a00,green);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:hsla(0,0%,100%,0)}@keyframes loading-5ce8d590{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.wrap[data-v-786fe646]{padding-right:1rem}.remark[data-v-786fe646]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wrap[data-v-286c7cac]{padding-right:1rem}.el-switch.is-disabled[data-v-0b701835]{opacity:1}.upgrade-wrap[data-v-0b701835]{border:1px solid #ddd;margin-bottom:2rem;padding:0 0 1rem 0}.el-switch.is-disabled[data-v-67ed3552]{opacity:1}.calc span[data-v-67ed3552]{display:inline-block}.calc span.label[data-v-67ed3552]{width:6rem}.el-icon.loading[data-v-3a4bfe6c],a.loading[data-v-3a4bfe6c]{vertical-align:middle;font-weight:700;animation:loading-3a4bfe6c 1s linear infinite}.el-switch.is-disabled[data-v-3a4bfe6c]{opacity:1}.el-input[data-v-3a4bfe6c]{width:8rem}.switch-btn[data-v-3a4bfe6c]{font-size:1.5rem}@keyframes loading-3a4bfe6c{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.el-switch.is-disabled[data-v-022e3781]{opacity:1}.upgrade-wrap[data-v-022e3781]{border:1px solid #ddd;margin-bottom:2rem;padding:1rem 0 1rem 0}.lan-item[data-v-022e3781]{margin-bottom:0}.el-switch.is-disabled[data-v-64b81c5b]{opacity:1}.green[data-v-64b81c5b]{font-weight:700}img.system[data-v-64b81c5b]{height:1.4rem;margin-right:.4rem;border:1px solid #eee}.el-switch.is-disabled[data-v-6941c158]{opacity:1}ul li[data-v-6941c158]{padding-left:2rem}a[data-v-2ee190a4]{text-decoration:underline}a+a[data-v-2ee190a4]{margin-left:1rem}a.green[data-v-2ee190a4]{font-weight:700}.head[data-v-6897ed85]{padding-bottom:1rem}.green[data-v-6897ed85]{color:green;font-weight:700}.error[data-v-6897ed85]{font-weight:700}.error .el-icon[data-v-6897ed85]{vertical-align:text-bottom}.head[data-v-7d65167d]{padding-bottom:1rem}.error[data-v-7d65167d]{font-weight:700}.error .el-icon[data-v-7d65167d]{vertical-align:text-bottom}.head[data-v-8c388c86]{padding-bottom:1rem}.blue[data-v-8c388c86]{color:#409eff}.dropdown[data-v-8c388c86]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-8c388c86]{vertical-align:middle}.dropdown .badge[data-v-8c388c86]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}.table-sort.el-table th.el-table__cell.is-leaf{border-bottom:0}.table-sort.el-table .el-table__inner-wrapper:before{height:0}.home-list-wrap[data-v-4766ad40]{padding:1rem}.home-list-wrap .page[data-v-4766ad40]{padding-top:1rem}.home-list-wrap .page-wrap[data-v-4766ad40]{display:inline-block}
|
||||
.table-sort th[data-v-754b053a]{border-bottom:0}.dropdown[data-v-2f0ed5e0]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-2f0ed5e0]{vertical-align:middle}.dropdown .badge[data-v-2f0ed5e0]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}a[data-v-56c0e8be]{color:#666;text-decoration:underline}a.green[data-v-56c0e8be]{color:green;font-weight:700}a.download[data-v-56c0e8be]{margin-left:.6rem}a.download .el-icon[data-v-56c0e8be]{vertical-align:middle;font-weight:700;margin-left:.3rem}a.download .el-icon.loading[data-v-56c0e8be]{animation:loading-56c0e8be 1s linear infinite}a.download+a.download[data-v-56c0e8be]{margin-left:.2rem}@keyframes loading-56c0e8be{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}img.system[data-v-9f58a72e]{height:1.6rem;vertical-align:middle;margin-right:.4rem}.self[data-v-9f58a72e]{color:#d400ff}.self .el-icon[data-v-9f58a72e]{vertical-align:text-bottom}.ipaddress span[data-v-5db71b03]{vertical-align:middle}.el-input[data-v-5db71b03]{width:12rem;margin-right:.6rem}.el-col[data-v-7a697708]{text-align:left}div.point[data-v-41d1beca]{margin:-.2rem .3rem 0 -1.3rem;position:absolute}span.point[data-v-41d1beca]{width:.8rem;height:.8rem;border-radius:50%;display:inline-block;vertical-align:middle;background-color:#eee;border:1px solid #ddd;cursor:pointer;transition:.3s}span.point[data-v-41d1beca]:hover{transform:scale(2)}span.point.p2p[data-v-41d1beca]{background-color:#01c901;border:1px solid #049538}span.point.relay[data-v-41d1beca]{background-color:#e3e811;border:1px solid #b3c410}span.point.node[data-v-41d1beca]{background-color:#09dda9;border:1px solid #0cac90}.el-icon.loading[data-v-5ce8d590],a.loading[data-v-5ce8d590]{vertical-align:middle;font-weight:700;animation:loading-5ce8d590 1s linear infinite}.el-switch.is-disabled[data-v-5ce8d590]{opacity:1}.el-input[data-v-5ce8d590]{width:8rem}.delay[data-v-5ce8d590]{position:absolute;right:0;bottom:0;line-height:normal}.switch-btn[data-v-5ce8d590]{font-size:1.5rem}.any[data-v-5ce8d590]{position:absolute;left:-7px;top:-2px;line-height:normal}.any.green[data-v-5ce8d590]{background:linear-gradient(270deg,#caff00,green,#0d6d23,#e38a00,green);background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:hsla(0,0%,100%,0)}@keyframes loading-5ce8d590{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.wrap[data-v-786fe646]{padding-right:1rem}.remark[data-v-786fe646]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wrap[data-v-286c7cac]{padding-right:1rem}.el-switch.is-disabled[data-v-d52cdcd0]{opacity:1}.upgrade-wrap[data-v-d52cdcd0]{border:1px solid #ddd;margin-bottom:2rem;padding:0 0 1rem 0}.el-switch.is-disabled[data-v-67ed3552]{opacity:1}.calc span[data-v-67ed3552]{display:inline-block}.calc span.label[data-v-67ed3552]{width:6rem}.el-icon.loading[data-v-3a4bfe6c],a.loading[data-v-3a4bfe6c]{vertical-align:middle;font-weight:700;animation:loading-3a4bfe6c 1s linear infinite}.el-switch.is-disabled[data-v-3a4bfe6c]{opacity:1}.el-input[data-v-3a4bfe6c]{width:8rem}.switch-btn[data-v-3a4bfe6c]{font-size:1.5rem}@keyframes loading-3a4bfe6c{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.el-switch.is-disabled[data-v-022e3781]{opacity:1}.upgrade-wrap[data-v-022e3781]{border:1px solid #ddd;margin-bottom:2rem;padding:1rem 0 1rem 0}.lan-item[data-v-022e3781]{margin-bottom:0}.el-switch.is-disabled[data-v-64b81c5b]{opacity:1}.green[data-v-64b81c5b]{font-weight:700}img.system[data-v-64b81c5b]{height:1.4rem;margin-right:.4rem;border:1px solid #eee}.el-switch.is-disabled[data-v-6941c158]{opacity:1}ul li[data-v-6941c158]{padding-left:2rem}a[data-v-2ee190a4]{text-decoration:underline}a+a[data-v-2ee190a4]{margin-left:1rem}a.green[data-v-2ee190a4]{font-weight:700}.head[data-v-6897ed85]{padding-bottom:1rem}.green[data-v-6897ed85]{color:green;font-weight:700}.error[data-v-6897ed85]{font-weight:700}.error .el-icon[data-v-6897ed85]{vertical-align:text-bottom}.head[data-v-7d65167d]{padding-bottom:1rem}.error[data-v-7d65167d]{font-weight:700}.error .el-icon[data-v-7d65167d]{vertical-align:text-bottom}.head[data-v-8c388c86]{padding-bottom:1rem}.blue[data-v-8c388c86]{color:#409eff}.dropdown[data-v-8c388c86]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-8c388c86]{vertical-align:middle}.dropdown .badge[data-v-8c388c86]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}.table-sort.el-table th.el-table__cell.is-leaf{border-bottom:0}.table-sort.el-table .el-table__inner-wrapper:before{height:0}.home-list-wrap[data-v-4766ad40]{padding:1rem}.home-list-wrap .page[data-v-4766ad40]{padding-top:1rem}.home-list-wrap .page-wrap[data-v-4766ad40]{display:inline-block}
|
||||
@@ -1 +1 @@
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/><script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script><script defer="defer" src="js/chunk-vendors.3be25225.js"></script><script defer="defer" src="js/app.0e347be3.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.7bd6c330.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/><script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script><script defer="defer" src="js/chunk-vendors.3be25225.js"></script><script defer="defer" src="js/app.3d2b2fb0.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.7bd6c330.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
File diff suppressed because one or more lines are too long
1
src/linker.tray.win/web/js/879.ce2aff26.js
Normal file
1
src/linker.tray.win/web/js/879.ce2aff26.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -98,7 +98,7 @@ namespace linker.tun
|
||||
/// 检查网卡是否可用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<bool> CheckAvailable();
|
||||
public Task<bool> CheckAvailable(bool order = false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -341,7 +341,7 @@ namespace linker.tun
|
||||
return output;
|
||||
}
|
||||
|
||||
public async Task<bool> CheckAvailable()
|
||||
public async Task<bool> CheckAvailable(bool order = false)
|
||||
{
|
||||
string output = CommandHelper.Linux(string.Empty, new string[] { $"ip link show {Name}" });
|
||||
return await Task.FromResult(output.Contains("state UP")).ConfigureAwait(false);
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace linker.tun
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> CheckAvailable()
|
||||
public async Task<bool> CheckAvailable(bool order = false)
|
||||
{
|
||||
return await Task.FromResult(true).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using linker.libs;
|
||||
using linker.libs.timer;
|
||||
using System.Buffers.Binary;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.tun
|
||||
@@ -285,9 +284,9 @@ namespace linker.tun
|
||||
}
|
||||
|
||||
|
||||
public async Task<bool> CheckAvailable()
|
||||
public async Task<bool> CheckAvailable(bool order = false)
|
||||
{
|
||||
return await linkerTunDevice.CheckAvailable();
|
||||
return await linkerTunDevice.CheckAvailable(order);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,14 +154,17 @@ namespace linker.tun
|
||||
if (session == 0) return;
|
||||
try
|
||||
{
|
||||
WinTun.SetEvent(waitHandle);
|
||||
WinTun.WintunEndSession(session);
|
||||
IntPtr oldSession = session;
|
||||
IntPtr oldWaitHandle = waitHandle;
|
||||
|
||||
CommandHelper.Windows(string.Empty, new string[] { $"netsh interface set interface {Name} enable" });
|
||||
session = WinTun.WintunStartSession(adapter, 0x400000);
|
||||
waitHandle = WinTun.WintunGetReadWaitEvent(session);
|
||||
AddIPV4();
|
||||
AddIPV6();
|
||||
|
||||
WinTun.SetEvent(oldWaitHandle);
|
||||
WinTun.WintunEndSession(oldSession);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -391,11 +394,12 @@ namespace linker.tun
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> CheckAvailable()
|
||||
public async Task<bool> CheckAvailable(bool order = false)
|
||||
{
|
||||
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
|
||||
|
||||
InterfaceOrder(interfaces);
|
||||
if (order)
|
||||
InterfaceOrder(interfaces);
|
||||
NetworkInterface networkInterface = interfaces.FirstOrDefault(c => c.Name == Name || c.Description == $"{Name} Tunnel" || c.Name.Contains(Name));
|
||||
|
||||
UnicastIPAddressInformation firstIpv4 = networkInterface?.GetIPProperties()
|
||||
|
||||
@@ -117,7 +117,6 @@ namespace linker.tunnel
|
||||
{
|
||||
if (tunnelMessengerAdapter.ServerHost == null) return;
|
||||
|
||||
Console.WriteLine(tunnelMessengerAdapter.ServerHost);
|
||||
GetLocalIP(tunnelMessengerAdapter.ServerHost).ContinueWith((result) =>
|
||||
{
|
||||
if (tunnelMessengerAdapter.PortMapPrivate > 0)
|
||||
|
||||
@@ -154,6 +154,7 @@ namespace linker.tunnel.connection
|
||||
/// </summary>
|
||||
public LastTicksManager LastTicks { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 发送数据
|
||||
/// </summary>
|
||||
@@ -175,6 +176,10 @@ namespace linker.tunnel.connection
|
||||
/// <param name="userToken">自定义数据,回调带上</param>
|
||||
public void BeginReceive(ITunnelConnectionReceiveCallback callback, object userToken);
|
||||
|
||||
public void StartPacketMerge()
|
||||
{
|
||||
}
|
||||
|
||||
public string ToString();
|
||||
public bool Equals(ITunnelConnection connection);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace linker.tunnel.connection
|
||||
|
||||
public LastTicksManager LastTicks { get; private set; } = new LastTicksManager();
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
public QuicStream Stream { get; init; }
|
||||
[JsonIgnore]
|
||||
@@ -55,12 +56,11 @@ namespace linker.tunnel.connection
|
||||
private ITunnelConnectionReceiveCallback callback;
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private object userToken;
|
||||
private ReceiveDataBuffer bufferCache = new ReceiveDataBuffer();
|
||||
private readonly ReceiveDataBuffer bufferCache = new ReceiveDataBuffer();
|
||||
|
||||
private LastTicksManager pingTicks = new();
|
||||
private byte[] pingBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.ping");
|
||||
private byte[] pongBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.pong");
|
||||
private bool pong = true;
|
||||
private readonly LastTicksManager pingTicks = new();
|
||||
private readonly byte[] pingBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.ping");
|
||||
private readonly byte[] pongBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.pong");
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -153,7 +153,6 @@ namespace linker.tunnel.connection
|
||||
else if (packet.Span.SequenceEqual(pongBytes))
|
||||
{
|
||||
Delay = (int)pingTicks.Diff();
|
||||
pong = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +200,6 @@ namespace linker.tunnel.connection
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
pong = true;
|
||||
Dispose();
|
||||
}
|
||||
finally
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Net;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text;
|
||||
using System.Net.Sockets;
|
||||
using System.IO.Pipelines;
|
||||
|
||||
namespace linker.tunnel.connection
|
||||
{
|
||||
@@ -39,6 +40,7 @@ namespace linker.tunnel.connection
|
||||
|
||||
public LastTicksManager LastTicks { get; private set; } = new LastTicksManager();
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
public SslStream Stream { get; init; }
|
||||
|
||||
@@ -49,19 +51,17 @@ namespace linker.tunnel.connection
|
||||
private ITunnelConnectionReceiveCallback callback;
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private object userToken;
|
||||
private ReceiveDataBuffer bufferCache = new ReceiveDataBuffer();
|
||||
private readonly ReceiveDataBuffer bufferCache = new ReceiveDataBuffer();
|
||||
|
||||
private LastTicksManager pingTicks = new LastTicksManager();
|
||||
private byte[] pingBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.ping");
|
||||
private byte[] pongBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.pong");
|
||||
private bool pong = true;
|
||||
private readonly LastTicksManager pingTicks = new LastTicksManager();
|
||||
private readonly byte[] pingBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.ping");
|
||||
private readonly byte[] pongBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.tcp.pong");
|
||||
|
||||
/// <summary>
|
||||
/// 开始接收数据
|
||||
/// </summary>
|
||||
/// <param name="callback">数据回调</param>
|
||||
/// <param name="userToken">自定义数据</param>
|
||||
/// <param name="byFrame">是否处理粘包,true时,请在首部4字节标注数据长度</param>
|
||||
public void BeginReceive(ITunnelConnectionReceiveCallback callback, object userToken)
|
||||
{
|
||||
if (this.callback != null) return;
|
||||
@@ -163,7 +163,6 @@ namespace linker.tunnel.connection
|
||||
else if (packet.Span.SequenceEqual(pongBytes))
|
||||
{
|
||||
Delay = (int)pingTicks.Diff();
|
||||
pong = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -226,7 +225,6 @@ namespace linker.tunnel.connection
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
pong = true;
|
||||
Dispose();
|
||||
}
|
||||
finally
|
||||
@@ -236,12 +234,21 @@ namespace linker.tunnel.connection
|
||||
|
||||
ArrayPool<byte>.Shared.Return(heartData);
|
||||
}
|
||||
private SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1);
|
||||
|
||||
private readonly SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1);
|
||||
public async Task<bool> SendAsync(ReadOnlyMemory<byte> data)
|
||||
{
|
||||
if (callback == null) return false;
|
||||
|
||||
if (pipe != null)
|
||||
{
|
||||
Memory<byte> memory = pipe.Writer.GetMemory(data.Length);
|
||||
data.CopyTo(memory);
|
||||
pipe.Writer.Advance(data.Length);
|
||||
await pipe.Writer.FlushAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Stream != null)
|
||||
{
|
||||
await semaphoreSlim.WaitAsync().ConfigureAwait(false);
|
||||
@@ -278,6 +285,16 @@ namespace linker.tunnel.connection
|
||||
{
|
||||
if (callback == null) return false;
|
||||
|
||||
if (pipe != null)
|
||||
{
|
||||
ReadOnlyMemory<byte> data = buffer.AsMemory(offset, length);
|
||||
Memory<byte> memory = pipe.Writer.GetMemory(data.Length);
|
||||
data.CopyTo(memory);
|
||||
pipe.Writer.Advance(data.Length);
|
||||
await pipe.Writer.FlushAsync();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Stream != null)
|
||||
{
|
||||
await semaphoreSlim.WaitAsync().ConfigureAwait(false);
|
||||
@@ -311,11 +328,11 @@ namespace linker.tunnel.connection
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
private Pipe pipe;
|
||||
public void PipeLines()
|
||||
public void StartPacketMerge()
|
||||
{
|
||||
pipe = new Pipe(new PipeOptions { });
|
||||
pipe = new Pipe(new PipeOptions(pauseWriterThreshold:800*1024));
|
||||
_ = Reader();
|
||||
}
|
||||
private async Task Reader()
|
||||
@@ -328,13 +345,13 @@ namespace linker.tunnel.connection
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ReadOnlySequence<byte> buffer = result.Buffer;
|
||||
while (buffer.Length > 0)
|
||||
{
|
||||
int chunkSize = (int)Math.Min(buffer.Length, 8192);
|
||||
ReadOnlySequence<byte> chunk = buffer.Slice(0, chunkSize);
|
||||
|
||||
|
||||
if (Stream != null) await semaphoreSlim.WaitAsync().ConfigureAwait(false);
|
||||
try
|
||||
{
|
||||
@@ -367,27 +384,8 @@ namespace linker.tunnel.connection
|
||||
}
|
||||
pipe.Reader.AdvanceTo(result.Buffer.End);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
public async Task<bool> WriteAsync(ReadOnlyMemory<byte> data)
|
||||
{
|
||||
Memory<byte> memory = pipe.Writer.GetMemory(data.Length);
|
||||
data.CopyTo(memory);
|
||||
pipe.Writer.Advance(data.Length);
|
||||
await pipe.Writer.FlushAsync();
|
||||
return true;
|
||||
}
|
||||
public async Task<bool> WriteAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
ReadOnlyMemory<byte> data = buffer.AsMemory(offset, length);
|
||||
Memory<byte> memory = pipe.Writer.GetMemory(data.Length);
|
||||
data.CopyTo(memory);
|
||||
pipe.Writer.Advance(data.Length);
|
||||
await pipe.Writer.FlushAsync();
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -407,6 +405,14 @@ namespace linker.tunnel.connection
|
||||
|
||||
Socket?.SafeClose();
|
||||
|
||||
try
|
||||
{
|
||||
pipe?.Writer.Complete();
|
||||
pipe?.Reader.Complete();
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
|
||||
}
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
@@ -5,7 +5,6 @@ using System.Net;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Net.Sockets;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace linker.tunnel.connection
|
||||
{
|
||||
@@ -62,12 +61,11 @@ namespace linker.tunnel.connection
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private object userToken;
|
||||
|
||||
private LastTicksManager pingTicks = new LastTicksManager();
|
||||
private byte[] pingBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.udp.ping");
|
||||
private byte[] pongBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.udp.pong");
|
||||
private byte[] finBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.udp.fing");
|
||||
private byte[] ttlBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.ttl");
|
||||
private bool pong = true;
|
||||
private readonly LastTicksManager pingTicks = new LastTicksManager();
|
||||
private readonly byte[] pingBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.udp.ping");
|
||||
private readonly byte[] pongBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.udp.pong");
|
||||
private readonly byte[] finBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.udp.fing");
|
||||
private readonly byte[] ttlBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.ttl");
|
||||
|
||||
|
||||
/// <summary>
|
||||
@@ -148,7 +146,6 @@ namespace linker.tunnel.connection
|
||||
else if (memory.Span.SequenceEqual(pongBytes))
|
||||
{
|
||||
Delay = (int)pingTicks.Diff();
|
||||
pong = true;
|
||||
}
|
||||
else if (memory.Span.SequenceEqual(finBytes))
|
||||
{
|
||||
@@ -226,7 +223,6 @@ namespace linker.tunnel.connection
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
pong = true;
|
||||
Dispose();
|
||||
}
|
||||
finally
|
||||
@@ -236,7 +232,6 @@ namespace linker.tunnel.connection
|
||||
ArrayPool<byte>.Shared.Return(heartData);
|
||||
}
|
||||
|
||||
|
||||
private byte[] encodeBuffer = new byte[8 * 1024];
|
||||
public async Task<bool> SendAsync(ReadOnlyMemory<byte> data)
|
||||
{
|
||||
@@ -308,6 +303,7 @@ namespace linker.tunnel.connection
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -337,4 +333,4 @@ namespace linker.tunnel.connection
|
||||
return connection != null && GetHashCode() == connection.GetHashCode() && IPEndPoint.Equals(connection.IPEndPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Mono.Nat" Version="3.0.4" />
|
||||
<PackageReference Include="System.IO.Pipelines" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -6,15 +6,19 @@
|
||||
<el-form-item label="网卡名" prop="Name">
|
||||
<el-input v-model="state.ruleForm.Name" style="width:14rem" /> <span>留空则使用【本组网络】的设置</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="网卡IP" prop="IP">
|
||||
<el-form-item label="网卡IP" prop="IP" class="mgb-0">
|
||||
<el-input v-model="state.ruleForm.IP" style="width:14rem" />
|
||||
<span>/</span>
|
||||
<el-input @change="handlePrefixLengthChange" v-model="state.ruleForm.PrefixLength" style="width:4rem" />
|
||||
<span style="width: 2rem;"></span>
|
||||
<el-checkbox v-model="state.ruleForm.ShowDelay" label="显示延迟" size="large" style="margin-right:1rem" />
|
||||
<el-checkbox v-model="state.ruleForm.AutoConnect" label="自动连接" size="large" style="margin-right:1rem" />
|
||||
<el-checkbox v-model="state.ruleForm.Multicast" label="禁用广播" size="large" />
|
||||
<el-checkbox v-model="state.ruleForm.Nat" label="禁用NAT" size="large" />
|
||||
<span>/</span>
|
||||
<el-input @change="handlePrefixLengthChange" v-model="state.ruleForm.PrefixLength" style="width:4rem" />
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="">
|
||||
<el-checkbox class="mgr-1" v-model="state.ruleForm.ShowDelay" label="显示延迟" size="large" />
|
||||
<el-checkbox class="mgr-1" v-model="state.ruleForm.AutoConnect" label="自动连接" size="large" />
|
||||
<el-checkbox class="mgr-1" v-model="state.ruleForm.Multicast" label="禁用广播" size="large" />
|
||||
<el-checkbox class="mgr-1" v-model="state.ruleForm.Nat" label="禁用NAT" size="large" />
|
||||
<el-checkbox class="mgr-1" v-model="state.ruleForm.TcpMerge" label="TCP包合并" size="large" />
|
||||
<el-checkbox v-model="state.ruleForm.InterfaceOrder" label="调整网卡顺序" size="large" />
|
||||
</el-form-item>
|
||||
<el-form-item prop="upgrade" class="mgb-0">
|
||||
<el-checkbox v-model="state.ruleForm.Upgrade" label="我很懂,我要使用高级功能(点对网和网对网)" size="large" />
|
||||
@@ -68,6 +72,8 @@ export default {
|
||||
Upgrade: tuntap.value.current.Upgrade,
|
||||
Multicast: tuntap.value.current.Multicast,
|
||||
Nat: tuntap.value.current.Nat,
|
||||
TcpMerge: tuntap.value.current.TcpMerge,
|
||||
InterfaceOrder: tuntap.value.current.InterfaceOrder,
|
||||
Forwards: tuntap.value.current.Forwards,
|
||||
Name: tuntap.value.current.Name,
|
||||
},
|
||||
@@ -112,6 +118,8 @@ export default {
|
||||
json.Upgrade = state.ruleForm.Upgrade;
|
||||
json.Multicast = state.ruleForm.Multicast;
|
||||
json.Nat = state.ruleForm.Nat;
|
||||
json.TcpMerge = state.ruleForm.TcpMerge;
|
||||
json.InterfaceOrder = state.ruleForm.InterfaceOrder;
|
||||
json.Forwards = forwardDom.value ? forwardDom.value.getData() : tuntap.value.current.Forwards;
|
||||
json.Name = state.ruleForm.Name;
|
||||
updateTuntap(json).then(() => {
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
<Authors>snltty</Authors>
|
||||
<Company>snltty</Company>
|
||||
<Description>1. 优化数据同步
|
||||
2. 优化linux网卡,我感觉网卡速度比较正常了
|
||||
3. 建议更新</Description>
|
||||
2. 优化linux的tun网卡网卡,读写分离,提高性能
|
||||
3. 优化windows网卡的禁用自动启用
|
||||
4. 增加TCP包合并。网卡IP包多个合并一起发送
|
||||
5. 建议更新</Description>
|
||||
<Copyright>snltty</Copyright>
|
||||
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
v1.7.1
|
||||
2025-03-23 20:24:26
|
||||
2025-03-26 00:16:31
|
||||
1. 优化数据同步
|
||||
2. 优化linux网卡,我感觉网卡速度比较正常了
|
||||
3. 建议更新
|
||||
2. 优化linux的tun网卡网卡,读写分离,提高性能
|
||||
3. 优化windows网卡的禁用自动启用
|
||||
4. 增加TCP包合并。网卡IP包多个合并一起发送
|
||||
5. 建议更新
|
||||
Reference in New Issue
Block a user