mirror of
https://github.com/snltty/linker.git
synced 2025-10-07 10:01:04 +08:00
整理代码
This commit is contained in:
@@ -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.184" ProductVersion="0.0.0.184" 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.185" ProductVersion="0.0.0.185" 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
linker.tray.win/dist/linker.tray.win.exe
vendored
BIN
linker.tray.win/dist/linker.tray.win.exe
vendored
Binary file not shown.
@@ -1 +1 @@
|
||||
.table-sort th[data-v-4b2df38c]{border-bottom:0}.dropdown[data-v-6638f97d]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-6638f97d]{vertical-align:middle}.dropdown .badge[data-v-6638f97d]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}a[data-v-6653ef00]{color:#666;text-decoration:underline}a.green[data-v-6653ef00]{color:green;font-weight:700}a.download[data-v-6653ef00]{margin-left:.6rem}a.download .el-icon[data-v-6653ef00]{vertical-align:middle;font-weight:700;margin-left:.3rem}a.download .el-icon.loading[data-v-6653ef00]{animation:loading-6653ef00 1s linear infinite}a.download+a.download[data-v-6653ef00]{margin-left:.2rem}@keyframes loading-6653ef00{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}img.system[data-v-ffd0d512]{height:1.6rem;vertical-align:middle;margin-right:.4rem}.self[data-v-ffd0d512]{color:#d400ff}.self .el-icon[data-v-ffd0d512]{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-5d52ca48]{text-align:left}.el-icon.loading[data-v-7edec26e],a.loading[data-v-7edec26e]{vertical-align:middle;font-weight:700;animation:loading-7edec26e 1s linear infinite}.el-switch.is-disabled[data-v-7edec26e]{opacity:1}.el-input[data-v-7edec26e]{width:8rem}.delay[data-v-7edec26e]{position:absolute;right:0;bottom:0;line-height:normal}.switch-btn[data-v-7edec26e]{font-size:1.5rem}@keyframes loading-7edec26e{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.wrap[data-v-71a71fe4]{padding-right:1rem}.remark[data-v-71a71fe4]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wrap[data-v-4abaaeaf]{padding-right:1rem}.el-switch.is-disabled[data-v-34275839]{opacity:1}.upgrade-wrap[data-v-34275839]{border:1px solid #ddd;margin-bottom:2rem;padding:0 0 1rem 0}.el-switch.is-disabled[data-v-4a28804a]{opacity:1}.calc span[data-v-4a28804a]{display:inline-block}.calc span.label[data-v-4a28804a]{width:6rem}.el-icon.loading[data-v-c1ea089c],a.loading[data-v-c1ea089c]{vertical-align:middle;font-weight:700;animation:loading-c1ea089c 1s linear infinite}.el-switch.is-disabled[data-v-c1ea089c]{opacity:1}.el-input[data-v-c1ea089c]{width:8rem}.switch-btn[data-v-c1ea089c]{font-size:1.5rem}@keyframes loading-c1ea089c{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-49e16cac]{opacity:1}.green[data-v-49e16cac]{font-weight:700}.el-switch.is-disabled[data-v-6ea047f9]{opacity:1}a[data-v-26b3f87e]{text-decoration:underline}a+a[data-v-26b3f87e]{margin-left:1rem}a.green[data-v-26b3f87e]{font-weight:700}.head[data-v-15b05a01]{padding-bottom:1rem}.green[data-v-15b05a01]{color:green;font-weight:700}.error[data-v-15b05a01]{font-weight:700}.error .el-icon[data-v-15b05a01]{vertical-align:text-bottom}.head[data-v-7eb8e7cc]{padding-bottom:1rem}.error[data-v-7eb8e7cc]{font-weight:700}.error .el-icon[data-v-7eb8e7cc]{vertical-align:text-bottom}.head[data-v-7891b902]{padding-bottom:1rem}.table-sort.el-table th.el-table__cell.is-leaf{border-bottom:0}.table-sort.el-table .el-table__inner-wrapper:before{height:0}.home-list-wrap[data-v-3d1c480c]{padding:1rem}.home-list-wrap .page[data-v-3d1c480c]{padding-top:1rem}.home-list-wrap .page-wrap[data-v-3d1c480c]{display:inline-block}
|
||||
.table-sort th[data-v-4b2df38c]{border-bottom:0}.dropdown[data-v-6638f97d]{border:1px solid #ddd;padding:.4rem;font-size:1.3rem;border-radius:.4rem;position:relative}.dropdown .el-icon[data-v-6638f97d]{vertical-align:middle}.dropdown .badge[data-v-6638f97d]{position:absolute;right:-1rem;top:-50%;border-radius:10px;background-color:#f1ae05;color:#fff;padding:.2rem .6rem;font-size:1.2rem}a[data-v-6653ef00]{color:#666;text-decoration:underline}a.green[data-v-6653ef00]{color:green;font-weight:700}a.download[data-v-6653ef00]{margin-left:.6rem}a.download .el-icon[data-v-6653ef00]{vertical-align:middle;font-weight:700;margin-left:.3rem}a.download .el-icon.loading[data-v-6653ef00]{animation:loading-6653ef00 1s linear infinite}a.download+a.download[data-v-6653ef00]{margin-left:.2rem}@keyframes loading-6653ef00{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}img.system[data-v-ffd0d512]{height:1.6rem;vertical-align:middle;margin-right:.4rem}.self[data-v-ffd0d512]{color:#d400ff}.self .el-icon[data-v-ffd0d512]{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-5d52ca48]{text-align:left}.el-icon.loading[data-v-7edec26e],a.loading[data-v-7edec26e]{vertical-align:middle;font-weight:700;animation:loading-7edec26e 1s linear infinite}.el-switch.is-disabled[data-v-7edec26e]{opacity:1}.el-input[data-v-7edec26e]{width:8rem}.delay[data-v-7edec26e]{position:absolute;right:0;bottom:0;line-height:normal}.switch-btn[data-v-7edec26e]{font-size:1.5rem}@keyframes loading-7edec26e{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-4abaaeaf]{padding-right:1rem}.el-switch.is-disabled[data-v-34275839]{opacity:1}.upgrade-wrap[data-v-34275839]{border:1px solid #ddd;margin-bottom:2rem;padding:0 0 1rem 0}.el-switch.is-disabled[data-v-4a28804a]{opacity:1}.calc span[data-v-4a28804a]{display:inline-block}.calc span.label[data-v-4a28804a]{width:6rem}.el-icon.loading[data-v-c1ea089c],a.loading[data-v-c1ea089c]{vertical-align:middle;font-weight:700;animation:loading-c1ea089c 1s linear infinite}.el-switch.is-disabled[data-v-c1ea089c]{opacity:1}.el-input[data-v-c1ea089c]{width:8rem}.switch-btn[data-v-c1ea089c]{font-size:1.5rem}@keyframes loading-c1ea089c{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-49e16cac]{opacity:1}.green[data-v-49e16cac]{font-weight:700}.el-switch.is-disabled[data-v-6ea047f9]{opacity:1}a[data-v-26b3f87e]{text-decoration:underline}a+a[data-v-26b3f87e]{margin-left:1rem}a.green[data-v-26b3f87e]{font-weight:700}.head[data-v-15b05a01]{padding-bottom:1rem}.green[data-v-15b05a01]{color:green;font-weight:700}.error[data-v-15b05a01]{font-weight:700}.error .el-icon[data-v-15b05a01]{vertical-align:text-bottom}.head[data-v-7eb8e7cc]{padding-bottom:1rem}.error[data-v-7eb8e7cc]{font-weight:700}.error .el-icon[data-v-7eb8e7cc]{vertical-align:text-bottom}.head[data-v-7891b902]{padding-bottom:1rem}.table-sort.el-table th.el-table__cell.is-leaf{border-bottom:0}.table-sort.el-table .el-table__inner-wrapper:before{height:0}.home-list-wrap[data-v-3d1c480c]{padding:1rem}.home-list-wrap .page[data-v-3d1c480c]{padding-top:1rem}.home-list-wrap .page-wrap[data-v-3d1c480c]{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><script defer="defer" src="js/chunk-vendors.7b81ea90.js"></script><script defer="defer" src="js/app.8e82ca5d.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.e2cbd3ed.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
||||
<!doctype html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>linker.web</title><script defer="defer" src="js/chunk-vendors.7b81ea90.js"></script><script defer="defer" src="js/app.1dbd8a85.js"></script><link href="css/chunk-vendors.d8267b33.css" rel="stylesheet"><link href="css/app.e2cbd3ed.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but linker.web doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div></body></html>
|
File diff suppressed because one or more lines are too long
1
linker.tray.win/web/js/509.b1ccc755.js
Normal file
1
linker.tray.win/web/js/509.b1ccc755.js
Normal file
File diff suppressed because one or more lines are too long
1
linker.tray.win/web/js/app.1dbd8a85.js
Normal file
1
linker.tray.win/web/js/app.1dbd8a85.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,5 +1,4 @@
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.connection;
|
||||
using linker.tunnel.connection;
|
||||
using linker.tunnel.transport;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
@@ -7,14 +6,63 @@ using System.Collections.Concurrent;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using linker.tunnel.wanport;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace linker.tunnel
|
||||
{
|
||||
public sealed class TunnelTransfer
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 本机局域网IP,当然你也可以使用0.0.0.0,但是使用局域网IP会提高打洞成功率
|
||||
/// </summary>
|
||||
public Func<IPAddress> LocalIP { get; set; } = () => IPAddress.Any;
|
||||
/// <summary>
|
||||
/// 服务器地址
|
||||
/// </summary>
|
||||
public Func<IPEndPoint> ServerHost { get; set; } = () => new IPEndPoint(IPAddress.Any, 0);
|
||||
/// <summary>
|
||||
/// ssl加密证书,没有证书则无法加密通信
|
||||
/// </summary>
|
||||
public Func<X509Certificate2> Certificate { get; set; } = () => null;
|
||||
/// <summary>
|
||||
/// 获取打洞协议列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Func<List<TunnelTransportItemInfo>> GetTunnelTransports { get; set; } = () => new List<TunnelTransportItemInfo>();
|
||||
/// <summary>
|
||||
/// 保存打洞协议列表
|
||||
/// </summary>
|
||||
/// <param name="transports"></param>
|
||||
public Action<List<TunnelTransportItemInfo>, bool> SetTunnelTransports { get; set; } = (list, update) => { };
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地网络信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Func<NetworkInfo> GetLocalConfig { get; set; } = () => new NetworkInfo();
|
||||
|
||||
/// <summary>
|
||||
/// 获取远端的外网信息,比如你是A,你要获取B的信息,可以在B调用 TunnelTransfer.GetWanPort() 发送回来
|
||||
/// </summary>
|
||||
public Func<TunnelWanPortProtocolInfo, Task<TunnelTransportWanPortInfo>> GetRemoteWanPort { get; set; } = async (info) => { return await Task.FromResult(new TunnelTransportWanPortInfo()); };
|
||||
|
||||
/// <summary>
|
||||
/// 发送开始打洞
|
||||
/// </summary>
|
||||
public Func<TunnelTransportInfo, Task<bool>> SendConnectBegin { get; set; } = async (info) => { return await Task.FromResult(false); };
|
||||
/// <summary>
|
||||
/// 发送打洞失败
|
||||
/// </summary>
|
||||
public Func<TunnelTransportInfo, Task<bool>> SendConnectFail { get; set; } = async (info) => { return await Task.FromResult(false); };
|
||||
/// <summary>
|
||||
/// 发送打洞成功
|
||||
/// </summary>
|
||||
public Func<TunnelTransportInfo, Task<bool>> SendConnectSuccess { get; set; } = async (info) => { return await Task.FromResult(false); };
|
||||
|
||||
|
||||
private List<ITunnelTransport> transports;
|
||||
private TunnelWanPortTransfer compactTransfer;
|
||||
private ITunnelAdapter tunnelAdapter;
|
||||
private TunnelWanPortTransfer tunnelWanPortTransfer;
|
||||
private TunnelUpnpTransfer TunnelUpnpTransfer;
|
||||
|
||||
private ConcurrentDictionary<string, bool> connectingDic = new ConcurrentDictionary<string, bool>();
|
||||
@@ -29,23 +77,22 @@ namespace linker.tunnel
|
||||
/// 加载打洞协议
|
||||
/// </summary>
|
||||
/// <param name="assembs"></param>
|
||||
public void LoadTransports(TunnelWanPortTransfer compactTransfer, ITunnelAdapter tunnelAdapter, TunnelUpnpTransfer TunnelUpnpTransfer, List<ITunnelTransport> transports)
|
||||
public void LoadTransports(TunnelWanPortTransfer tunnelWanPortTransfer, TunnelUpnpTransfer TunnelUpnpTransfer, List<ITunnelTransport> transports)
|
||||
{
|
||||
this.compactTransfer = compactTransfer;
|
||||
this.tunnelAdapter = tunnelAdapter;
|
||||
this.tunnelWanPortTransfer = tunnelWanPortTransfer;
|
||||
this.transports = transports;
|
||||
this.TunnelUpnpTransfer = TunnelUpnpTransfer;
|
||||
|
||||
foreach (var item in transports)
|
||||
{
|
||||
item.OnSendConnectBegin = tunnelAdapter.SendConnectBegin;
|
||||
item.OnSendConnectFail = tunnelAdapter.SendConnectFail;
|
||||
item.OnSendConnectSuccess = tunnelAdapter.SendConnectSuccess;
|
||||
item.OnSendConnectBegin = SendConnectBegin;
|
||||
item.OnSendConnectFail = SendConnectFail;
|
||||
item.OnSendConnectSuccess = SendConnectSuccess;
|
||||
item.OnConnected = _OnConnected;
|
||||
item.SetAdapter(tunnelAdapter);
|
||||
item.SetSSL(Certificate());
|
||||
}
|
||||
|
||||
var transportItems = tunnelAdapter.GetTunnelTransports();
|
||||
var transportItems = GetTunnelTransports();
|
||||
//有新的协议
|
||||
var newTransportNames = transports.Select(c => c.Name).Except(transportItems.Select(c => c.Name));
|
||||
if (newTransportNames.Any())
|
||||
@@ -96,11 +143,10 @@ namespace linker.tunnel
|
||||
}
|
||||
}
|
||||
|
||||
tunnelAdapter.SetTunnelTransports(transportItems, true);
|
||||
SetTunnelTransports(transportItems, true);
|
||||
LoggerHelper.Instance.Info($"load tunnel transport:{string.Join(",", transports.Select(c => c.Name))}");
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置成功打洞回调
|
||||
/// </summary>
|
||||
@@ -154,7 +200,7 @@ namespace linker.tunnel
|
||||
|
||||
try
|
||||
{
|
||||
foreach (TunnelTransportItemInfo transportItem in tunnelAdapter.GetTunnelTransports().OrderBy(c => c.Order).Where(c => c.Disabled == false))
|
||||
foreach (TunnelTransportItemInfo transportItem in GetTunnelTransports().OrderBy(c => c.Order).Where(c => c.Disabled == false))
|
||||
{
|
||||
ITunnelTransport transport = transports.FirstOrDefault(c => c.Name == transportItem.Name);
|
||||
//找不到这个打洞协议,或者是不支持的协议
|
||||
@@ -163,7 +209,7 @@ namespace linker.tunnel
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var wanPortProtocol in compactTransfer.Protocols)
|
||||
foreach (var wanPortProtocol in tunnelWanPortTransfer.Protocols)
|
||||
{
|
||||
|
||||
//这个打洞协议不支持这个外网端口协议
|
||||
@@ -182,7 +228,7 @@ namespace linker.tunnel
|
||||
//获取自己的外网ip
|
||||
Task<TunnelTransportWanPortInfo> localInfo = GetLocalInfo(wanPortProtocol);
|
||||
//获取对方的外网ip
|
||||
Task<TunnelTransportWanPortInfo> remoteInfo = tunnelAdapter.GetRemoteWanPort(new TunnelWanPortProtocolInfo
|
||||
Task<TunnelTransportWanPortInfo> remoteInfo = GetRemoteWanPort(new TunnelWanPortProtocolInfo
|
||||
{
|
||||
MachineId = remoteMachineId,
|
||||
ProtocolType = wanPortProtocol
|
||||
@@ -270,7 +316,7 @@ namespace linker.tunnel
|
||||
try
|
||||
{
|
||||
ITunnelTransport _transports = transports.FirstOrDefault(c => c.Name == tunnelTransportInfo.TransportName && c.ProtocolType == tunnelTransportInfo.TransportType);
|
||||
TunnelTransportItemInfo item = tunnelAdapter.GetTunnelTransports().FirstOrDefault(c => c.Name == tunnelTransportInfo.TransportName && c.Disabled == false);
|
||||
TunnelTransportItemInfo item = GetTunnelTransports().FirstOrDefault(c => c.Name == tunnelTransportInfo.TransportName && c.Disabled == false);
|
||||
if (_transports != null && item != null)
|
||||
{
|
||||
OnConnectBegin(tunnelTransportInfo);
|
||||
@@ -283,7 +329,7 @@ namespace linker.tunnel
|
||||
else
|
||||
{
|
||||
connectingDic.TryRemove(tunnelTransportInfo.Remote.MachineId, out _);
|
||||
_ = tunnelAdapter.SendConnectFail(tunnelTransportInfo);
|
||||
_ = SendConnectFail(tunnelTransportInfo);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -331,11 +377,11 @@ namespace linker.tunnel
|
||||
/// <returns></returns>
|
||||
private async Task<TunnelTransportWanPortInfo> GetLocalInfo(TunnelWanPortProtocolType tunnelWanPortProtocolType)
|
||||
{
|
||||
TunnelWanPortEndPoint ip = await compactTransfer.GetWanPortAsync(tunnelAdapter.LocalIP, tunnelWanPortProtocolType).ConfigureAwait(false);
|
||||
TunnelWanPortEndPoint ip = await tunnelWanPortTransfer.GetWanPortAsync(ServerHost(), LocalIP(), tunnelWanPortProtocolType).ConfigureAwait(false);
|
||||
if (ip != null)
|
||||
{
|
||||
MapInfo portMapInfo = TunnelUpnpTransfer.PortMap ?? new MapInfo { PrivatePort = 0, PublicPort = 0 };
|
||||
var config = tunnelAdapter.GetLocalConfig();
|
||||
var config = GetLocalConfig();
|
||||
return new TunnelTransportWanPortInfo
|
||||
{
|
||||
Local = ip.Local,
|
||||
@@ -492,6 +538,12 @@ namespace linker.tunnel
|
||||
{
|
||||
backgroundDic.TryRemove(GetBackgroundKey(remoteMachineId, transactionId), out _);
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否正在后台打洞
|
||||
/// </summary>
|
||||
/// <param name="remoteMachineId"></param>
|
||||
/// <param name="transactionId"></param>
|
||||
/// <returns></returns>
|
||||
public bool IsBackground(string remoteMachineId, string transactionId)
|
||||
{
|
||||
return backgroundDic.ContainsKey(GetBackgroundKey(remoteMachineId, transactionId));
|
||||
|
@@ -1,103 +0,0 @@
|
||||
using linker.tunnel.wanport;
|
||||
using linker.tunnel.transport;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace linker.tunnel.adapter
|
||||
{
|
||||
public interface ITunnelAdapter
|
||||
{
|
||||
/// <summary>
|
||||
/// 本机局域网IP,当然你也可以使用0.0.0.0,但是使用局域网IP会提高打洞成功率
|
||||
/// </summary>
|
||||
public IPAddress LocalIP { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务器地址
|
||||
/// </summary>
|
||||
public IPEndPoint ServerHost { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ssl加密证书,没有证书则无法加密通信
|
||||
/// </summary>
|
||||
public X509Certificate2 Certificate { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取打洞协议列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<TunnelTransportItemInfo> GetTunnelTransports();
|
||||
/// <summary>
|
||||
/// 保存打洞协议列表
|
||||
/// </summary>
|
||||
/// <param name="transports"></param>
|
||||
public void SetTunnelTransports(List<TunnelTransportItemInfo> transports, bool updateVersion);
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地网络信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public NetworkInfo GetLocalConfig();
|
||||
|
||||
/// <summary>
|
||||
/// 获取远端的外网信息,比如你是A,你要获取B的信息,可以在B调用 TunnelTransfer.GetWanPort() 发送回来
|
||||
/// </summary>
|
||||
/// <param name="remoteMachineId"></param>
|
||||
/// <returns></returns>
|
||||
public Task<TunnelTransportWanPortInfo> GetRemoteWanPort(TunnelWanPortProtocolInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// 发送开始打洞
|
||||
/// </summary>
|
||||
/// <param name="tunnelTransportInfo"></param>
|
||||
/// <returns></returns>
|
||||
public Task<bool> SendConnectBegin(TunnelTransportInfo tunnelTransportInfo);
|
||||
/// <summary>
|
||||
/// 发送打洞失败
|
||||
/// </summary>
|
||||
/// <param name="tunnelTransportInfo"></param>
|
||||
/// <returns></returns>
|
||||
public Task<bool> SendConnectFail(TunnelTransportInfo tunnelTransportInfo);
|
||||
/// <summary>
|
||||
/// 发送打洞成功
|
||||
/// </summary>
|
||||
/// <param name="tunnelTransportInfo"></param>
|
||||
/// <returns></returns>
|
||||
public Task<bool> SendConnectSuccess(TunnelTransportInfo tunnelTransportInfo);
|
||||
}
|
||||
|
||||
public sealed class NetworkInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 本机局域网IP列表,可以通过NetworkHelper.GetRouteLevel 获取
|
||||
/// </summary>
|
||||
public IPAddress[] LocalIps { get; set; }
|
||||
/// <summary>
|
||||
/// 本机与外网的距离,通过多少网关,可以通过NetworkHelper.GetRouteLevel 获取
|
||||
/// </summary>
|
||||
public int RouteLevel { get; set; }
|
||||
/// <summary>
|
||||
/// 本机名
|
||||
/// </summary>
|
||||
public string MachineId { get; set; }
|
||||
}
|
||||
|
||||
public sealed class PortMapInfo
|
||||
{
|
||||
public int WanPort { get; set; }
|
||||
public int LanPort { get; set; }
|
||||
}
|
||||
|
||||
public sealed class TunnelWanPortProtocolInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议
|
||||
/// </summary>
|
||||
public TunnelWanPortProtocolType ProtocolType { get; set; } = TunnelWanPortProtocolType.Udp;
|
||||
/// <summary>
|
||||
/// 对方id
|
||||
/// </summary>
|
||||
public string MachineId { get; set; }
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.connection;
|
||||
using linker.tunnel.connection;
|
||||
using linker.tunnel.wanport;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace linker.tunnel.transport
|
||||
{
|
||||
@@ -62,7 +62,7 @@ namespace linker.tunnel.transport
|
||||
/// </summary>
|
||||
public Action<ITunnelConnection> OnConnected { get; set; }
|
||||
|
||||
public void SetAdapter(ITunnelAdapter tunnelAdapter);
|
||||
public void SetSSL(X509Certificate2 certificate);
|
||||
|
||||
/// <summary>
|
||||
/// 连接对方
|
||||
@@ -228,4 +228,32 @@ namespace linker.tunnel.transport
|
||||
}
|
||||
|
||||
|
||||
|
||||
public sealed class NetworkInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 本机局域网IP列表,可以通过NetworkHelper.GetRouteLevel 获取
|
||||
/// </summary>
|
||||
public IPAddress[] LocalIps { get; set; }
|
||||
/// <summary>
|
||||
/// 本机与外网的距离,通过多少网关,可以通过NetworkHelper.GetRouteLevel 获取
|
||||
/// </summary>
|
||||
public int RouteLevel { get; set; }
|
||||
/// <summary>
|
||||
/// 本机名
|
||||
/// </summary>
|
||||
public string MachineId { get; set; }
|
||||
}
|
||||
|
||||
public sealed class TunnelWanPortProtocolInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 协议
|
||||
/// </summary>
|
||||
public TunnelWanPortProtocolType ProtocolType { get; set; } = TunnelWanPortProtocolType.Udp;
|
||||
/// <summary>
|
||||
/// 对方id
|
||||
/// </summary>
|
||||
public string MachineId { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using linker.tunnel.adapter;
|
||||
|
||||
using linker.tunnel.connection;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
@@ -10,6 +10,7 @@ using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Text;
|
||||
using linker.tunnel.wanport;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace linker.tunnel.transport
|
||||
{
|
||||
@@ -46,15 +47,16 @@ namespace linker.tunnel.transport
|
||||
private byte[] endBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.end");
|
||||
private IPEndPoint quicListenEP = null;
|
||||
|
||||
private ITunnelAdapter tunnelAdapter;
|
||||
|
||||
public TransportMsQuic()
|
||||
{
|
||||
_ = QuicListen();
|
||||
}
|
||||
|
||||
public void SetAdapter(ITunnelAdapter tunnelAdapter)
|
||||
private X509Certificate2 certificate;
|
||||
public void SetSSL(X509Certificate2 certificate)
|
||||
{
|
||||
this.tunnelAdapter = tunnelAdapter;
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,7 +74,7 @@ namespace linker.tunnel.transport
|
||||
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
return null;
|
||||
}
|
||||
if (tunnelAdapter.Certificate == null)
|
||||
if (certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Warning($"msquic need ssl");
|
||||
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
@@ -132,7 +134,7 @@ namespace linker.tunnel.transport
|
||||
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
if (tunnelAdapter.Certificate == null)
|
||||
if (certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Warning($"msquic need ssl");
|
||||
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
@@ -661,7 +663,7 @@ namespace linker.tunnel.transport
|
||||
LoggerHelper.Instance.Warning($"msquic not supported, need win11+,or linux, or try to restart linker");
|
||||
return;
|
||||
}
|
||||
if (tunnelAdapter.Certificate == null)
|
||||
if (certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Warning($"msquic need ssl");
|
||||
return;
|
||||
@@ -683,7 +685,7 @@ namespace linker.tunnel.transport
|
||||
IdleTimeout = TimeSpan.FromMilliseconds(15000),
|
||||
ServerAuthenticationOptions = new SslServerAuthenticationOptions
|
||||
{
|
||||
ServerCertificate = tunnelAdapter.Certificate,
|
||||
ServerCertificate = certificate,
|
||||
EnabledSslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13,
|
||||
ApplicationProtocols = new List<SslApplicationProtocol> { SslApplicationProtocol.Http3 }
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using linker.tunnel.adapter;
|
||||
|
||||
using linker.tunnel.connection;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
@@ -54,13 +54,13 @@ namespace linker.tunnel.transport
|
||||
/// </summary>
|
||||
public Action<ITunnelConnection> OnConnected { get; set; } = (state) => { };
|
||||
|
||||
private ITunnelAdapter tunnelAdapter;
|
||||
public TunnelTransportTcpNutssb()
|
||||
{
|
||||
}
|
||||
public void SetAdapter(ITunnelAdapter tunnelAdapter)
|
||||
private X509Certificate2 certificate;
|
||||
public void SetSSL(X509Certificate2 certificate)
|
||||
{
|
||||
this.tunnelAdapter = tunnelAdapter;
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -114,7 +114,7 @@ namespace linker.tunnel.transport
|
||||
/// <param name="tunnelTransportInfo"></param>
|
||||
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
if (tunnelTransportInfo.SSL && tunnelAdapter.Certificate == null)
|
||||
if (tunnelTransportInfo.SSL && certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"{Name}->ssl Certificate not found");
|
||||
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
@@ -278,7 +278,7 @@ namespace linker.tunnel.transport
|
||||
SslStream sslStream = null;
|
||||
if (_state.SSL)
|
||||
{
|
||||
if (tunnelAdapter.Certificate == null)
|
||||
if (certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found");
|
||||
socket.SafeClose();
|
||||
@@ -286,7 +286,7 @@ namespace linker.tunnel.transport
|
||||
}
|
||||
|
||||
sslStream = new SslStream(new NetworkStream(socket, false), false);
|
||||
await sslStream.AuthenticateAsServerAsync(tunnelAdapter.Certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
|
||||
await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
TunnelConnectionTcp result = new TunnelConnectionTcp
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using linker.tunnel.adapter;
|
||||
|
||||
using linker.tunnel.connection;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
@@ -55,14 +55,14 @@ namespace linker.tunnel.transport
|
||||
private byte[] authBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.ttl");
|
||||
private byte[] endBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.end");
|
||||
|
||||
|
||||
private ITunnelAdapter tunnelAdapter;
|
||||
public TransportTcpP2PNAT()
|
||||
{
|
||||
}
|
||||
public void SetAdapter(ITunnelAdapter tunnelAdapter)
|
||||
|
||||
private X509Certificate2 certificate;
|
||||
public void SetSSL(X509Certificate2 certificate)
|
||||
{
|
||||
this.tunnelAdapter = tunnelAdapter;
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -96,7 +96,7 @@ namespace linker.tunnel.transport
|
||||
/// <param name="tunnelTransportInfo"></param>
|
||||
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
if (tunnelTransportInfo.SSL && tunnelAdapter.Certificate == null)
|
||||
if (tunnelTransportInfo.SSL && certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"{Name}->ssl Certificate not found");
|
||||
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
@@ -217,7 +217,7 @@ namespace linker.tunnel.transport
|
||||
SslStream sslStream = null;
|
||||
if (state.SSL)
|
||||
{
|
||||
if (tunnelAdapter.Certificate == null)
|
||||
if (certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found");
|
||||
socket.SafeClose();
|
||||
@@ -225,7 +225,7 @@ namespace linker.tunnel.transport
|
||||
}
|
||||
|
||||
sslStream = new SslStream(new NetworkStream(socket, false), false);
|
||||
await sslStream.AuthenticateAsServerAsync(tunnelAdapter.Certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
|
||||
await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return new TunnelConnectionTcp
|
||||
|
@@ -6,7 +6,6 @@ using System.Text;
|
||||
using linker.libs.extends;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.libs;
|
||||
using linker.tunnel.adapter;
|
||||
using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Security.Authentication;
|
||||
@@ -44,13 +43,14 @@ namespace linker.tunnel.transport
|
||||
|
||||
|
||||
private readonly ConcurrentDictionary<string, TaskCompletionSource<Socket>> distDic = new ConcurrentDictionary<string, TaskCompletionSource<Socket>>();
|
||||
private ITunnelAdapter tunnelAdapter;
|
||||
|
||||
public TransportTcpPortMap()
|
||||
{
|
||||
}
|
||||
public void SetAdapter(ITunnelAdapter tunnelAdapter)
|
||||
private X509Certificate2 certificate;
|
||||
public void SetSSL(X509Certificate2 certificate)
|
||||
{
|
||||
this.tunnelAdapter = tunnelAdapter;
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ namespace linker.tunnel.transport
|
||||
}
|
||||
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
if (tunnelTransportInfo.SSL && tunnelAdapter.Certificate == null)
|
||||
if (tunnelTransportInfo.SSL && certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"{Name}->ssl Certificate not found");
|
||||
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
@@ -246,7 +246,7 @@ namespace linker.tunnel.transport
|
||||
SslStream sslStream = null;
|
||||
if (tunnelTransportInfo.SSL)
|
||||
{
|
||||
if (tunnelAdapter.Certificate == null)
|
||||
if (certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found");
|
||||
socket.SafeClose();
|
||||
@@ -254,7 +254,7 @@ namespace linker.tunnel.transport
|
||||
}
|
||||
|
||||
sslStream = new SslStream(new NetworkStream(socket, false), false);
|
||||
await sslStream.AuthenticateAsServerAsync(tunnelAdapter.Certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
|
||||
await sslStream.AuthenticateAsServerAsync(certificate, false, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
TunnelConnectionTcp result = new TunnelConnectionTcp
|
||||
|
@@ -6,7 +6,7 @@ using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using linker.tunnel.wanport;
|
||||
using linker.tunnel.adapter;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace linker.tunnel.transport
|
||||
{
|
||||
@@ -53,7 +53,7 @@ namespace linker.tunnel.transport
|
||||
public TransportUdp()
|
||||
{
|
||||
}
|
||||
public void SetAdapter(ITunnelAdapter tunnelAdapter)
|
||||
public void SetSSL(X509Certificate2 certificate)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -6,7 +6,7 @@ using System.Text;
|
||||
using linker.libs.extends;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.libs;
|
||||
using linker.tunnel.adapter;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace linker.tunnel.transport
|
||||
{
|
||||
@@ -46,14 +46,15 @@ namespace linker.tunnel.transport
|
||||
|
||||
private readonly ConcurrentDictionary<string, TaskCompletionSource<State>> distDic = new ConcurrentDictionary<string, TaskCompletionSource<State>>();
|
||||
private readonly ConcurrentDictionary<IPEndPoint, ConnectionCacheInfo> connectionsDic = new ConcurrentDictionary<IPEndPoint, ConnectionCacheInfo>(new IPEndPointComparer());
|
||||
private ITunnelAdapter tunnelAdapter;
|
||||
|
||||
public TransportUdpPortMap()
|
||||
{
|
||||
CleanTask();
|
||||
}
|
||||
public void SetAdapter(ITunnelAdapter tunnelAdapter)
|
||||
private X509Certificate2 certificate;
|
||||
public void SetSSL(X509Certificate2 certificate)
|
||||
{
|
||||
this.tunnelAdapter = tunnelAdapter;
|
||||
this.certificate = certificate;
|
||||
}
|
||||
|
||||
Socket socket;
|
||||
@@ -197,7 +198,7 @@ namespace linker.tunnel.transport
|
||||
}
|
||||
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo)
|
||||
{
|
||||
if (tunnelTransportInfo.SSL && tunnelAdapter.Certificate == null)
|
||||
if (tunnelTransportInfo.SSL && certificate == null)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"{Name}->ssl Certificate not found");
|
||||
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using linker.libs;
|
||||
using linker.tunnel.adapter;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.tunnel.wanport
|
||||
@@ -13,14 +12,10 @@ namespace linker.tunnel.wanport
|
||||
|
||||
public List<TunnelWanPortProtocolType> Protocols => tunnelWanPorts.Select(p => p.ProtocolType).ToList();
|
||||
|
||||
private readonly ITunnelAdapter tunnelAdapter;
|
||||
public TunnelWanPortTransfer(ITunnelAdapter tunnelAdapter)
|
||||
public TunnelWanPortTransfer()
|
||||
{
|
||||
this.tunnelAdapter = tunnelAdapter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加载所有外网端口协议
|
||||
/// </summary>
|
||||
@@ -37,14 +32,13 @@ namespace linker.tunnel.wanport
|
||||
/// </summary>
|
||||
/// <param name="localIP">你的局域网IP</param>
|
||||
/// <returns></returns>
|
||||
public async Task<TunnelWanPortEndPoint> GetWanPortAsync(IPAddress localIP, TunnelWanPortProtocolType protocolType)
|
||||
public async Task<TunnelWanPortEndPoint> GetWanPortAsync(IPEndPoint server,IPAddress localIP, TunnelWanPortProtocolType protocolType)
|
||||
{
|
||||
var tunnelWanPort = tunnelWanPorts.FirstOrDefault(c => c.ProtocolType == protocolType);
|
||||
if (tunnelWanPort == null) return null;
|
||||
try
|
||||
{
|
||||
if (tunnelAdapter.ServerHost == null) return null;
|
||||
TunnelWanPortEndPoint wanPort = await tunnelWanPort.GetAsync(localIP, tunnelAdapter.ServerHost).ConfigureAwait(false);
|
||||
TunnelWanPortEndPoint wanPort = await tunnelWanPort.GetAsync(localIP, server).ConfigureAwait(false);
|
||||
if (wanPort != null)
|
||||
{
|
||||
wanPort.Local.Address = localIP;
|
||||
|
@@ -146,7 +146,6 @@ namespace linker.config
|
||||
public IConfig PropertyMethod { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public interface IConfig
|
||||
{
|
||||
public string Serialize(object obj);
|
||||
@@ -217,7 +216,6 @@ namespace linker.config
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class JsonAotAttribute : Attribute { }
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@ namespace linker.plugins.relay.client
|
||||
/// </summary>
|
||||
public sealed class RelayTestTransfer
|
||||
{
|
||||
private readonly FileConfig fileConfig;
|
||||
private readonly RelayTransfer relayTransfer;
|
||||
private readonly ClientSignInState clientSignInState;
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
@@ -20,9 +19,8 @@ namespace linker.plugins.relay.client
|
||||
|
||||
public List<RelayNodeReportInfo> Nodes { get; private set; } = new List<RelayNodeReportInfo>();
|
||||
|
||||
public RelayTestTransfer(FileConfig fileConfig, RelayTransfer relayTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
|
||||
public RelayTestTransfer( RelayTransfer relayTransfer, ClientSignInState clientSignInState, ClientConfigTransfer clientConfigTransfer, RelayClientConfigTransfer relayClientConfigTransfer)
|
||||
{
|
||||
this.fileConfig = fileConfig;
|
||||
this.relayTransfer = relayTransfer;
|
||||
this.clientSignInState = clientSignInState;
|
||||
this.clientConfigTransfer = clientConfigTransfer;
|
||||
|
@@ -54,17 +54,6 @@ namespace linker.plugins.socks5
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
LoggerHelper.Instance.Error(ex);
|
||||
}
|
||||
/*
|
||||
bool online = await clientSignInTransfer.GetOnline(connection.RemoteMachineId);
|
||||
if (online == false)
|
||||
{
|
||||
foreach (var item in ip2MachineDic.Where(c => c.Value == connection.RemoteMachineId).Select(c => c.Key).ToList())
|
||||
{
|
||||
ip2MachineDic.TryRemove(item, out string str);
|
||||
}
|
||||
RefreshConfig();
|
||||
}
|
||||
*/
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
/// <summary>
|
||||
|
@@ -1,46 +1,73 @@
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.plugins.tunnel.messenger;
|
||||
using linker.tunnel.adapter;
|
||||
using linker.plugins.tunnel.messenger;
|
||||
using linker.tunnel.transport;
|
||||
using linker.libs;
|
||||
using MemoryPack;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.tunnel.excludeip;
|
||||
using linker.tunnel.wanport;
|
||||
using linker.tunnel;
|
||||
|
||||
namespace linker.plugins.tunnel
|
||||
{
|
||||
public sealed class TunnelAdapter : ITunnelAdapter
|
||||
public sealed class TunnelAdapter
|
||||
{
|
||||
public IPAddress LocalIP => clientSignInState.Connection?.LocalAddress.Address ?? IPAddress.Any;
|
||||
public IPEndPoint ServerHost => clientSignInState.Connection?.Address ?? null;
|
||||
public X509Certificate2 Certificate => tunnelConfigTransfer.Certificate;
|
||||
|
||||
private readonly ClientSignInState clientSignInState;
|
||||
private readonly IMessengerSender messengerSender;
|
||||
|
||||
private readonly TunnelExcludeIPTransfer excludeIPTransfer;
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
private readonly TunnelConfigTransfer tunnelConfigTransfer;
|
||||
|
||||
public TunnelAdapter(ClientSignInState clientSignInState, IMessengerSender messengerSender, TunnelExcludeIPTransfer excludeIPTransfer, ClientConfigTransfer clientConfigTransfer, TunnelConfigTransfer tunnelConfigTransfer)
|
||||
private readonly TunnelWanPortTransfer tunnelWanPortTransfer;
|
||||
private readonly TunnelUpnpTransfer tunnelUpnpTransfer;
|
||||
private readonly TunnelTransfer tunnelTransfer;
|
||||
|
||||
public TunnelAdapter(ClientSignInState clientSignInState, IMessengerSender messengerSender,
|
||||
TunnelExcludeIPTransfer excludeIPTransfer, ClientConfigTransfer clientConfigTransfer, TunnelConfigTransfer tunnelConfigTransfer,
|
||||
TunnelWanPortTransfer tunnelWanPortTransfer, TunnelUpnpTransfer tunnelUpnpTransfer, TunnelTransfer tunnelTransfer)
|
||||
{
|
||||
this.clientSignInState = clientSignInState;
|
||||
this.messengerSender = messengerSender;
|
||||
this.excludeIPTransfer = excludeIPTransfer;
|
||||
this.clientConfigTransfer = clientConfigTransfer;
|
||||
this.tunnelConfigTransfer = tunnelConfigTransfer;
|
||||
}
|
||||
|
||||
public List<TunnelTransportItemInfo> GetTunnelTransports()
|
||||
{
|
||||
return tunnelConfigTransfer.Transports;
|
||||
}
|
||||
public void SetTunnelTransports(List<TunnelTransportItemInfo> transports, bool updateVersion)
|
||||
{
|
||||
tunnelConfigTransfer.SetTransports(transports);
|
||||
this.tunnelWanPortTransfer = tunnelWanPortTransfer;
|
||||
this.tunnelUpnpTransfer = tunnelUpnpTransfer;
|
||||
this.tunnelTransfer = tunnelTransfer;
|
||||
|
||||
tunnelWanPortTransfer.LoadTransports(new List<ITunnelWanPortProtocol>
|
||||
{
|
||||
new TunnelWanPortProtocolLinkerUdp(),
|
||||
new TunnelWanPortProtocolLinkerTcp(),
|
||||
});
|
||||
|
||||
tunnelTransfer.LocalIP = () => clientSignInState.Connection?.LocalAddress.Address ?? IPAddress.Any;
|
||||
tunnelTransfer.ServerHost = () => clientSignInState.Connection?.Address ?? null;
|
||||
tunnelTransfer.Certificate = () => tunnelConfigTransfer.Certificate;
|
||||
tunnelTransfer.GetTunnelTransports = () => tunnelConfigTransfer.Transports;
|
||||
tunnelTransfer.SetTunnelTransports = (transports,update) => tunnelConfigTransfer.SetTransports(transports);
|
||||
tunnelTransfer.GetLocalConfig = GetLocalConfig;
|
||||
tunnelTransfer.GetRemoteWanPort = GetRemoteWanPort;
|
||||
tunnelTransfer.SendConnectBegin = SendConnectBegin;
|
||||
tunnelTransfer.SendConnectFail = SendConnectFail;
|
||||
tunnelTransfer.SendConnectSuccess = SendConnectSuccess;
|
||||
tunnelTransfer.LoadTransports(tunnelWanPortTransfer, tunnelUpnpTransfer, new List<ITunnelTransport> {
|
||||
new TunnelTransportTcpNutssb(),
|
||||
new TransportMsQuic(),
|
||||
new TransportTcpP2PNAT(),
|
||||
new TransportTcpPortMap(),
|
||||
new TransportUdpPortMap(),
|
||||
new TransportUdp(),
|
||||
});
|
||||
|
||||
clientSignInState.NetworkEnabledHandle += (times) =>
|
||||
{
|
||||
RefreshPortMap();
|
||||
};
|
||||
tunnelConfigTransfer.OnChanged += RefreshPortMap;
|
||||
}
|
||||
|
||||
public NetworkInfo GetLocalConfig()
|
||||
@@ -70,6 +97,7 @@ namespace linker.plugins.tunnel
|
||||
MachineId = clientConfigTransfer.Id
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<TunnelTransportWanPortInfo> GetRemoteWanPort(TunnelWanPortProtocolInfo info)
|
||||
{
|
||||
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||
@@ -118,5 +146,17 @@ namespace linker.plugins.tunnel
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void RefreshPortMap()
|
||||
{
|
||||
if (tunnelConfigTransfer.PortMapLan > 0)
|
||||
{
|
||||
tunnelUpnpTransfer.SetMap(tunnelConfigTransfer.PortMapLan, tunnelConfigTransfer.PortMapWan);
|
||||
}
|
||||
else
|
||||
{
|
||||
tunnelUpnpTransfer.SetMap(clientSignInState.Connection.LocalAddress.Address, 18180);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,5 @@
|
||||
using linker.config;
|
||||
using linker.plugins.tunnel.messenger;
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.transport;
|
||||
using linker.libs.api;
|
||||
using linker.libs.extends;
|
||||
@@ -20,27 +19,23 @@ namespace linker.plugins.tunnel
|
||||
/// </summary>
|
||||
public sealed class TunnelApiController : IApiClientController
|
||||
{
|
||||
private readonly FileConfig config;
|
||||
private readonly TunnelWanPortTransfer compactTransfer;
|
||||
private readonly ClientSignInState clientSignInState;
|
||||
private readonly IMessengerSender messengerSender;
|
||||
private readonly TunnelConfigTransfer tunnelConfigTransfer;
|
||||
private readonly ITunnelAdapter tunnelMessengerAdapter;
|
||||
private readonly TunnelExcludeIPTransfer excludeIPTransfer;
|
||||
private readonly AccessTransfer accessTransfer;
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
private readonly TunnelDecenter tunnelDecenter;
|
||||
|
||||
public TunnelApiController(FileConfig config, TunnelWanPortTransfer compactTransfer, ClientSignInState clientSignInState, IMessengerSender messengerSender, TunnelConfigTransfer tunnelConfigTransfer, ITunnelAdapter tunnelMessengerAdapter, TunnelExcludeIPTransfer excludeIPTransfer, AccessTransfer accessTransfer, ClientConfigTransfer clientConfigTransfer)
|
||||
public TunnelApiController(ClientSignInState clientSignInState, IMessengerSender messengerSender, TunnelConfigTransfer tunnelConfigTransfer, TunnelExcludeIPTransfer excludeIPTransfer, AccessTransfer accessTransfer, ClientConfigTransfer clientConfigTransfer, TunnelDecenter tunnelDecenter)
|
||||
{
|
||||
this.config = config;
|
||||
this.compactTransfer = compactTransfer;
|
||||
this.clientSignInState = clientSignInState;
|
||||
this.messengerSender = messengerSender;
|
||||
this.tunnelConfigTransfer = tunnelConfigTransfer;
|
||||
this.tunnelMessengerAdapter = tunnelMessengerAdapter;
|
||||
this.excludeIPTransfer = excludeIPTransfer;
|
||||
this.accessTransfer = accessTransfer;
|
||||
this.clientConfigTransfer = clientConfigTransfer;
|
||||
this.tunnelDecenter = tunnelDecenter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -51,11 +46,11 @@ namespace linker.plugins.tunnel
|
||||
public TunnelListInfo Get(ApiControllerParamsInfo param)
|
||||
{
|
||||
ulong hashCode = ulong.Parse(param.Content);
|
||||
if (tunnelConfigTransfer.Version.Eq(hashCode, out ulong version) == false)
|
||||
if (tunnelDecenter.Version.Eq(hashCode, out ulong version) == false)
|
||||
{
|
||||
return new TunnelListInfo
|
||||
{
|
||||
List = tunnelConfigTransfer.Config,
|
||||
List = tunnelDecenter.Config,
|
||||
HashCode = version
|
||||
};
|
||||
}
|
||||
@@ -67,7 +62,7 @@ namespace linker.plugins.tunnel
|
||||
/// <param name="param"></param>
|
||||
public void Refresh(ApiControllerParamsInfo param)
|
||||
{
|
||||
tunnelConfigTransfer.RefreshConfig();
|
||||
tunnelDecenter.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -105,7 +100,7 @@ namespace linker.plugins.tunnel
|
||||
/// <returns></returns>
|
||||
public List<TunnelTransportItemInfo> GetTransports(ApiControllerParamsInfo param)
|
||||
{
|
||||
return tunnelMessengerAdapter.GetTunnelTransports();
|
||||
return tunnelConfigTransfer.Transports;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置打洞协议
|
||||
@@ -116,7 +111,7 @@ namespace linker.plugins.tunnel
|
||||
public bool SetTransports(ApiControllerParamsInfo param)
|
||||
{
|
||||
List<TunnelTransportItemInfo> info = param.Content.DeJson<List<TunnelTransportItemInfo>>();
|
||||
tunnelMessengerAdapter.SetTunnelTransports(info, true);
|
||||
tunnelConfigTransfer.SetTransports(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using linker.config;
|
||||
using linker.libs;
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.plugins.client;
|
||||
using linker.tunnel;
|
||||
@@ -7,7 +6,6 @@ using linker.tunnel.connection;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.plugins.relay.client;
|
||||
using linker.plugins.pcp;
|
||||
using linker.client.config;
|
||||
|
||||
namespace linker.plugins.tunnel
|
||||
{
|
||||
|
@@ -2,26 +2,22 @@
|
||||
using linker.config;
|
||||
using linker.libs;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.decenter;
|
||||
using linker.plugins.messenger;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.transport;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using System.Net.Quic;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
namespace linker.plugins.tunnel
|
||||
{
|
||||
public sealed class TunnelConfigTransfer : IDecenter
|
||||
public sealed class TunnelConfigTransfer
|
||||
{
|
||||
public string Name => "tunnel";
|
||||
public VersionManager DataVersion { get; } = new VersionManager();
|
||||
|
||||
public int RouteLevel => config.Data.Client.Tunnel.RouteLevel + running.Data.Tunnel.RouteLevelPlus;
|
||||
public IPAddress[] LocalIPs => config.Data.Client.Tunnel.LocalIPs;
|
||||
public IPAddress[] RouteIPs => config.Data.Client.Tunnel.RouteIPs;
|
||||
public int PortMapLan => running.Data.Tunnel.PortMapLan;
|
||||
public int PortMapWan => running.Data.Tunnel.PortMapWan;
|
||||
public List<TunnelTransportItemInfo> Transports => config.Data.Client.Tunnel.Transports;
|
||||
public X509Certificate2 Certificate { get; private set; }
|
||||
|
||||
@@ -32,8 +28,7 @@ namespace linker.plugins.tunnel
|
||||
private readonly TunnelUpnpTransfer upnpTransfer;
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
|
||||
public VersionManager Version { get; } = new VersionManager();
|
||||
public ConcurrentDictionary<string, TunnelTransportRouteLevelInfo> Config { get; } = new ConcurrentDictionary<string, TunnelTransportRouteLevelInfo>();
|
||||
public Action OnChanged { get; set; } = () => { };
|
||||
|
||||
public TunnelConfigTransfer(FileConfig config, RunningConfig running, ClientSignInState clientSignInState, IMessengerSender messengerSender, TunnelUpnpTransfer upnpTransfer, ClientConfigTransfer clientConfigTransfer)
|
||||
{
|
||||
@@ -52,36 +47,10 @@ namespace linker.plugins.tunnel
|
||||
clientSignInState.NetworkEnabledHandle += (times) =>
|
||||
{
|
||||
TimerHelper.Async(RefreshRouteLevel);
|
||||
RefreshPortMap();
|
||||
};
|
||||
TestQuic();
|
||||
}
|
||||
|
||||
public Memory<byte> GetData()
|
||||
{
|
||||
TunnelTransportRouteLevelInfo tunnelTransportRouteLevelInfo = GetLocalRouteLevel();
|
||||
Config.AddOrUpdate(tunnelTransportRouteLevelInfo.MachineId, tunnelTransportRouteLevelInfo, (a, b) => tunnelTransportRouteLevelInfo);
|
||||
Version.Add();
|
||||
return MemoryPackSerializer.Serialize(tunnelTransportRouteLevelInfo);
|
||||
}
|
||||
public void SetData(Memory<byte> data)
|
||||
{
|
||||
TunnelTransportRouteLevelInfo tunnelTransportRouteLevelInfo = MemoryPackSerializer.Deserialize<TunnelTransportRouteLevelInfo>(data.Span);
|
||||
Config.AddOrUpdate(tunnelTransportRouteLevelInfo.MachineId, tunnelTransportRouteLevelInfo, (a, b) => tunnelTransportRouteLevelInfo);
|
||||
Version.Add();
|
||||
}
|
||||
public void SetData(List<ReadOnlyMemory<byte>> data)
|
||||
{
|
||||
List<TunnelTransportRouteLevelInfo> list = data.Select(c => MemoryPackSerializer.Deserialize<TunnelTransportRouteLevelInfo>(c.Span)).ToList();
|
||||
foreach (var item in list)
|
||||
{
|
||||
Config.AddOrUpdate(item.MachineId, item, (a, b) => item);
|
||||
}
|
||||
TunnelTransportRouteLevelInfo config = GetLocalRouteLevel();
|
||||
Config.AddOrUpdate(config.MachineId, config, (a, b) => config);
|
||||
Version.Add();
|
||||
}
|
||||
|
||||
public void SetTransports(List<TunnelTransportItemInfo> transports)
|
||||
{
|
||||
config.Data.Client.Tunnel.Transports = transports;
|
||||
@@ -96,16 +65,9 @@ namespace linker.plugins.tunnel
|
||||
config.Data.Client.Tunnel.RouteLevel = NetworkHelper.GetRouteLevel(clientConfigTransfer.Server.Host, out List<IPAddress> ips);
|
||||
config.Data.Client.Tunnel.RouteIPs = ips.ToArray();
|
||||
config.Data.Client.Tunnel.LocalIPs = NetworkHelper.GetIPV6().Concat(NetworkHelper.GetIPV4()).ToArray();
|
||||
DataVersion.Add();
|
||||
OnChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新关于隧道的配置信息,也就是获取自己的和别的客户端的,方便查看
|
||||
/// </summary>
|
||||
public void RefreshConfig()
|
||||
{
|
||||
DataVersion.Add();
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改自己的网关层级信息
|
||||
/// </summary>
|
||||
@@ -116,10 +78,9 @@ namespace linker.plugins.tunnel
|
||||
running.Data.Tunnel.PortMapWan = tunnelTransportFileConfigInfo.PortMapWan;
|
||||
running.Data.Tunnel.PortMapLan = tunnelTransportFileConfigInfo.PortMapLan;
|
||||
running.Data.Update();
|
||||
GetData();
|
||||
DataVersion.Add();
|
||||
OnChanged();
|
||||
}
|
||||
private TunnelTransportRouteLevelInfo GetLocalRouteLevel()
|
||||
public TunnelTransportRouteLevelInfo GetLocalRouteLevel()
|
||||
{
|
||||
return new TunnelTransportRouteLevelInfo
|
||||
{
|
||||
@@ -172,16 +133,6 @@ namespace linker.plugins.tunnel
|
||||
}
|
||||
}
|
||||
}
|
||||
private void RefreshPortMap()
|
||||
{
|
||||
if (running.Data.Tunnel.PortMapLan > 0)
|
||||
{
|
||||
upnpTransfer.SetMap(running.Data.Tunnel.PortMapLan, running.Data.Tunnel.PortMapWan);
|
||||
}
|
||||
else
|
||||
{
|
||||
upnpTransfer.SetMap(clientSignInState.Connection.LocalAddress.Address, 18180);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
55
linker/plugins/tunnel/TunnelDecenter.cs
Normal file
55
linker/plugins/tunnel/TunnelDecenter.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using linker.config;
|
||||
using linker.libs;
|
||||
using linker.plugins.decenter;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
namespace linker.plugins.tunnel
|
||||
{
|
||||
public sealed class TunnelDecenter:IDecenter
|
||||
{
|
||||
public string Name => "tunnel";
|
||||
public VersionManager DataVersion { get; } = new VersionManager();
|
||||
|
||||
public VersionManager Version { get; } = new VersionManager();
|
||||
public ConcurrentDictionary<string, TunnelTransportRouteLevelInfo> Config { get; } = new ConcurrentDictionary<string, TunnelTransportRouteLevelInfo>();
|
||||
|
||||
private readonly TunnelConfigTransfer tunnelConfigTransfer;
|
||||
public TunnelDecenter(TunnelConfigTransfer tunnelConfigTransfer)
|
||||
{
|
||||
this.tunnelConfigTransfer = tunnelConfigTransfer;
|
||||
tunnelConfigTransfer.OnChanged += Refresh;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新关于隧道的配置信息,也就是获取自己的和别的客户端的,方便查看
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
DataVersion.Add();
|
||||
}
|
||||
public Memory<byte> GetData()
|
||||
{
|
||||
TunnelTransportRouteLevelInfo tunnelTransportRouteLevelInfo = tunnelConfigTransfer.GetLocalRouteLevel();
|
||||
Config.AddOrUpdate(tunnelTransportRouteLevelInfo.MachineId, tunnelTransportRouteLevelInfo, (a, b) => tunnelTransportRouteLevelInfo);
|
||||
Version.Add();
|
||||
return MemoryPackSerializer.Serialize(tunnelTransportRouteLevelInfo);
|
||||
}
|
||||
public void SetData(Memory<byte> data)
|
||||
{
|
||||
TunnelTransportRouteLevelInfo tunnelTransportRouteLevelInfo = MemoryPackSerializer.Deserialize<TunnelTransportRouteLevelInfo>(data.Span);
|
||||
Config.AddOrUpdate(tunnelTransportRouteLevelInfo.MachineId, tunnelTransportRouteLevelInfo, (a, b) => tunnelTransportRouteLevelInfo);
|
||||
Version.Add();
|
||||
}
|
||||
public void SetData(List<ReadOnlyMemory<byte>> data)
|
||||
{
|
||||
List<TunnelTransportRouteLevelInfo> list = data.Select(c => MemoryPackSerializer.Deserialize<TunnelTransportRouteLevelInfo>(c.Span)).ToList();
|
||||
foreach (var item in list)
|
||||
{
|
||||
Config.AddOrUpdate(item.MachineId, item, (a, b) => item);
|
||||
}
|
||||
TunnelTransportRouteLevelInfo config = tunnelConfigTransfer.GetLocalRouteLevel();
|
||||
Config.AddOrUpdate(config.MachineId, config, (a, b) => config);
|
||||
Version.Add();
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,12 +2,9 @@
|
||||
using linker.plugins.tunnel.messenger;
|
||||
using linker.startup;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.transport;
|
||||
using linker.libs;
|
||||
using MemoryPack;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Net;
|
||||
using linker.tunnel.wanport;
|
||||
using linker.plugins.tunnel.excludeip;
|
||||
using linker.plugins.client;
|
||||
@@ -36,7 +33,6 @@ namespace linker.plugins.tunnel
|
||||
MemoryPackFormatterProvider.Register(new TunnelTransportInfoFormatter());
|
||||
MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter());
|
||||
|
||||
|
||||
//管理接口
|
||||
serviceCollection.AddSingleton<TunnelApiController>();
|
||||
//命令接口
|
||||
@@ -44,30 +40,18 @@ namespace linker.plugins.tunnel
|
||||
|
||||
//外网端口协议
|
||||
serviceCollection.AddSingleton<TunnelWanPortTransfer>();
|
||||
serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerUdp>();
|
||||
serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerTcp>();
|
||||
|
||||
|
||||
//打洞协议
|
||||
serviceCollection.AddSingleton<TunnelTransfer>();
|
||||
serviceCollection.AddSingleton<TunnelTransportTcpNutssb>();
|
||||
serviceCollection.AddSingleton<TransportMsQuic>();
|
||||
serviceCollection.AddSingleton<TransportTcpP2PNAT>();
|
||||
serviceCollection.AddSingleton<TransportTcpPortMap>();
|
||||
serviceCollection.AddSingleton<TransportUdpPortMap>();
|
||||
serviceCollection.AddSingleton<TransportUdp>();
|
||||
serviceCollection.AddSingleton<TunnelUpnpTransfer>();
|
||||
|
||||
|
||||
serviceCollection.AddSingleton<TunnelExcludeIPTransfer>();
|
||||
serviceCollection.AddSingleton<TunnelExcludeIPTypesLoader>();
|
||||
serviceCollection.AddSingleton<TunnelConfigTransfer>();
|
||||
serviceCollection.AddSingleton<ITunnelAdapter, TunnelAdapter>();
|
||||
|
||||
serviceCollection.AddSingleton<TunnelUpnpTransfer>();
|
||||
|
||||
serviceCollection.AddSingleton<TunnelConfigSyncTransports>();
|
||||
serviceCollection.AddSingleton<TunnelDecenter>();
|
||||
|
||||
serviceCollection.AddSingleton<TunnelConfigTransfer>();
|
||||
serviceCollection.AddSingleton<TunnelAdapter>();
|
||||
}
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, FileConfig config)
|
||||
@@ -83,36 +67,14 @@ namespace linker.plugins.tunnel
|
||||
|
||||
public void UseClient(ServiceProvider serviceProvider, FileConfig config)
|
||||
{
|
||||
ITunnelAdapter tunnelAdapter = serviceProvider.GetService<ITunnelAdapter>();
|
||||
TunnelUpnpTransfer upnpTransfer = serviceProvider.GetService<TunnelUpnpTransfer>();
|
||||
|
||||
IEnumerable<Type> types = new List<Type> {
|
||||
typeof(TunnelWanPortProtocolLinkerUdp),
|
||||
typeof(TunnelWanPortProtocolLinkerTcp)
|
||||
};
|
||||
List<ITunnelWanPortProtocol> compacts = types.Select(c => (ITunnelWanPortProtocol)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Name) == false).ToList();
|
||||
TunnelWanPortTransfer compack = serviceProvider.GetService<TunnelWanPortTransfer>();
|
||||
compack.LoadTransports(compacts);
|
||||
|
||||
|
||||
types = new List<Type> {
|
||||
typeof(TunnelTransportTcpNutssb),
|
||||
typeof(TransportMsQuic),
|
||||
typeof(TransportTcpP2PNAT),
|
||||
typeof(TransportTcpPortMap),
|
||||
typeof(TransportUdpPortMap),
|
||||
typeof(TransportUdp),
|
||||
};
|
||||
List<ITunnelTransport> transports = types.Select(c => (ITunnelTransport)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Name) == false).ToList();
|
||||
TunnelTransfer tunnel = serviceProvider.GetService<TunnelTransfer>();
|
||||
tunnel.LoadTransports(compack, tunnelAdapter, upnpTransfer, transports);
|
||||
|
||||
TunnelExcludeIPTransfer excludeIPTransfer = serviceProvider.GetService<TunnelExcludeIPTransfer>();
|
||||
TunnelExcludeIPTypesLoader tunnelExcludeIPTypesLoader = serviceProvider.GetService<TunnelExcludeIPTypesLoader>();
|
||||
|
||||
ClientConfigTransfer clientConfigTransfer = serviceProvider.GetService<ClientConfigTransfer>();
|
||||
TunnelConfigTransfer tunnelConfigTransfer = serviceProvider.GetService<TunnelConfigTransfer>();
|
||||
|
||||
TunnelAdapter tunnelAdapter = serviceProvider.GetService<TunnelAdapter>();
|
||||
|
||||
LoggerHelper.Instance.Info($"tunnel route level getting.");
|
||||
tunnelConfigTransfer.RefreshRouteLevel();
|
||||
LoggerHelper.Instance.Warning($"route ips:{string.Join(",", tunnelConfigTransfer.RouteIPs.Select(c => c.ToString()))}");
|
||||
|
@@ -5,7 +5,6 @@ using LiteDB;
|
||||
using MemoryPack;
|
||||
using System.Net;
|
||||
using System.Text.Json.Serialization;
|
||||
using linker.tunnel.adapter;
|
||||
|
||||
|
||||
namespace linker.client.config
|
||||
|
@@ -1,8 +1,6 @@
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.libs;
|
||||
using linker.plugins.client;
|
||||
using MemoryPack;
|
||||
|
||||
namespace linker.plugins.tunnel.excludeip
|
||||
{
|
||||
|
@@ -1,7 +1,6 @@
|
||||
using linker.config;
|
||||
using linker.plugins.signin.messenger;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.adapter;
|
||||
using linker.tunnel.transport;
|
||||
using linker.libs;
|
||||
using MemoryPack;
|
||||
|
237
linker/plugins/tuntap/TuntapAdapter.cs
Normal file
237
linker/plugins/tuntap/TuntapAdapter.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
using linker.libs;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.tunnel;
|
||||
using linker.plugins.tuntap.config;
|
||||
using linker.tun;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.plugins.tuntap
|
||||
{
|
||||
public sealed class TuntapAdapter : ILinkerTunDeviceCallback
|
||||
{
|
||||
private List<LinkerTunDeviceForwardItem> forwardItems = new List<LinkerTunDeviceForwardItem>();
|
||||
private LinkerTunDeviceRouteItem[] routeItems = new LinkerTunDeviceRouteItem[0];
|
||||
|
||||
private readonly TuntapTransfer tuntapTransfer;
|
||||
private readonly TuntapConfigTransfer tuntapConfigTransfer;
|
||||
private readonly TuntapDecenter tuntapDecenter;
|
||||
private readonly TuntapProxy tuntapProxy;
|
||||
private readonly ClientSignInState clientSignInState;
|
||||
private readonly TunnelConfigTransfer tunnelConfigTransfer;
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
|
||||
public TuntapAdapter(TuntapTransfer tuntapTransfer, TuntapConfigTransfer tuntapConfigTransfer, TuntapDecenter tuntapDecenter, TuntapProxy tuntapProxy,
|
||||
ClientSignInState clientSignInState, TunnelConfigTransfer tunnelConfigTransfer, ClientConfigTransfer clientConfigTransfer)
|
||||
{
|
||||
this.tuntapTransfer = tuntapTransfer;
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
this.tuntapDecenter = tuntapDecenter;
|
||||
this.tuntapProxy = tuntapProxy;
|
||||
this.clientSignInState = clientSignInState;
|
||||
this.tunnelConfigTransfer = tunnelConfigTransfer;
|
||||
this.clientConfigTransfer = clientConfigTransfer;
|
||||
|
||||
//初始化网卡
|
||||
tuntapTransfer.Init(tuntapConfigTransfer.DeviceName, this);
|
||||
//与服务器连接,刷新一下IP
|
||||
clientSignInState.NetworkEnabledHandle += (times) => tuntapConfigTransfer.RefreshIP();
|
||||
//配置又更新,去同步一下
|
||||
tuntapConfigTransfer.OnUpdate += tuntapDecenter.Refresh;
|
||||
//配置发生变化,重启网卡
|
||||
tuntapConfigTransfer.OnChanged += RetstartDevice;
|
||||
|
||||
//收到新的信息,添加一下路由
|
||||
tuntapDecenter.OnChangeBefore += DelRoute;
|
||||
tuntapDecenter.OnChangeAfter += AddRoute;
|
||||
tuntapDecenter.OnReset += tuntapProxy.ClearIPs;
|
||||
tuntapDecenter.HandleCurrentInfo = GetCurrentInfo;
|
||||
|
||||
//网卡状态发生变化,同步一下信息
|
||||
tuntapTransfer.OnSetupBefore += tuntapDecenter.Refresh;
|
||||
tuntapTransfer.OnSetupAfter += tuntapDecenter.Refresh;
|
||||
tuntapTransfer.OnSetupSuccess += () => { tuntapDecenter.Refresh(); AddForward(); tuntapConfigTransfer.SetRunning(true); };
|
||||
tuntapTransfer.OnShutdownBefore += tuntapDecenter.Refresh;
|
||||
tuntapTransfer.OnShutdownAfter += tuntapDecenter.Refresh;
|
||||
tuntapTransfer.OnShutdownSuccess += () => { tuntapDecenter.Refresh(); DeleteForward(); tuntapConfigTransfer.SetRunning(false); };
|
||||
|
||||
//隧道关闭
|
||||
tuntapProxy.OnTunnelClose += async (connection) => { tuntapDecenter.Refresh(); await Task.CompletedTask; };
|
||||
//收到隧道数据包,写入网卡
|
||||
tuntapProxy.OnReceivePacket += async (connection, buffer) => { tuntapTransfer.Write(buffer); await Task.CompletedTask; };
|
||||
//IP没找到,是否需要同步一下数据
|
||||
tuntapProxy.OnIPNotFound += (ip) => tuntapDecenter.Refresh();
|
||||
|
||||
}
|
||||
private TuntapInfo GetCurrentInfo()
|
||||
{
|
||||
return new TuntapInfo
|
||||
{
|
||||
IP = tuntapConfigTransfer.Info.IP,
|
||||
Lans = tuntapConfigTransfer.Info.Lans.Where(c => c.IP != null && c.IP.Equals(IPAddress.Any) == false).Select(c => { c.Exists = false; return c; }).ToList(),
|
||||
PrefixLength = tuntapConfigTransfer.Info.PrefixLength,
|
||||
MachineId = clientConfigTransfer.Id,
|
||||
Status = tuntapTransfer.Status,
|
||||
SetupError = tuntapTransfer.SetupError,
|
||||
NatError = tuntapTransfer.NatError,
|
||||
SystemInfo = $"{System.Runtime.InteropServices.RuntimeInformation.OSDescription} {(string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")) == false ? "Docker" : "")}",
|
||||
|
||||
Forwards = tuntapConfigTransfer.Info.Forwards,
|
||||
Switch = tuntapConfigTransfer.Info.Switch
|
||||
};
|
||||
}
|
||||
|
||||
public async Task Callback(LinkerTunDevicPacket packet)
|
||||
{
|
||||
if (packet.IPV4Broadcast || packet.IPV6Multicast)
|
||||
{
|
||||
if ((tuntapConfigTransfer.Switch & TuntapSwitch.Multicast) == TuntapSwitch.Multicast)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
await tuntapProxy.InputPacket(packet);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 重启网卡
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task RetstartDevice()
|
||||
{
|
||||
tuntapTransfer.Shutdown();
|
||||
await tuntapConfigTransfer.RefreshIPASync();
|
||||
tuntapTransfer.Setup(tuntapConfigTransfer.Info.IP, tuntapConfigTransfer.Info.PrefixLength);
|
||||
}
|
||||
/// <summary>
|
||||
/// 关闭网卡
|
||||
/// </summary>
|
||||
public void StopDevice()
|
||||
{
|
||||
tuntapTransfer.Shutdown();
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// 添加端口转发
|
||||
/// </summary>
|
||||
private void AddForward()
|
||||
{
|
||||
var temp = ParseForwardItems();
|
||||
var removes = forwardItems.Except(temp, new LinkerTunDeviceForwardItemComparer());
|
||||
if (removes.Any())
|
||||
{
|
||||
tuntapTransfer.RemoveForward(removes.ToList());
|
||||
}
|
||||
forwardItems = temp;
|
||||
tuntapTransfer.AddForward(forwardItems);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除端口转发
|
||||
/// </summary>
|
||||
public void DeleteForward()
|
||||
{
|
||||
tuntapTransfer.RemoveForward(forwardItems);
|
||||
}
|
||||
private List<LinkerTunDeviceForwardItem> ParseForwardItems()
|
||||
{
|
||||
return tuntapConfigTransfer.Info.Forwards.Select(c => new LinkerTunDeviceForwardItem { ListenAddr = c.ListenAddr, ListenPort = c.ListenPort, ConnectAddr = c.ConnectAddr, ConnectPort = c.ConnectPort }).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除路由
|
||||
/// </summary>
|
||||
private void DelRoute()
|
||||
{
|
||||
if (routeItems != null)
|
||||
tuntapTransfer.DelRoute(routeItems);
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加路由
|
||||
/// </summary>
|
||||
private void AddRoute()
|
||||
{
|
||||
List<TuntapVeaLanIPAddressList> ipsList = ParseIPs(tuntapDecenter.Infos.Values.ToList());
|
||||
TuntapVeaLanIPAddress[] ips = ipsList.SelectMany(c => c.IPS).ToArray();
|
||||
routeItems = ipsList.SelectMany(c => c.IPS).Select(c => new LinkerTunDeviceRouteItem { Address = c.OriginIPAddress, PrefixLength = c.PrefixLength }).ToArray();
|
||||
|
||||
tuntapTransfer.AddRoute(routeItems, tuntapConfigTransfer.Info.IP);
|
||||
|
||||
tuntapProxy.SetIPs(ips);
|
||||
foreach (var item in tuntapDecenter.Infos.Values)
|
||||
{
|
||||
tuntapProxy.SetIP(item.MachineId, NetworkHelper.IP2Value(item.IP));
|
||||
}
|
||||
foreach (var item in tuntapDecenter.Infos.Values.Where(c => c.IP.Equals(IPAddress.Any)))
|
||||
{
|
||||
tuntapProxy.RemoveIP(item.MachineId);
|
||||
}
|
||||
}
|
||||
|
||||
private List<TuntapVeaLanIPAddressList> ParseIPs(List<TuntapInfo> infos)
|
||||
{
|
||||
//排除的IP,
|
||||
uint[] excludeIps =//本机局域网IP
|
||||
tunnelConfigTransfer.LocalIPs.Where(c => c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
||||
//路由上的IP
|
||||
.Concat(tunnelConfigTransfer.RouteIPs)
|
||||
//网卡IP 服务器IP
|
||||
.Concat(new IPAddress[] { tuntapConfigTransfer.Info.IP, clientSignInState.Connection.Address.Address })
|
||||
//网卡配置的局域网IP
|
||||
.Concat(tuntapConfigTransfer.Info.Lans.Select(c => c.IP))
|
||||
.Select(NetworkHelper.IP2Value)
|
||||
.ToArray();
|
||||
|
||||
HashSet<uint> hashSet = new HashSet<uint>();
|
||||
|
||||
return infos
|
||||
.Where(c => c.MachineId != clientConfigTransfer.Id)
|
||||
.OrderByDescending(c => c.Status)
|
||||
.OrderByDescending(c => c.LastTicks.Value)
|
||||
|
||||
.Select(c =>
|
||||
{
|
||||
var lans = c.Lans.Where(c => c.Disabled == false && c.IP.Equals(IPAddress.Any) == false).Where(c =>
|
||||
{
|
||||
uint ipInt = NetworkHelper.IP2Value(c.IP);
|
||||
uint maskValue = NetworkHelper.PrefixLength2Value(c.PrefixLength);
|
||||
uint network = ipInt & maskValue;
|
||||
c.Exists = excludeIps.Any(d => (d & maskValue) == network) || hashSet.Contains(network);
|
||||
hashSet.Add(network);
|
||||
return c.Exists == false;
|
||||
});
|
||||
|
||||
return new TuntapVeaLanIPAddressList
|
||||
{
|
||||
MachineId = c.MachineId,
|
||||
IPS = ParseIPs(lans.ToList(), c.MachineId)
|
||||
.Where(c => excludeIps.Select(d => d & c.MaskValue).Contains(c.NetWork) == false).ToList(),
|
||||
};
|
||||
}).ToList();
|
||||
}
|
||||
private List<TuntapVeaLanIPAddress> ParseIPs(List<TuntapLanInfo> lans, string machineid)
|
||||
{
|
||||
return lans.Where(c => c.IP.Equals(IPAddress.Any) == false && c != null).Select((c, index) =>
|
||||
{
|
||||
return ParseIPAddress(c.IP, c.PrefixLength, machineid);
|
||||
|
||||
}).ToList();
|
||||
}
|
||||
private TuntapVeaLanIPAddress ParseIPAddress(IPAddress ip, byte prefixLength, string machineid)
|
||||
{
|
||||
uint ipInt = NetworkHelper.IP2Value(ip);
|
||||
//掩码十进制
|
||||
uint maskValue = NetworkHelper.PrefixLength2Value(prefixLength);
|
||||
return new TuntapVeaLanIPAddress
|
||||
{
|
||||
IPAddress = ipInt,
|
||||
PrefixLength = prefixLength,
|
||||
MaskValue = maskValue,
|
||||
NetWork = ipInt & maskValue,
|
||||
Broadcast = ipInt | ~maskValue,
|
||||
OriginIPAddress = ip,
|
||||
MachineId = machineid
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -22,28 +22,30 @@ namespace linker.plugins.tuntap
|
||||
private readonly IMessengerSender messengerSender;
|
||||
private readonly TuntapTransfer tuntapTransfer;
|
||||
private readonly ClientSignInState clientSignInState;
|
||||
private readonly FileConfig config;
|
||||
private readonly TuntapProxy tuntapProxy;
|
||||
private readonly RunningConfig runningConfig;
|
||||
private readonly TuntapConfigTransfer tuntapConfigTransfer;
|
||||
private readonly LeaseClientTreansfer leaseClientTreansfer;
|
||||
private readonly TuntapPingTransfer pingTransfer;
|
||||
private readonly AccessTransfer accessTransfer;
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
private readonly TuntapDecenter tuntapDecenter;
|
||||
private readonly TuntapAdapter tuntapAdapter;
|
||||
|
||||
public TuntapClientApiController(IMessengerSender messengerSender, TuntapTransfer tuntapTransfer, ClientSignInState clientSignInState, FileConfig config, TuntapProxy tuntapProxy, RunningConfig runningConfig, TuntapConfigTransfer tuntapConfigTransfer, LeaseClientTreansfer leaseClientTreansfer, TuntapPingTransfer pingTransfer, AccessTransfer accessTransfer, ClientConfigTransfer clientConfigTransfer)
|
||||
public TuntapClientApiController(IMessengerSender messengerSender, TuntapTransfer tuntapTransfer, ClientSignInState clientSignInState,
|
||||
TuntapProxy tuntapProxy,TuntapConfigTransfer tuntapConfigTransfer, LeaseClientTreansfer leaseClientTreansfer,
|
||||
TuntapPingTransfer pingTransfer, AccessTransfer accessTransfer, ClientConfigTransfer clientConfigTransfer, TuntapDecenter tuntapDecenter, TuntapAdapter tuntapAdapter)
|
||||
{
|
||||
this.messengerSender = messengerSender;
|
||||
this.tuntapTransfer = tuntapTransfer;
|
||||
this.clientSignInState = clientSignInState;
|
||||
this.config = config;
|
||||
this.tuntapProxy = tuntapProxy;
|
||||
this.runningConfig = runningConfig;
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
this.leaseClientTreansfer = leaseClientTreansfer;
|
||||
this.pingTransfer = pingTransfer;
|
||||
this.accessTransfer = accessTransfer;
|
||||
this.clientConfigTransfer = clientConfigTransfer;
|
||||
this.tuntapDecenter = tuntapDecenter;
|
||||
this.tuntapAdapter = tuntapAdapter;
|
||||
}
|
||||
|
||||
public ConnectionListInfo Connections(ApiControllerParamsInfo param)
|
||||
@@ -74,11 +76,11 @@ namespace linker.plugins.tuntap
|
||||
public TuntabListInfo Get(ApiControllerParamsInfo param)
|
||||
{
|
||||
ulong hashCode = ulong.Parse(param.Content);
|
||||
if (tuntapConfigTransfer.Version.Eq(hashCode, out ulong version) == false)
|
||||
if (tuntapDecenter.Version.Eq(hashCode, out ulong version) == false)
|
||||
{
|
||||
return new TuntabListInfo
|
||||
{
|
||||
List = tuntapConfigTransfer.Infos,
|
||||
List = tuntapDecenter.Infos,
|
||||
HashCode = version
|
||||
};
|
||||
}
|
||||
@@ -90,7 +92,7 @@ namespace linker.plugins.tuntap
|
||||
/// <param name="param"></param>
|
||||
public void Refresh(ApiControllerParamsInfo param)
|
||||
{
|
||||
tuntapConfigTransfer.RefreshConfig();
|
||||
tuntapDecenter.Refresh();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -105,7 +107,7 @@ namespace linker.plugins.tuntap
|
||||
{
|
||||
if (accessTransfer.HasAccess(ClientApiAccess.TuntapStatusSelf) == false) return false;
|
||||
|
||||
await tuntapConfigTransfer.RetstartDevice();
|
||||
await tuntapAdapter.RetstartDevice();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -131,7 +133,7 @@ namespace linker.plugins.tuntap
|
||||
if (param.Content == clientConfigTransfer.Id)
|
||||
{
|
||||
if (accessTransfer.HasAccess(ClientApiAccess.TuntapStatusSelf) == false) return false;
|
||||
tuntapConfigTransfer.StopDevice();
|
||||
tuntapAdapter.StopDevice();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -160,7 +162,7 @@ namespace linker.plugins.tuntap
|
||||
if (info.MachineId == clientConfigTransfer.Id)
|
||||
{
|
||||
if (accessTransfer.HasAccess(ClientApiAccess.TuntapChangeSelf) == false) return false;
|
||||
tuntapConfigTransfer.UpdateConfig(info);
|
||||
tuntapConfigTransfer.Update(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -1,413 +1,128 @@
|
||||
using linker.client.config;
|
||||
using linker.config;
|
||||
using linker.libs;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Net;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.messenger;
|
||||
using linker.plugins.tuntap.config;
|
||||
using linker.tun;
|
||||
using linker.plugins.tuntap.lease;
|
||||
using linker.plugins.decenter;
|
||||
using linker.plugins.tunnel;
|
||||
|
||||
namespace linker.plugins.tuntap
|
||||
{
|
||||
public sealed class TuntapConfigTransfer : IDecenter
|
||||
public sealed class TuntapConfigTransfer
|
||||
{
|
||||
public string Name => "tuntap";
|
||||
public VersionManager DataVersion { get; } = new VersionManager();
|
||||
public TuntapConfigInfo Info => runningConfig.Data.Tuntap;
|
||||
public IPAddress IP => Info.IP;
|
||||
public bool Running => Info.Running;
|
||||
public TuntapSwitch Switch => Info.Switch;
|
||||
|
||||
private TuntapConfigInfo configInfo => runningConfig.Data.Tuntap;
|
||||
public IPAddress IP=> configInfo.IP;
|
||||
public bool Running => configInfo.Running;
|
||||
public TuntapSwitch Switch => configInfo.Switch;
|
||||
public string DeviceName => "linker";
|
||||
|
||||
|
||||
private readonly IMessengerSender messengerSender;
|
||||
private readonly ClientSignInState clientSignInState;
|
||||
private readonly RunningConfig runningConfig;
|
||||
private readonly TuntapTransfer tuntapTransfer;
|
||||
private readonly LeaseClientTreansfer leaseClientTreansfer;
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
private readonly TunnelConfigTransfer tunnelConfigTransfer;
|
||||
|
||||
private LinkerTunDeviceRouteItem[] routeItems = new LinkerTunDeviceRouteItem[0];
|
||||
private List<LinkerTunDeviceForwardItem> forwardItems = new List<LinkerTunDeviceForwardItem>();
|
||||
public Action OnUpdate { get; set; } = () => { };
|
||||
public Func<Task> OnChanged { get; set; } = async () => { await Task.CompletedTask; };
|
||||
|
||||
public VersionManager Version { get; } = new VersionManager();
|
||||
private readonly ConcurrentDictionary<string, TuntapInfo> tuntapInfos = new ConcurrentDictionary<string, TuntapInfo>();
|
||||
public ConcurrentDictionary<string, TuntapInfo> Infos => tuntapInfos;
|
||||
|
||||
|
||||
public Action HandleReset { get; set; }
|
||||
public Action<TuntapVeaLanIPAddress[]> HandleSetIPs { get; set; }
|
||||
public Action<string,uint> HandleSetIP { get; set; }
|
||||
public Action<string> HandleRemoveIP { get; set; }
|
||||
|
||||
|
||||
private readonly SemaphoreSlim slim = new SemaphoreSlim(1);
|
||||
public TuntapConfigTransfer(IMessengerSender messengerSender, ClientSignInState clientSignInState, RunningConfig runningConfig, TuntapTransfer tuntapTransfer, LeaseClientTreansfer leaseClientTreansfer, ClientConfigTransfer clientConfigTransfer, TunnelConfigTransfer tunnelConfigTransfer)
|
||||
public TuntapConfigTransfer(RunningConfig runningConfig, LeaseClientTreansfer leaseClientTreansfer, ClientConfigTransfer clientConfigTransfer)
|
||||
{
|
||||
this.messengerSender = messengerSender;
|
||||
this.clientSignInState = clientSignInState;
|
||||
this.runningConfig = runningConfig;
|
||||
this.tuntapTransfer = tuntapTransfer;
|
||||
this.leaseClientTreansfer = leaseClientTreansfer;
|
||||
this.clientConfigTransfer = clientConfigTransfer;
|
||||
this.tunnelConfigTransfer = tunnelConfigTransfer;
|
||||
|
||||
clientSignInState.NetworkEnabledHandle += NetworkEnable;
|
||||
|
||||
tuntapTransfer.OnSetupBefore += () => { DataVersion.Add(); };
|
||||
tuntapTransfer.OnSetupAfter += () => { DataVersion.Add(); };
|
||||
tuntapTransfer.OnSetupSuccess += () => { DataVersion.Add(); configInfo.Running = true; runningConfig.Data.Update(); AddForward(); };
|
||||
|
||||
tuntapTransfer.OnShutdownBefore += () => { DataVersion.Add(); };
|
||||
tuntapTransfer.OnShutdownAfter += () => { DataVersion.Add(); };
|
||||
tuntapTransfer.OnShutdownSuccess += () => { DataVersion.Add(); DeleteForward(); DelRoute(); configInfo.Running = false; runningConfig.Data.Update(); DataVersion.Add(); };
|
||||
|
||||
}
|
||||
|
||||
string groupid = string.Empty;
|
||||
private void NetworkEnable(int times)
|
||||
{
|
||||
if (groupid != clientConfigTransfer.Group.Id)
|
||||
{
|
||||
tuntapInfos.Clear(); HandleReset();
|
||||
}
|
||||
groupid = clientConfigTransfer.Group.Id;
|
||||
|
||||
RefreshIP();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新本机网卡信息
|
||||
/// 保存启动状态,方便下次启动时自动启动网卡
|
||||
/// </summary>
|
||||
/// <param name="running"></param>
|
||||
public void SetRunning(bool running)
|
||||
{
|
||||
Info.Running = running;
|
||||
runningConfig.Data.Update();
|
||||
OnUpdate();
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新本机网卡信息,会触发事件
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
public void UpdateConfig(TuntapInfo info)
|
||||
public void Update(TuntapInfo info)
|
||||
{
|
||||
TimerHelper.Async(async () =>
|
||||
{
|
||||
IPAddress oldIP = configInfo.IP;
|
||||
byte prefixLength = configInfo.PrefixLength;
|
||||
IPAddress ip = Info.IP;
|
||||
byte prefixLength = Info.PrefixLength;
|
||||
|
||||
configInfo.IP = info.IP ?? IPAddress.Any;
|
||||
configInfo.Lans = info.Lans;
|
||||
configInfo.PrefixLength = info.PrefixLength;
|
||||
configInfo.Switch = info.Switch;
|
||||
configInfo.Forwards = info.Forwards;
|
||||
Info.IP = info.IP ?? IPAddress.Any;
|
||||
Info.Lans = info.Lans;
|
||||
Info.PrefixLength = info.PrefixLength;
|
||||
Info.Switch = info.Switch;
|
||||
Info.Forwards = info.Forwards;
|
||||
runningConfig.Data.Update();
|
||||
|
||||
TuntapGroup2IPInfo tuntapGroup2IPInfo = new TuntapGroup2IPInfo { IP = configInfo.IP, PrefixLength = configInfo.PrefixLength };
|
||||
configInfo.Group2IP.AddOrUpdate(clientConfigTransfer.Group.Id, tuntapGroup2IPInfo, (a, b) => tuntapGroup2IPInfo);
|
||||
|
||||
await LeaseIP();
|
||||
SetGroupIP();
|
||||
|
||||
if ((oldIP.Equals(configInfo.IP) == false || prefixLength != configInfo.PrefixLength) && configInfo.Running)
|
||||
if ((ip.Equals(Info.IP) == false || prefixLength != Info.PrefixLength) && Info.Running)
|
||||
{
|
||||
await RetstartDevice();
|
||||
}
|
||||
else
|
||||
{
|
||||
AddForward();
|
||||
await OnChanged();
|
||||
}
|
||||
|
||||
GetData();
|
||||
DataVersion.Add();
|
||||
OnUpdate();
|
||||
});
|
||||
}
|
||||
public Memory<byte> GetData()
|
||||
{
|
||||
TuntapInfo info = new TuntapInfo
|
||||
{
|
||||
IP = configInfo.IP,
|
||||
Lans = configInfo.Lans.Where(c => c.IP != null && c.IP.Equals(IPAddress.Any) == false).Select(c => { c.Exists = false; return c; }).ToList(),
|
||||
PrefixLength = configInfo.PrefixLength,
|
||||
MachineId = clientConfigTransfer.Id,
|
||||
Status = tuntapTransfer.Status,
|
||||
SetupError = tuntapTransfer.SetupError,
|
||||
NatError = tuntapTransfer.NatError,
|
||||
SystemInfo = $"{System.Runtime.InteropServices.RuntimeInformation.OSDescription} {(string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("SNLTTY_LINKER_IS_DOCKER")) == false ? "Docker" : "")}",
|
||||
|
||||
Forwards = configInfo.Forwards,
|
||||
Switch = configInfo.Switch
|
||||
};
|
||||
tuntapInfos.AddOrUpdate(info.MachineId, info, (a, b) => info);
|
||||
Version.Add();
|
||||
return MemoryPackSerializer.Serialize(info);
|
||||
}
|
||||
public void SetData(Memory<byte> data)
|
||||
{
|
||||
TuntapInfo info = MemoryPackSerializer.Deserialize<TuntapInfo>(data.Span);
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Debug($"tuntap got {info.IP}");
|
||||
}
|
||||
|
||||
TimerHelper.Async(async () =>
|
||||
{
|
||||
await slim.WaitAsync();
|
||||
try
|
||||
{
|
||||
DelRoute();
|
||||
tuntapInfos.AddOrUpdate(info.MachineId, info, (a, b) => info);
|
||||
Version.Add();
|
||||
AddRoute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Error(ex);
|
||||
}
|
||||
}
|
||||
slim.Release();
|
||||
});
|
||||
}
|
||||
public void SetData(List<ReadOnlyMemory<byte>> data)
|
||||
{
|
||||
List<TuntapInfo> list = data.Select(c => MemoryPackSerializer.Deserialize<TuntapInfo>(c.Span)).ToList();
|
||||
TimerHelper.Async(async () =>
|
||||
{
|
||||
await slim.WaitAsync();
|
||||
|
||||
try
|
||||
{
|
||||
DelRoute();
|
||||
foreach (var item in list)
|
||||
{
|
||||
tuntapInfos.AddOrUpdate(item.MachineId, item, (a, b) => item);
|
||||
item.LastTicks.Update();
|
||||
}
|
||||
var removes = tuntapInfos.Keys.Except(list.Select(c => c.MachineId)).Where(c => c != clientConfigTransfer.Id).ToList();
|
||||
foreach (var item in removes)
|
||||
{
|
||||
if (tuntapInfos.TryGetValue(item, out TuntapInfo tuntapInfo))
|
||||
{
|
||||
tuntapInfo.Status = TuntapStatus.Normal;
|
||||
tuntapInfo.LastTicks.Clear();
|
||||
}
|
||||
}
|
||||
Version.Add();
|
||||
AddRoute();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Error(ex);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
slim.Release();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 刷新信息,把自己的网卡配置发给别人,顺便把别人的网卡信息带回来
|
||||
/// </summary>
|
||||
public void RefreshConfig()
|
||||
{
|
||||
DataVersion.Add();
|
||||
}
|
||||
/// <summary>
|
||||
/// 刷新IP
|
||||
/// 刷新IP,会触发OnChanged事件
|
||||
/// </summary>
|
||||
public void RefreshIP()
|
||||
{
|
||||
TimerHelper.Async(async () =>
|
||||
{
|
||||
IPAddress oldIP = configInfo.IP;
|
||||
byte prefixLength = configInfo.PrefixLength;
|
||||
IPAddress oldIP = Info.IP;
|
||||
byte prefixLength = Info.PrefixLength;
|
||||
|
||||
await LeaseIP();
|
||||
while (tuntapTransfer.Status == TuntapStatus.Operating)
|
||||
await RefreshIPASync();
|
||||
|
||||
if ((oldIP.Equals(Info.IP) == false || prefixLength != Info.PrefixLength) && Info.Running)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
await OnChanged();
|
||||
}
|
||||
|
||||
bool run = (oldIP.Equals(configInfo.IP) == false || prefixLength != configInfo.PrefixLength) && configInfo.Running
|
||||
|| configInfo.Running && tuntapTransfer.Status != TuntapStatus.Running;
|
||||
|
||||
if (run)
|
||||
{
|
||||
tuntapTransfer.Shutdown();
|
||||
tuntapTransfer.Setup(configInfo.IP, configInfo.PrefixLength);
|
||||
}
|
||||
DataVersion.Add();
|
||||
OnUpdate();
|
||||
});
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 租赁IP
|
||||
/// 刷新IP,不会触发OnChanged
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task RefreshIPASync()
|
||||
{
|
||||
LoadGroupIP();
|
||||
await LeaseIP();
|
||||
SetGroupIP();
|
||||
OnUpdate();
|
||||
}
|
||||
private async Task LeaseIP()
|
||||
{
|
||||
if (configInfo.Group2IP.TryGetValue(clientConfigTransfer.Group.Id, out TuntapGroup2IPInfo tuntapGroup2IPInfo))
|
||||
LeaseInfo leaseInfo = await leaseClientTreansfer.LeaseIp(Info.IP, Info.PrefixLength);
|
||||
Info.IP = leaseInfo.IP;
|
||||
Info.PrefixLength = leaseInfo.PrefixLength;
|
||||
runningConfig.Data.Update();
|
||||
}
|
||||
|
||||
private void LoadGroupIP()
|
||||
{
|
||||
if (Info.Group2IP.TryGetValue(clientConfigTransfer.Group.Id, out TuntapGroup2IPInfo tuntapGroup2IPInfo))
|
||||
{
|
||||
if (tuntapGroup2IPInfo.IP.Equals(configInfo.IP) == false || tuntapGroup2IPInfo.PrefixLength != configInfo.PrefixLength)
|
||||
if (tuntapGroup2IPInfo.IP.Equals(Info.IP) == false || tuntapGroup2IPInfo.PrefixLength != Info.PrefixLength)
|
||||
{
|
||||
configInfo.IP = tuntapGroup2IPInfo.IP;
|
||||
configInfo.PrefixLength = tuntapGroup2IPInfo.PrefixLength;
|
||||
Info.IP = tuntapGroup2IPInfo.IP;
|
||||
Info.PrefixLength = tuntapGroup2IPInfo.PrefixLength;
|
||||
}
|
||||
}
|
||||
LeaseInfo leaseInfo = await leaseClientTreansfer.LeaseIp(configInfo.IP, configInfo.PrefixLength);
|
||||
configInfo.IP = leaseInfo.IP;
|
||||
configInfo.PrefixLength = leaseInfo.PrefixLength;
|
||||
runningConfig.Data.Update();
|
||||
|
||||
tuntapGroup2IPInfo = new TuntapGroup2IPInfo { IP = configInfo.IP, PrefixLength = configInfo.PrefixLength };
|
||||
configInfo.Group2IP.AddOrUpdate(clientConfigTransfer.Group.Id, tuntapGroup2IPInfo, (a, b) => tuntapGroup2IPInfo);
|
||||
}
|
||||
/// <summary>
|
||||
/// 重启网卡
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task RetstartDevice()
|
||||
private void SetGroupIP()
|
||||
{
|
||||
tuntapTransfer.Shutdown();
|
||||
await LeaseIP();
|
||||
tuntapTransfer.Setup(configInfo.IP, configInfo.PrefixLength);
|
||||
TuntapGroup2IPInfo tuntapGroup2IPInfo = new TuntapGroup2IPInfo { IP = Info.IP, PrefixLength = Info.PrefixLength };
|
||||
Info.Group2IP.AddOrUpdate(clientConfigTransfer.Group.Id, tuntapGroup2IPInfo, (a, b) => tuntapGroup2IPInfo);
|
||||
}
|
||||
/// <summary>
|
||||
/// 关闭网卡
|
||||
/// </summary>
|
||||
public void StopDevice()
|
||||
{
|
||||
tuntapTransfer.Shutdown();
|
||||
}
|
||||
|
||||
|
||||
// <summary>
|
||||
/// 添加端口转发
|
||||
/// </summary>
|
||||
private void AddForward()
|
||||
{
|
||||
var temp = ParseForwardItems();
|
||||
var removes = forwardItems.Except(temp, new LinkerTunDeviceForwardItemComparer());
|
||||
if (removes.Any())
|
||||
{
|
||||
tuntapTransfer.RemoveForward(removes.ToList());
|
||||
}
|
||||
forwardItems = temp;
|
||||
tuntapTransfer.AddForward(forwardItems);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除端口转发
|
||||
/// </summary>
|
||||
private void DeleteForward()
|
||||
{
|
||||
tuntapTransfer.RemoveForward(forwardItems);
|
||||
}
|
||||
private List<LinkerTunDeviceForwardItem> ParseForwardItems()
|
||||
{
|
||||
return configInfo.Forwards.Select(c => new LinkerTunDeviceForwardItem { ListenAddr = c.ListenAddr, ListenPort = c.ListenPort, ConnectAddr = c.ConnectAddr, ConnectPort = c.ConnectPort }).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除路由
|
||||
/// </summary>
|
||||
private void DelRoute()
|
||||
{
|
||||
if (routeItems != null)
|
||||
tuntapTransfer.DelRoute(routeItems);
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加路由
|
||||
/// </summary>
|
||||
private void AddRoute()
|
||||
{
|
||||
List<TuntapVeaLanIPAddressList> ipsList = ParseIPs(tuntapInfos.Values.ToList());
|
||||
TuntapVeaLanIPAddress[] ips = ipsList.SelectMany(c => c.IPS).ToArray();
|
||||
routeItems = ipsList.SelectMany(c => c.IPS).Select(c => new LinkerTunDeviceRouteItem { Address = c.OriginIPAddress, PrefixLength = c.PrefixLength }).ToArray();
|
||||
|
||||
tuntapTransfer.AddRoute(routeItems, configInfo.IP);
|
||||
|
||||
HandleSetIPs(ips);
|
||||
foreach (var item in tuntapInfos.Values)
|
||||
{
|
||||
HandleSetIP(item.MachineId, NetworkHelper.IP2Value(item.IP));
|
||||
}
|
||||
foreach (var item in tuntapInfos.Values.Where(c => c.IP.Equals(IPAddress.Any)))
|
||||
{
|
||||
HandleRemoveIP(item.MachineId);
|
||||
}
|
||||
Version.Add();
|
||||
}
|
||||
|
||||
private List<TuntapVeaLanIPAddressList> ParseIPs(List<TuntapInfo> infos)
|
||||
{
|
||||
//排除的IP,
|
||||
uint[] excludeIps =//本机局域网IP
|
||||
tunnelConfigTransfer.LocalIPs.Where(c => c.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
||||
//路由上的IP
|
||||
.Concat(tunnelConfigTransfer.RouteIPs)
|
||||
//网卡IP 服务器IP
|
||||
.Concat(new IPAddress[] { configInfo.IP, clientSignInState.Connection.Address.Address })
|
||||
//网卡配置的局域网IP
|
||||
.Concat(configInfo.Lans.Select(c => c.IP))
|
||||
.Select(NetworkHelper.IP2Value)
|
||||
.ToArray();
|
||||
|
||||
HashSet<uint> hashSet = new HashSet<uint>();
|
||||
|
||||
return infos
|
||||
.Where(c => c.MachineId != clientConfigTransfer.Id)
|
||||
.OrderByDescending(c => c.Status)
|
||||
.OrderByDescending(c => c.LastTicks.Value)
|
||||
|
||||
.Select(c =>
|
||||
{
|
||||
var lans = c.Lans.Where(c => c.Disabled == false && c.IP.Equals(IPAddress.Any) == false).Where(c =>
|
||||
{
|
||||
uint ipInt = NetworkHelper.IP2Value(c.IP);
|
||||
uint maskValue = NetworkHelper.PrefixLength2Value(c.PrefixLength);
|
||||
uint network = ipInt & maskValue;
|
||||
c.Exists = excludeIps.Any(d => (d & maskValue) == network) || hashSet.Contains(network);
|
||||
hashSet.Add(network);
|
||||
return c.Exists == false;
|
||||
});
|
||||
|
||||
return new TuntapVeaLanIPAddressList
|
||||
{
|
||||
MachineId = c.MachineId,
|
||||
IPS = ParseIPs(lans.ToList(), c.MachineId)
|
||||
.Where(c => excludeIps.Select(d => d & c.MaskValue).Contains(c.NetWork) == false).ToList(),
|
||||
};
|
||||
}).ToList();
|
||||
}
|
||||
private List<TuntapVeaLanIPAddress> ParseIPs(List<TuntapLanInfo> lans, string machineid)
|
||||
{
|
||||
return lans.Where(c => c.IP.Equals(IPAddress.Any) == false && c != null).Select((c, index) =>
|
||||
{
|
||||
return ParseIPAddress(c.IP, c.PrefixLength, machineid);
|
||||
|
||||
}).ToList();
|
||||
}
|
||||
private TuntapVeaLanIPAddress ParseIPAddress(IPAddress ip, byte prefixLength, string machineid)
|
||||
{
|
||||
uint ipInt = NetworkHelper.IP2Value(ip);
|
||||
//掩码十进制
|
||||
uint maskValue = NetworkHelper.PrefixLength2Value(prefixLength);
|
||||
return new TuntapVeaLanIPAddress
|
||||
{
|
||||
IPAddress = ipInt,
|
||||
PrefixLength = prefixLength,
|
||||
MaskValue = maskValue,
|
||||
NetWork = ipInt & maskValue,
|
||||
Broadcast = ipInt | ~maskValue,
|
||||
OriginIPAddress = ip,
|
||||
MachineId = machineid
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
126
linker/plugins/tuntap/TuntapDecenter.cs
Normal file
126
linker/plugins/tuntap/TuntapDecenter.cs
Normal file
@@ -0,0 +1,126 @@
|
||||
using linker.libs;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.decenter;
|
||||
using linker.plugins.tuntap.config;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace linker.plugins.tuntap
|
||||
{
|
||||
public sealed class TuntapDecenter : IDecenter
|
||||
{
|
||||
public string Name => "tuntap";
|
||||
public VersionManager DataVersion { get; } = new VersionManager();
|
||||
|
||||
public VersionManager Version { get; } = new VersionManager();
|
||||
public ConcurrentDictionary<string, TuntapInfo> Infos => tuntapInfos;
|
||||
|
||||
private readonly SemaphoreSlim slim = new SemaphoreSlim(1);
|
||||
private readonly ConcurrentDictionary<string, TuntapInfo> tuntapInfos = new ConcurrentDictionary<string, TuntapInfo>();
|
||||
|
||||
public Action OnChangeBefore { get; set; } = () => { };
|
||||
public Action OnChangeAfter { get; set; } = () => { };
|
||||
public Action OnReset { get; set; } = () => { };
|
||||
|
||||
public Func<TuntapInfo> HandleCurrentInfo { get; set; } = () => { return null; };
|
||||
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
public TuntapDecenter(ClientConfigTransfer clientConfigTransfer, ClientSignInState clientSignInState)
|
||||
{
|
||||
this.clientConfigTransfer = clientConfigTransfer;
|
||||
clientSignInState.NetworkEnabledHandle += NetworkEnable;
|
||||
}
|
||||
string groupid = string.Empty;
|
||||
private void NetworkEnable(int times)
|
||||
{
|
||||
if (groupid != clientConfigTransfer.Group.Id)
|
||||
{
|
||||
tuntapInfos.Clear();
|
||||
OnReset();
|
||||
}
|
||||
groupid = clientConfigTransfer.Group.Id;
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
DataVersion.Add();
|
||||
}
|
||||
|
||||
public Memory<byte> GetData()
|
||||
{
|
||||
TuntapInfo info = HandleCurrentInfo();
|
||||
tuntapInfos.AddOrUpdate(info.MachineId, info, (a, b) => info);
|
||||
Version.Add();
|
||||
return MemoryPackSerializer.Serialize(info);
|
||||
}
|
||||
public void SetData(Memory<byte> data)
|
||||
{
|
||||
TuntapInfo info = MemoryPackSerializer.Deserialize<TuntapInfo>(data.Span);
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Debug($"tuntap got {info.IP}");
|
||||
}
|
||||
|
||||
TimerHelper.Async(async () =>
|
||||
{
|
||||
await slim.WaitAsync();
|
||||
try
|
||||
{
|
||||
OnChangeBefore();
|
||||
tuntapInfos.AddOrUpdate(info.MachineId, info, (a, b) => info);
|
||||
Version.Add();
|
||||
OnChangeAfter();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Error(ex);
|
||||
}
|
||||
}
|
||||
slim.Release();
|
||||
});
|
||||
}
|
||||
public void SetData(List<ReadOnlyMemory<byte>> data)
|
||||
{
|
||||
List<TuntapInfo> list = data.Select(c => MemoryPackSerializer.Deserialize<TuntapInfo>(c.Span)).ToList();
|
||||
TimerHelper.Async(async () =>
|
||||
{
|
||||
await slim.WaitAsync();
|
||||
|
||||
try
|
||||
{
|
||||
OnChangeBefore();
|
||||
foreach (var item in list)
|
||||
{
|
||||
tuntapInfos.AddOrUpdate(item.MachineId, item, (a, b) => item);
|
||||
item.LastTicks.Update();
|
||||
}
|
||||
var removes = tuntapInfos.Keys.Except(list.Select(c => c.MachineId)).Where(c => c != clientConfigTransfer.Id).ToList();
|
||||
foreach (var item in removes)
|
||||
{
|
||||
if (tuntapInfos.TryGetValue(item, out TuntapInfo tuntapInfo))
|
||||
{
|
||||
tuntapInfo.Status = TuntapStatus.Normal;
|
||||
tuntapInfo.LastTicks.Clear();
|
||||
}
|
||||
}
|
||||
Version.Add();
|
||||
OnChangeAfter();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
LoggerHelper.Instance.Error(ex);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
slim.Release();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,28 +1,25 @@
|
||||
using linker.client.config;
|
||||
using linker.libs;
|
||||
using linker.libs;
|
||||
using linker.plugins.tuntap.config;
|
||||
using linker.tun;
|
||||
using System.Net.NetworkInformation;
|
||||
|
||||
namespace linker.plugins.tuntap
|
||||
{
|
||||
public sealed class TuntapDeviceStatusTransfer
|
||||
{
|
||||
private readonly RunningConfig runningConfig;
|
||||
private readonly TuntapTransfer tuntapTransfer;
|
||||
private readonly TuntapConfigTransfer tuntapConfigTransfer;
|
||||
private readonly LinkerTunDeviceAdapter linkerTunDeviceAdapter;
|
||||
private readonly TuntapAdapter tuntapAdapter;
|
||||
private ulong setupTimes = 0;
|
||||
public TuntapDeviceStatusTransfer(RunningConfig runningConfig, TuntapTransfer tuntapTransfer, TuntapConfigTransfer tuntapConfigTransfer, LinkerTunDeviceAdapter linkerTunDeviceAdapter)
|
||||
public TuntapDeviceStatusTransfer(TuntapTransfer tuntapTransfer, TuntapConfigTransfer tuntapConfigTransfer, TuntapAdapter tuntapAdapter)
|
||||
{
|
||||
this.runningConfig = runningConfig;
|
||||
this.tuntapTransfer = tuntapTransfer;
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
this.linkerTunDeviceAdapter = linkerTunDeviceAdapter;
|
||||
this.tuntapAdapter = tuntapAdapter;
|
||||
|
||||
tuntapTransfer.OnSetupSuccess += () => { setupTimes++; };
|
||||
|
||||
CheckTuntapStatusTask();
|
||||
|
||||
}
|
||||
private void CheckTuntapStatusTask()
|
||||
{
|
||||
@@ -41,11 +38,10 @@ namespace linker.plugins.tuntap
|
||||
if (await InterfaceAvailable() == false && tuntapTransfer.Status != TuntapStatus.Operating)
|
||||
{
|
||||
LoggerHelper.Instance.Error($"tuntap inerface {tuntapConfigTransfer.DeviceName} is down, restarting");
|
||||
linkerTunDeviceAdapter.Shutdown();
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
if (await InterfaceAvailable() == false && tuntapTransfer.Status != TuntapStatus.Operating)
|
||||
{
|
||||
await tuntapConfigTransfer.RetstartDevice();
|
||||
await tuntapAdapter.RetstartDevice().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,18 +49,19 @@ namespace linker.plugins.tuntap
|
||||
{
|
||||
NetworkInterface networkInterface = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(c => c.Name == tuntapConfigTransfer.DeviceName);
|
||||
return networkInterface != null && networkInterface.OperationalStatus == OperationalStatus.Up && await InterfacePing();
|
||||
}
|
||||
private async Task<bool> InterfacePing()
|
||||
{
|
||||
try
|
||||
|
||||
async Task<bool> InterfacePing()
|
||||
{
|
||||
using Ping ping = new Ping();
|
||||
PingReply pingReply = await ping.SendPingAsync(tuntapConfigTransfer.IP, 500);
|
||||
return pingReply.Status == IPStatus.Success;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
try
|
||||
{
|
||||
using Ping ping = new Ping();
|
||||
PingReply pingReply = await ping.SendPingAsync(tuntapConfigTransfer.IP, 500);
|
||||
return pingReply.Status == IPStatus.Success;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,8 @@
|
||||
using linker.client.config;
|
||||
using linker.libs;
|
||||
using linker.libs;
|
||||
using linker.plugins.tuntap.config;
|
||||
using linker.tunnel.connection;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net;
|
||||
using linker.config;
|
||||
using System.Net.Sockets;
|
||||
using linker.libs.extends;
|
||||
using linker.plugins.client;
|
||||
@@ -17,19 +15,21 @@ namespace linker.plugins.tuntap
|
||||
private readonly TuntapConfigTransfer tuntapConfigTransfer;
|
||||
private readonly TuntapProxy tuntapProxy;
|
||||
private readonly ClientConfigTransfer clientConfigTransfer;
|
||||
private readonly TuntapDecenter tuntapDecenter;
|
||||
|
||||
public TuntapPingTransfer(TuntapTransfer tuntapTransfer, TuntapConfigTransfer tuntapConfigTransfer, TuntapProxy tuntapProxy, ClientConfigTransfer clientConfigTransfer)
|
||||
public TuntapPingTransfer(TuntapTransfer tuntapTransfer, TuntapConfigTransfer tuntapConfigTransfer, TuntapProxy tuntapProxy, ClientConfigTransfer clientConfigTransfer, TuntapDecenter tuntapDecenter)
|
||||
{
|
||||
this.tuntapTransfer = tuntapTransfer;
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
this.tuntapProxy = tuntapProxy;
|
||||
this.clientConfigTransfer = clientConfigTransfer;
|
||||
this.tuntapDecenter = tuntapDecenter;
|
||||
|
||||
PingTask();
|
||||
|
||||
}
|
||||
|
||||
private readonly LastTicksManager lastTicksManager = new LastTicksManager();
|
||||
private readonly LastTicksManager lastTicksManager1 = new LastTicksManager();
|
||||
public void SubscribePing()
|
||||
{
|
||||
lastTicksManager.Update();
|
||||
@@ -49,7 +49,7 @@ namespace linker.plugins.tuntap
|
||||
{
|
||||
if (tuntapTransfer.Status == TuntapStatus.Running && (tuntapConfigTransfer.Switch & TuntapSwitch.ShowDelay) == TuntapSwitch.ShowDelay)
|
||||
{
|
||||
var items = tuntapConfigTransfer.Infos.Values.Where(c => c.IP != null && c.IP.Equals(IPAddress.Any) == false && (c.Status & TuntapStatus.Running) == TuntapStatus.Running);
|
||||
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)
|
||||
{
|
||||
var connections = tuntapProxy.GetConnections();
|
||||
@@ -61,7 +61,7 @@ namespace linker.plugins.tuntap
|
||||
using Ping ping = new Ping();
|
||||
PingReply pingReply = await ping.SendPingAsync(c.IP, 500);
|
||||
c.Delay = pingReply.Status == IPStatus.Success ? (int)pingReply.RoundtripTime : -1;
|
||||
tuntapConfigTransfer.Version.Add();
|
||||
tuntapDecenter.Version.Add();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,4 @@
|
||||
using linker.config;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel;
|
||||
using linker.tunnel.connection;
|
||||
using linker.libs;
|
||||
using System.Collections.Concurrent;
|
||||
@@ -9,38 +8,32 @@ using System.Buffers.Binary;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.tunnel;
|
||||
using System.Buffers;
|
||||
using linker.client.config;
|
||||
using linker.plugins.relay.client;
|
||||
using linker.plugins.pcp;
|
||||
|
||||
namespace linker.plugins.tuntap
|
||||
{
|
||||
public sealed class TuntapProxy : TunnelBase, ILinkerTunDeviceCallback, ITunnelConnectionReceiveCallback
|
||||
public sealed class TuntapProxy : TunnelBase, ITunnelConnectionReceiveCallback
|
||||
{
|
||||
|
||||
public Func<ITunnelConnection, Task> OnTunnelClose { get; set; } = async (connection) => { await Task.CompletedTask; };
|
||||
public Func<ITunnelConnection, ReadOnlyMemory<byte>, Task> OnReceivePacket { get; set; } = async (connection, packet) => { await Task.CompletedTask; };
|
||||
public Action<uint> OnIPNotFound { get; set; } = (ip) =>{};
|
||||
|
||||
|
||||
private uint[] maskValues = Array.Empty<uint>();
|
||||
private readonly ConcurrentDictionary<uint, string> ip2MachineDic = new ConcurrentDictionary<uint, string>();
|
||||
private readonly ConcurrentDictionary<uint, ITunnelConnection> ipConnections = new ConcurrentDictionary<uint, ITunnelConnection>();
|
||||
private readonly OperatingMultipleManager operatingMultipleManager = new OperatingMultipleManager();
|
||||
|
||||
protected override string TransactionId => "tuntap";
|
||||
private readonly LinkerTunDeviceAdapter linkerTunDeviceAdapter;
|
||||
|
||||
private HashSet<uint> ipRefreshCache = new HashSet<uint>();
|
||||
protected override string TransactionId => "tuntap";
|
||||
|
||||
private readonly ClientSignInTransfer clientSignInTransfer;
|
||||
private readonly TuntapConfigTransfer tuntapConfigTransfer;
|
||||
|
||||
public TuntapProxy(ClientConfigTransfer clientConfigTransfer, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, LinkerTunDeviceAdapter linkerTunDeviceAdapter, ClientSignInState clientSignInState,RelayClientConfigTransfer relayClientConfigTransfer, TuntapConfigTransfer tuntapConfigTransfer)
|
||||
public TuntapProxy(ClientConfigTransfer clientConfigTransfer,
|
||||
TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, PcpTransfer pcpTransfer,
|
||||
ClientSignInTransfer clientSignInTransfer, TuntapTransfer tuntapTransfer, ClientSignInState clientSignInState,
|
||||
RelayClientConfigTransfer relayClientConfigTransfer, TuntapConfigTransfer tuntapConfigTransfer)
|
||||
: base(tunnelTransfer, relayTransfer, pcpTransfer, clientSignInTransfer, clientSignInState, clientConfigTransfer, relayClientConfigTransfer)
|
||||
{
|
||||
this.clientSignInTransfer = clientSignInTransfer;
|
||||
this.linkerTunDeviceAdapter = linkerTunDeviceAdapter;
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
|
||||
tuntapConfigTransfer.HandleReset += ClearIPs;
|
||||
tuntapConfigTransfer.HandleSetIPs += SetIPs;
|
||||
tuntapConfigTransfer.HandleSetIP += SetIP;
|
||||
tuntapConfigTransfer.HandleRemoveIP += RemoveIP;
|
||||
}
|
||||
|
||||
protected override void Connected(ITunnelConnection connection)
|
||||
@@ -64,8 +57,7 @@ namespace linker.plugins.tuntap
|
||||
/// <returns></returns>
|
||||
public async Task Receive(ITunnelConnection connection, ReadOnlyMemory<byte> buffer, object state)
|
||||
{
|
||||
linkerTunDeviceAdapter.Write(buffer);
|
||||
await Task.CompletedTask;
|
||||
await OnReceivePacket(connection, buffer).ConfigureAwait(false);
|
||||
}
|
||||
/// <summary>
|
||||
/// 隧道关闭
|
||||
@@ -75,9 +67,8 @@ namespace linker.plugins.tuntap
|
||||
/// <returns></returns>
|
||||
public async Task Closed(ITunnelConnection connection, object state)
|
||||
{
|
||||
tuntapConfigTransfer.RefreshConfig();
|
||||
await OnTunnelClose(connection).ConfigureAwait(false);
|
||||
Version.Add();
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -85,12 +76,12 @@ namespace linker.plugins.tuntap
|
||||
/// </summary>
|
||||
/// <param name="packet"></param>
|
||||
/// <returns></returns>
|
||||
public async Task Callback(LinkerTunDevicPacket packet)
|
||||
public async Task InputPacket(LinkerTunDevicPacket packet)
|
||||
{
|
||||
//IPV4广播组播、IPV6 多播
|
||||
if (packet.IPV4Broadcast || packet.IPV6Multicast)
|
||||
{
|
||||
if (connections.IsEmpty == false && (tuntapConfigTransfer.Switch & TuntapSwitch.Multicast) == 0)
|
||||
if (connections.IsEmpty == false)
|
||||
{
|
||||
await Task.WhenAll(connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Packet)));
|
||||
}
|
||||
@@ -127,53 +118,6 @@ namespace linker.plugins.tuntap
|
||||
await connection.SendAsync(packet.Packet);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置IP,等下有连接进来,用IP匹配,才能知道这个连接是要连谁
|
||||
/// </summary>
|
||||
/// <param name="ips"></param>
|
||||
private void SetIPs(TuntapVeaLanIPAddress[] ips)
|
||||
{
|
||||
var dic = ips.GroupBy(c => c.NetWork).ToDictionary(c => c.Key, d => d.Select(e => e.MachineId).ToList());
|
||||
foreach (var item in dic.Where(c => c.Value.Count > 0))
|
||||
{
|
||||
string machineId = item.Value[0];
|
||||
ip2MachineDic.AddOrUpdate(item.Key, machineId, (a, b) => machineId);
|
||||
|
||||
if (ipConnections.TryGetValue(item.Key, out ITunnelConnection connection) && item.Value.Count > 0 && machineId != connection.RemoteMachineId)
|
||||
{
|
||||
ipConnections.TryRemove(item.Key, out _);
|
||||
}
|
||||
}
|
||||
maskValues = ips.Select(c => c.MaskValue).Distinct().OrderBy(c => c).ToArray();
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置IP,等下有连接进来,用IP匹配,才能知道这个连接是要连谁
|
||||
/// </summary>
|
||||
/// <param name="machineId"></param>
|
||||
/// <param name="ip"></param>
|
||||
private void SetIP(string machineId, uint ip)
|
||||
{
|
||||
ip2MachineDic.AddOrUpdate(ip, machineId, (a, b) => machineId);
|
||||
if (ipConnections.TryGetValue(ip, out ITunnelConnection connection) && machineId != connection.RemoteMachineId)
|
||||
{
|
||||
ipConnections.TryRemove(ip, out _);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 移除
|
||||
/// </summary>
|
||||
/// <param name="machineId"></param>
|
||||
private void RemoveIP(string machineId)
|
||||
{
|
||||
foreach (var item in ip2MachineDic.Where(c => c.Value == machineId).ToList())
|
||||
{
|
||||
ipConnections.TryRemove(item.Key, out _);
|
||||
ip2MachineDic.TryRemove(item.Key, out _);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打洞或者中继
|
||||
/// </summary>
|
||||
@@ -199,7 +143,7 @@ namespace linker.plugins.tuntap
|
||||
if (ipRefreshCache.Contains(ip) == false)
|
||||
{
|
||||
ipRefreshCache.Add(ip);
|
||||
tuntapConfigTransfer.RefreshConfig();
|
||||
OnIPNotFound(ip);
|
||||
}
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
{
|
||||
@@ -210,7 +154,10 @@ namespace linker.plugins.tuntap
|
||||
|
||||
}
|
||||
|
||||
private void ClearIPs()
|
||||
/// <summary>
|
||||
/// 清除IP
|
||||
/// </summary>
|
||||
public void ClearIPs()
|
||||
{
|
||||
ip2MachineDic.Clear();
|
||||
ipConnections.Clear();
|
||||
@@ -220,5 +167,52 @@ namespace linker.plugins.tuntap
|
||||
LoggerHelper.Instance.Debug($"tuntap cache clear");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置IP,等下有连接进来,用IP匹配,才能知道这个连接是要连谁
|
||||
/// </summary>
|
||||
/// <param name="ips"></param>
|
||||
public void SetIPs(TuntapVeaLanIPAddress[] ips)
|
||||
{
|
||||
var dic = ips.GroupBy(c => c.NetWork).ToDictionary(c => c.Key, d => d.Select(e => e.MachineId).ToList());
|
||||
foreach (var item in dic.Where(c => c.Value.Count > 0))
|
||||
{
|
||||
string machineId = item.Value[0];
|
||||
ip2MachineDic.AddOrUpdate(item.Key, machineId, (a, b) => machineId);
|
||||
|
||||
if (ipConnections.TryGetValue(item.Key, out ITunnelConnection connection) && item.Value.Count > 0 && machineId != connection.RemoteMachineId)
|
||||
{
|
||||
ipConnections.TryRemove(item.Key, out _);
|
||||
}
|
||||
}
|
||||
maskValues = ips.Select(c => c.MaskValue).Distinct().OrderBy(c => c).ToArray();
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置IP,等下有连接进来,用IP匹配,才能知道这个连接是要连谁
|
||||
/// </summary>
|
||||
/// <param name="machineId"></param>
|
||||
/// <param name="ip"></param>
|
||||
public void SetIP(string machineId, uint ip)
|
||||
{
|
||||
ip2MachineDic.AddOrUpdate(ip, machineId, (a, b) => machineId);
|
||||
if (ipConnections.TryGetValue(ip, out ITunnelConnection connection) && machineId != connection.RemoteMachineId)
|
||||
{
|
||||
ipConnections.TryRemove(ip, out _);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 移除
|
||||
/// </summary>
|
||||
/// <param name="machineId"></param>
|
||||
public void RemoveIP(string machineId)
|
||||
{
|
||||
foreach (var item in ip2MachineDic.Where(c => c.Value == machineId).ToList())
|
||||
{
|
||||
ipConnections.TryRemove(item.Key, out _);
|
||||
ip2MachineDic.TryRemove(item.Key, out _);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -36,7 +36,9 @@ namespace linker.plugins.tuntap
|
||||
serviceCollection.AddSingleton<TuntapPingTransfer>();
|
||||
serviceCollection.AddSingleton<TuntapDeviceStatusTransfer>();
|
||||
|
||||
serviceCollection.AddSingleton<TuntapDecenter>();
|
||||
|
||||
serviceCollection.AddSingleton<TuntapAdapter>();
|
||||
}
|
||||
|
||||
public void AddServer(ServiceCollection serviceCollection, FileConfig config)
|
||||
@@ -57,7 +59,7 @@ namespace linker.plugins.tuntap
|
||||
TuntapPingTransfer tuntapPingTransfer = serviceProvider.GetService<TuntapPingTransfer>();
|
||||
TuntapDeviceStatusTransfer tuntapDeviceStatusTransfer = serviceProvider.GetService<TuntapDeviceStatusTransfer>();
|
||||
|
||||
tuntapTransfer.Init(tuntapConfigTransfer.DeviceName, tuntapProxy);
|
||||
TuntapAdapter tuntapAdapter = serviceProvider.GetService<TuntapAdapter>();
|
||||
}
|
||||
|
||||
public void UseServer(ServiceProvider serviceProvider, FileConfig config)
|
||||
|
@@ -1,7 +1,5 @@
|
||||
using linker.client.config;
|
||||
using linker.libs;
|
||||
using linker.libs;
|
||||
using System.Net;
|
||||
using linker.plugins.client;
|
||||
using linker.plugins.tuntap.config;
|
||||
using linker.tun;
|
||||
|
||||
@@ -28,12 +26,20 @@ namespace linker.plugins.tuntap
|
||||
this.linkerTunDeviceAdapter = linkerTunDeviceAdapter;
|
||||
}
|
||||
|
||||
bool inited = false;
|
||||
public void Init(string name,ILinkerTunDeviceCallback linkerTunDeviceCallback)
|
||||
{
|
||||
if (inited) return;
|
||||
inited = true;
|
||||
|
||||
linkerTunDeviceAdapter.Initialize(name, linkerTunDeviceCallback);
|
||||
AppDomain.CurrentDomain.ProcessExit += (s, e) => linkerTunDeviceAdapter.Shutdown();
|
||||
Console.CancelKeyPress += (s, e) => linkerTunDeviceAdapter.Shutdown();
|
||||
}
|
||||
public bool Write(ReadOnlyMemory<byte> buffer)
|
||||
{
|
||||
return linkerTunDeviceAdapter.Write(buffer);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 运行网卡
|
||||
|
@@ -4,7 +4,6 @@ using System.Net;
|
||||
using linker.libs;
|
||||
using MemoryPack;
|
||||
using System.Collections.Concurrent;
|
||||
using linker.libs.extends;
|
||||
|
||||
namespace linker.plugins.tuntap.lease
|
||||
{
|
||||
|
@@ -17,8 +17,10 @@ namespace linker.plugins.tuntap.messenger
|
||||
private readonly LeaseClientTreansfer leaseClientTreansfer;
|
||||
private readonly TuntapPingTransfer pingTransfer;
|
||||
private readonly IMessengerSender messengerSender;
|
||||
private readonly TuntapAdapter tuntapAdapter;
|
||||
|
||||
public TuntapClientMessenger(TuntapTransfer tuntapTransfer, TuntapConfigTransfer tuntapConfigTransfer, TuntapProxy tuntapProxy, LeaseClientTreansfer leaseClientTreansfer, TuntapPingTransfer pingTransfer, IMessengerSender messengerSender)
|
||||
public TuntapClientMessenger(TuntapTransfer tuntapTransfer, TuntapConfigTransfer tuntapConfigTransfer,
|
||||
TuntapProxy tuntapProxy, LeaseClientTreansfer leaseClientTreansfer, TuntapPingTransfer pingTransfer, IMessengerSender messengerSender, TuntapAdapter tuntapAdapter)
|
||||
{
|
||||
this.tuntapTransfer = tuntapTransfer;
|
||||
this.tuntapConfigTransfer = tuntapConfigTransfer;
|
||||
@@ -26,6 +28,7 @@ namespace linker.plugins.tuntap.messenger
|
||||
this.leaseClientTreansfer = leaseClientTreansfer;
|
||||
this.pingTransfer = pingTransfer;
|
||||
this.messengerSender = messengerSender;
|
||||
this.tuntapAdapter = tuntapAdapter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -35,7 +38,7 @@ namespace linker.plugins.tuntap.messenger
|
||||
[MessengerId((ushort)TuntapMessengerIds.Run)]
|
||||
public void Run(IConnection connection)
|
||||
{
|
||||
_ = tuntapConfigTransfer.RetstartDevice();
|
||||
_ = tuntapAdapter.RetstartDevice();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -45,7 +48,7 @@ namespace linker.plugins.tuntap.messenger
|
||||
[MessengerId((ushort)TuntapMessengerIds.Stop)]
|
||||
public void Stop(IConnection connection)
|
||||
{
|
||||
tuntapConfigTransfer.StopDevice();
|
||||
tuntapAdapter.StopDevice();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -56,7 +59,7 @@ namespace linker.plugins.tuntap.messenger
|
||||
public void Update(IConnection connection)
|
||||
{
|
||||
TuntapInfo info = MemoryPackSerializer.Deserialize<TuntapInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||
tuntapConfigTransfer.UpdateConfig(info);
|
||||
tuntapConfigTransfer.Update(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
v1.6.3
|
||||
2024-12-12 00:29:09
|
||||
2024-12-12 17:37:53
|
||||
1. 优化UI,显示网络计算IP数
|
||||
2. 修复内网穿透不停止直接删除导致的无法再次添加的问题
|
||||
3. 优化网卡的端口转发
|
||||
|
Reference in New Issue
Block a user