整理代码

This commit is contained in:
snltty
2024-12-12 17:37:53 +08:00
parent f95926ec81
commit cc4a9ef3f1
42 changed files with 843 additions and 806 deletions

View File

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

Binary file not shown.

View File

@@ -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}

View File

@@ -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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,4 @@
using linker.tunnel.adapter; using linker.tunnel.connection;
using linker.tunnel.connection;
using linker.tunnel.transport; using linker.tunnel.transport;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
@@ -7,14 +6,63 @@ using System.Collections.Concurrent;
using System.Net.Sockets; using System.Net.Sockets;
using System.Net; using System.Net;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using System.Security.Cryptography.X509Certificates;
namespace linker.tunnel namespace linker.tunnel
{ {
public sealed class TunnelTransfer 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 List<ITunnelTransport> transports;
private TunnelWanPortTransfer compactTransfer; private TunnelWanPortTransfer tunnelWanPortTransfer;
private ITunnelAdapter tunnelAdapter;
private TunnelUpnpTransfer TunnelUpnpTransfer; private TunnelUpnpTransfer TunnelUpnpTransfer;
private ConcurrentDictionary<string, bool> connectingDic = new ConcurrentDictionary<string, bool>(); private ConcurrentDictionary<string, bool> connectingDic = new ConcurrentDictionary<string, bool>();
@@ -29,23 +77,22 @@ namespace linker.tunnel
/// 加载打洞协议 /// 加载打洞协议
/// </summary> /// </summary>
/// <param name="assembs"></param> /// <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.tunnelWanPortTransfer = tunnelWanPortTransfer;
this.tunnelAdapter = tunnelAdapter;
this.transports = transports; this.transports = transports;
this.TunnelUpnpTransfer = TunnelUpnpTransfer; this.TunnelUpnpTransfer = TunnelUpnpTransfer;
foreach (var item in transports) foreach (var item in transports)
{ {
item.OnSendConnectBegin = tunnelAdapter.SendConnectBegin; item.OnSendConnectBegin = SendConnectBegin;
item.OnSendConnectFail = tunnelAdapter.SendConnectFail; item.OnSendConnectFail = SendConnectFail;
item.OnSendConnectSuccess = tunnelAdapter.SendConnectSuccess; item.OnSendConnectSuccess = SendConnectSuccess;
item.OnConnected = _OnConnected; 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)); var newTransportNames = transports.Select(c => c.Name).Except(transportItems.Select(c => c.Name));
if (newTransportNames.Any()) 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))}"); LoggerHelper.Instance.Info($"load tunnel transport:{string.Join(",", transports.Select(c => c.Name))}");
} }
/// <summary> /// <summary>
/// 设置成功打洞回调 /// 设置成功打洞回调
/// </summary> /// </summary>
@@ -154,7 +200,7 @@ namespace linker.tunnel
try 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); ITunnelTransport transport = transports.FirstOrDefault(c => c.Name == transportItem.Name);
//找不到这个打洞协议,或者是不支持的协议 //找不到这个打洞协议,或者是不支持的协议
@@ -163,7 +209,7 @@ namespace linker.tunnel
continue; continue;
} }
foreach (var wanPortProtocol in compactTransfer.Protocols) foreach (var wanPortProtocol in tunnelWanPortTransfer.Protocols)
{ {
//这个打洞协议不支持这个外网端口协议 //这个打洞协议不支持这个外网端口协议
@@ -182,7 +228,7 @@ namespace linker.tunnel
//获取自己的外网ip //获取自己的外网ip
Task<TunnelTransportWanPortInfo> localInfo = GetLocalInfo(wanPortProtocol); Task<TunnelTransportWanPortInfo> localInfo = GetLocalInfo(wanPortProtocol);
//获取对方的外网ip //获取对方的外网ip
Task<TunnelTransportWanPortInfo> remoteInfo = tunnelAdapter.GetRemoteWanPort(new TunnelWanPortProtocolInfo Task<TunnelTransportWanPortInfo> remoteInfo = GetRemoteWanPort(new TunnelWanPortProtocolInfo
{ {
MachineId = remoteMachineId, MachineId = remoteMachineId,
ProtocolType = wanPortProtocol ProtocolType = wanPortProtocol
@@ -270,7 +316,7 @@ namespace linker.tunnel
try try
{ {
ITunnelTransport _transports = transports.FirstOrDefault(c => c.Name == tunnelTransportInfo.TransportName && c.ProtocolType == tunnelTransportInfo.TransportType); 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) if (_transports != null && item != null)
{ {
OnConnectBegin(tunnelTransportInfo); OnConnectBegin(tunnelTransportInfo);
@@ -283,7 +329,7 @@ namespace linker.tunnel
else else
{ {
connectingDic.TryRemove(tunnelTransportInfo.Remote.MachineId, out _); connectingDic.TryRemove(tunnelTransportInfo.Remote.MachineId, out _);
_ = tunnelAdapter.SendConnectFail(tunnelTransportInfo); _ = SendConnectFail(tunnelTransportInfo);
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -331,11 +377,11 @@ namespace linker.tunnel
/// <returns></returns> /// <returns></returns>
private async Task<TunnelTransportWanPortInfo> GetLocalInfo(TunnelWanPortProtocolType tunnelWanPortProtocolType) 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) if (ip != null)
{ {
MapInfo portMapInfo = TunnelUpnpTransfer.PortMap ?? new MapInfo { PrivatePort = 0, PublicPort = 0 }; MapInfo portMapInfo = TunnelUpnpTransfer.PortMap ?? new MapInfo { PrivatePort = 0, PublicPort = 0 };
var config = tunnelAdapter.GetLocalConfig(); var config = GetLocalConfig();
return new TunnelTransportWanPortInfo return new TunnelTransportWanPortInfo
{ {
Local = ip.Local, Local = ip.Local,
@@ -492,6 +538,12 @@ namespace linker.tunnel
{ {
backgroundDic.TryRemove(GetBackgroundKey(remoteMachineId, transactionId), out _); 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) public bool IsBackground(string remoteMachineId, string transactionId)
{ {
return backgroundDic.ContainsKey(GetBackgroundKey(remoteMachineId, transactionId)); return backgroundDic.ContainsKey(GetBackgroundKey(remoteMachineId, transactionId));

View File

@@ -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; }
}
}

View File

@@ -1,7 +1,7 @@
using linker.tunnel.adapter; using linker.tunnel.connection;
using linker.tunnel.connection;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using System.Net; using System.Net;
using System.Security.Cryptography.X509Certificates;
namespace linker.tunnel.transport namespace linker.tunnel.transport
{ {
@@ -62,7 +62,7 @@ namespace linker.tunnel.transport
/// </summary> /// </summary>
public Action<ITunnelConnection> OnConnected { get; set; } public Action<ITunnelConnection> OnConnected { get; set; }
public void SetAdapter(ITunnelAdapter tunnelAdapter); public void SetSSL(X509Certificate2 certificate);
/// <summary> /// <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; }
}
} }

View File

@@ -1,4 +1,4 @@
using linker.tunnel.adapter; 
using linker.tunnel.connection; using linker.tunnel.connection;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
@@ -10,6 +10,7 @@ using System.Net.Sockets;
using System.Security.Authentication; using System.Security.Authentication;
using System.Text; using System.Text;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using System.Security.Cryptography.X509Certificates;
namespace linker.tunnel.transport namespace linker.tunnel.transport
{ {
@@ -46,15 +47,16 @@ namespace linker.tunnel.transport
private byte[] endBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.end"); private byte[] endBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.end");
private IPEndPoint quicListenEP = null; private IPEndPoint quicListenEP = null;
private ITunnelAdapter tunnelAdapter;
public TransportMsQuic() public TransportMsQuic()
{ {
_ = QuicListen(); _ = QuicListen();
} }
public void SetAdapter(ITunnelAdapter tunnelAdapter) private X509Certificate2 certificate;
public void SetSSL(X509Certificate2 certificate)
{ {
this.tunnelAdapter = tunnelAdapter; this.certificate = certificate;
} }
/// <summary> /// <summary>
@@ -72,7 +74,7 @@ namespace linker.tunnel.transport
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false); await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
return null; return null;
} }
if (tunnelAdapter.Certificate == null) if (certificate == null)
{ {
LoggerHelper.Instance.Warning($"msquic need ssl"); LoggerHelper.Instance.Warning($"msquic need ssl");
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false); await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
@@ -132,7 +134,7 @@ namespace linker.tunnel.transport
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false); await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
return; return;
} }
if (tunnelAdapter.Certificate == null) if (certificate == null)
{ {
LoggerHelper.Instance.Warning($"msquic need ssl"); LoggerHelper.Instance.Warning($"msquic need ssl");
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false); 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"); LoggerHelper.Instance.Warning($"msquic not supported, need win11+,or linux, or try to restart linker");
return; return;
} }
if (tunnelAdapter.Certificate == null) if (certificate == null)
{ {
LoggerHelper.Instance.Warning($"msquic need ssl"); LoggerHelper.Instance.Warning($"msquic need ssl");
return; return;
@@ -683,7 +685,7 @@ namespace linker.tunnel.transport
IdleTimeout = TimeSpan.FromMilliseconds(15000), IdleTimeout = TimeSpan.FromMilliseconds(15000),
ServerAuthenticationOptions = new SslServerAuthenticationOptions ServerAuthenticationOptions = new SslServerAuthenticationOptions
{ {
ServerCertificate = tunnelAdapter.Certificate, ServerCertificate = certificate,
EnabledSslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13, EnabledSslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13,
ApplicationProtocols = new List<SslApplicationProtocol> { SslApplicationProtocol.Http3 } ApplicationProtocols = new List<SslApplicationProtocol> { SslApplicationProtocol.Http3 }
} }

View File

@@ -1,4 +1,4 @@
using linker.tunnel.adapter; 
using linker.tunnel.connection; using linker.tunnel.connection;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
@@ -54,13 +54,13 @@ namespace linker.tunnel.transport
/// </summary> /// </summary>
public Action<ITunnelConnection> OnConnected { get; set; } = (state) => { }; public Action<ITunnelConnection> OnConnected { get; set; } = (state) => { };
private ITunnelAdapter tunnelAdapter;
public TunnelTransportTcpNutssb() public TunnelTransportTcpNutssb()
{ {
} }
public void SetAdapter(ITunnelAdapter tunnelAdapter) private X509Certificate2 certificate;
public void SetSSL(X509Certificate2 certificate)
{ {
this.tunnelAdapter = tunnelAdapter; this.certificate = certificate;
} }
/// <summary> /// <summary>
@@ -114,7 +114,7 @@ namespace linker.tunnel.transport
/// <param name="tunnelTransportInfo"></param> /// <param name="tunnelTransportInfo"></param>
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo) 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"); LoggerHelper.Instance.Error($"{Name}->ssl Certificate not found");
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false); await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
@@ -278,7 +278,7 @@ namespace linker.tunnel.transport
SslStream sslStream = null; SslStream sslStream = null;
if (_state.SSL) if (_state.SSL)
{ {
if (tunnelAdapter.Certificate == null) if (certificate == null)
{ {
LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found"); LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found");
socket.SafeClose(); socket.SafeClose();
@@ -286,7 +286,7 @@ namespace linker.tunnel.transport
} }
sslStream = new SslStream(new NetworkStream(socket, false), false); 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 TunnelConnectionTcp result = new TunnelConnectionTcp

View File

@@ -1,4 +1,4 @@
using linker.tunnel.adapter; 
using linker.tunnel.connection; using linker.tunnel.connection;
using linker.libs; using linker.libs;
using linker.libs.extends; using linker.libs.extends;
@@ -55,14 +55,14 @@ namespace linker.tunnel.transport
private byte[] authBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.ttl"); private byte[] authBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.ttl");
private byte[] endBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.end"); private byte[] endBytes = Encoding.UTF8.GetBytes($"{Helper.GlobalString}.end");
private ITunnelAdapter tunnelAdapter;
public TransportTcpP2PNAT() public TransportTcpP2PNAT()
{ {
} }
public void SetAdapter(ITunnelAdapter tunnelAdapter)
private X509Certificate2 certificate;
public void SetSSL(X509Certificate2 certificate)
{ {
this.tunnelAdapter = tunnelAdapter; this.certificate = certificate;
} }
/// <summary> /// <summary>
@@ -96,7 +96,7 @@ namespace linker.tunnel.transport
/// <param name="tunnelTransportInfo"></param> /// <param name="tunnelTransportInfo"></param>
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo) 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"); LoggerHelper.Instance.Error($"{Name}->ssl Certificate not found");
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false); await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
@@ -217,7 +217,7 @@ namespace linker.tunnel.transport
SslStream sslStream = null; SslStream sslStream = null;
if (state.SSL) if (state.SSL)
{ {
if (tunnelAdapter.Certificate == null) if (certificate == null)
{ {
LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found"); LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found");
socket.SafeClose(); socket.SafeClose();
@@ -225,7 +225,7 @@ namespace linker.tunnel.transport
} }
sslStream = new SslStream(new NetworkStream(socket, false), false); 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 return new TunnelConnectionTcp

View File

@@ -6,7 +6,6 @@ using System.Text;
using linker.libs.extends; using linker.libs.extends;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using linker.libs; using linker.libs;
using linker.tunnel.adapter;
using System.Net.Security; using System.Net.Security;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
using System.Security.Authentication; 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 readonly ConcurrentDictionary<string, TaskCompletionSource<Socket>> distDic = new ConcurrentDictionary<string, TaskCompletionSource<Socket>>();
private ITunnelAdapter tunnelAdapter;
public TransportTcpPortMap() 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) 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"); LoggerHelper.Instance.Error($"{Name}->ssl Certificate not found");
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false); await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);
@@ -246,7 +246,7 @@ namespace linker.tunnel.transport
SslStream sslStream = null; SslStream sslStream = null;
if (tunnelTransportInfo.SSL) if (tunnelTransportInfo.SSL)
{ {
if (tunnelAdapter.Certificate == null) if (certificate == null)
{ {
LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found"); LoggerHelper.Instance.Error($"{Name}-> ssl Certificate not found");
socket.SafeClose(); socket.SafeClose();
@@ -254,7 +254,7 @@ namespace linker.tunnel.transport
} }
sslStream = new SslStream(new NetworkStream(socket, false), false); 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 TunnelConnectionTcp result = new TunnelConnectionTcp

View File

@@ -6,7 +6,7 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using linker.tunnel.adapter; using System.Security.Cryptography.X509Certificates;
namespace linker.tunnel.transport namespace linker.tunnel.transport
{ {
@@ -53,7 +53,7 @@ namespace linker.tunnel.transport
public TransportUdp() public TransportUdp()
{ {
} }
public void SetAdapter(ITunnelAdapter tunnelAdapter) public void SetSSL(X509Certificate2 certificate)
{ {
} }

View File

@@ -6,7 +6,7 @@ using System.Text;
using linker.libs.extends; using linker.libs.extends;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using linker.libs; using linker.libs;
using linker.tunnel.adapter; using System.Security.Cryptography.X509Certificates;
namespace linker.tunnel.transport 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<string, TaskCompletionSource<State>> distDic = new ConcurrentDictionary<string, TaskCompletionSource<State>>();
private readonly ConcurrentDictionary<IPEndPoint, ConnectionCacheInfo> connectionsDic = new ConcurrentDictionary<IPEndPoint, ConnectionCacheInfo>(new IPEndPointComparer()); private readonly ConcurrentDictionary<IPEndPoint, ConnectionCacheInfo> connectionsDic = new ConcurrentDictionary<IPEndPoint, ConnectionCacheInfo>(new IPEndPointComparer());
private ITunnelAdapter tunnelAdapter;
public TransportUdpPortMap() public TransportUdpPortMap()
{ {
CleanTask(); CleanTask();
} }
public void SetAdapter(ITunnelAdapter tunnelAdapter) private X509Certificate2 certificate;
public void SetSSL(X509Certificate2 certificate)
{ {
this.tunnelAdapter = tunnelAdapter; this.certificate = certificate;
} }
Socket socket; Socket socket;
@@ -197,7 +198,7 @@ namespace linker.tunnel.transport
} }
public async Task OnBegin(TunnelTransportInfo tunnelTransportInfo) 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"); LoggerHelper.Instance.Error($"{Name}->ssl Certificate not found");
await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false); await OnSendConnectFail(tunnelTransportInfo).ConfigureAwait(false);

View File

@@ -1,5 +1,4 @@
using linker.libs; using linker.libs;
using linker.tunnel.adapter;
using System.Net; using System.Net;
namespace linker.tunnel.wanport namespace linker.tunnel.wanport
@@ -13,14 +12,10 @@ namespace linker.tunnel.wanport
public List<TunnelWanPortProtocolType> Protocols => tunnelWanPorts.Select(p => p.ProtocolType).ToList(); public List<TunnelWanPortProtocolType> Protocols => tunnelWanPorts.Select(p => p.ProtocolType).ToList();
private readonly ITunnelAdapter tunnelAdapter; public TunnelWanPortTransfer()
public TunnelWanPortTransfer(ITunnelAdapter tunnelAdapter)
{ {
this.tunnelAdapter = tunnelAdapter;
} }
/// <summary> /// <summary>
/// 加载所有外网端口协议 /// 加载所有外网端口协议
/// </summary> /// </summary>
@@ -37,14 +32,13 @@ namespace linker.tunnel.wanport
/// </summary> /// </summary>
/// <param name="localIP">你的局域网IP</param> /// <param name="localIP">你的局域网IP</param>
/// <returns></returns> /// <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); var tunnelWanPort = tunnelWanPorts.FirstOrDefault(c => c.ProtocolType == protocolType);
if (tunnelWanPort == null) return null; if (tunnelWanPort == null) return null;
try try
{ {
if (tunnelAdapter.ServerHost == null) return null; TunnelWanPortEndPoint wanPort = await tunnelWanPort.GetAsync(localIP, server).ConfigureAwait(false);
TunnelWanPortEndPoint wanPort = await tunnelWanPort.GetAsync(localIP, tunnelAdapter.ServerHost).ConfigureAwait(false);
if (wanPort != null) if (wanPort != null)
{ {
wanPort.Local.Address = localIP; wanPort.Local.Address = localIP;

View File

@@ -146,7 +146,6 @@ namespace linker.config
public IConfig PropertyMethod { get; set; } public IConfig PropertyMethod { get; set; }
} }
public interface IConfig public interface IConfig
{ {
public string Serialize(object obj); public string Serialize(object obj);
@@ -217,7 +216,6 @@ namespace linker.config
} }
} }
[AttributeUsage(AttributeTargets.Class)] [AttributeUsage(AttributeTargets.Class)]
public class JsonAotAttribute : Attribute { } public class JsonAotAttribute : Attribute { }
} }

View File

@@ -12,7 +12,6 @@ namespace linker.plugins.relay.client
/// </summary> /// </summary>
public sealed class RelayTestTransfer public sealed class RelayTestTransfer
{ {
private readonly FileConfig fileConfig;
private readonly RelayTransfer relayTransfer; private readonly RelayTransfer relayTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly ClientConfigTransfer clientConfigTransfer; private readonly ClientConfigTransfer clientConfigTransfer;
@@ -20,9 +19,8 @@ namespace linker.plugins.relay.client
public List<RelayNodeReportInfo> Nodes { get; private set; } = new List<RelayNodeReportInfo>(); 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.relayTransfer = relayTransfer;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
this.clientConfigTransfer = clientConfigTransfer; this.clientConfigTransfer = clientConfigTransfer;

View File

@@ -54,17 +54,6 @@ namespace linker.plugins.socks5
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
LoggerHelper.Instance.Error(ex); 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; await Task.CompletedTask;
} }
/// <summary> /// <summary>

View File

@@ -1,46 +1,73 @@
using linker.client.config; using linker.plugins.tunnel.messenger;
using linker.config;
using linker.plugins.tunnel.messenger;
using linker.tunnel.adapter;
using linker.tunnel.transport; using linker.tunnel.transport;
using linker.libs; using linker.libs;
using MemoryPack; using MemoryPack;
using System.Net; using System.Net;
using System.Security.Cryptography.X509Certificates;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.messenger; using linker.plugins.messenger;
using linker.plugins.tunnel.excludeip; using linker.plugins.tunnel.excludeip;
using linker.tunnel.wanport;
using linker.tunnel;
namespace linker.plugins.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 ClientSignInState clientSignInState;
private readonly IMessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly TunnelExcludeIPTransfer excludeIPTransfer; private readonly TunnelExcludeIPTransfer excludeIPTransfer;
private readonly ClientConfigTransfer clientConfigTransfer; private readonly ClientConfigTransfer clientConfigTransfer;
private readonly TunnelConfigTransfer tunnelConfigTransfer; 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.clientSignInState = clientSignInState;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.excludeIPTransfer = excludeIPTransfer; this.excludeIPTransfer = excludeIPTransfer;
this.clientConfigTransfer = clientConfigTransfer; this.clientConfigTransfer = clientConfigTransfer;
this.tunnelConfigTransfer = tunnelConfigTransfer; this.tunnelConfigTransfer = tunnelConfigTransfer;
}
public List<TunnelTransportItemInfo> GetTunnelTransports() this.tunnelWanPortTransfer = tunnelWanPortTransfer;
this.tunnelUpnpTransfer = tunnelUpnpTransfer;
this.tunnelTransfer = tunnelTransfer;
tunnelWanPortTransfer.LoadTransports(new List<ITunnelWanPortProtocol>
{ {
return tunnelConfigTransfer.Transports; new TunnelWanPortProtocolLinkerUdp(),
} new TunnelWanPortProtocolLinkerTcp(),
public void SetTunnelTransports(List<TunnelTransportItemInfo> transports, bool updateVersion) });
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) =>
{ {
tunnelConfigTransfer.SetTransports(transports); RefreshPortMap();
};
tunnelConfigTransfer.OnChanged += RefreshPortMap;
} }
public NetworkInfo GetLocalConfig() public NetworkInfo GetLocalConfig()
@@ -70,6 +97,7 @@ namespace linker.plugins.tunnel
MachineId = clientConfigTransfer.Id MachineId = clientConfigTransfer.Id
}; };
} }
public async Task<TunnelTransportWanPortInfo> GetRemoteWanPort(TunnelWanPortProtocolInfo info) public async Task<TunnelTransportWanPortInfo> GetRemoteWanPort(TunnelWanPortProtocolInfo info)
{ {
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
@@ -118,5 +146,17 @@ namespace linker.plugins.tunnel
return true; return true;
} }
private void RefreshPortMap()
{
if (tunnelConfigTransfer.PortMapLan > 0)
{
tunnelUpnpTransfer.SetMap(tunnelConfigTransfer.PortMapLan, tunnelConfigTransfer.PortMapWan);
}
else
{
tunnelUpnpTransfer.SetMap(clientSignInState.Connection.LocalAddress.Address, 18180);
}
}
} }
} }

View File

@@ -1,6 +1,5 @@
using linker.config; using linker.config;
using linker.plugins.tunnel.messenger; using linker.plugins.tunnel.messenger;
using linker.tunnel.adapter;
using linker.tunnel.transport; using linker.tunnel.transport;
using linker.libs.api; using linker.libs.api;
using linker.libs.extends; using linker.libs.extends;
@@ -20,27 +19,23 @@ namespace linker.plugins.tunnel
/// </summary> /// </summary>
public sealed class TunnelApiController : IApiClientController public sealed class TunnelApiController : IApiClientController
{ {
private readonly FileConfig config;
private readonly TunnelWanPortTransfer compactTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly IMessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly TunnelConfigTransfer tunnelConfigTransfer; private readonly TunnelConfigTransfer tunnelConfigTransfer;
private readonly ITunnelAdapter tunnelMessengerAdapter;
private readonly TunnelExcludeIPTransfer excludeIPTransfer; private readonly TunnelExcludeIPTransfer excludeIPTransfer;
private readonly AccessTransfer accessTransfer; private readonly AccessTransfer accessTransfer;
private readonly ClientConfigTransfer clientConfigTransfer; 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.clientSignInState = clientSignInState;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.tunnelConfigTransfer = tunnelConfigTransfer; this.tunnelConfigTransfer = tunnelConfigTransfer;
this.tunnelMessengerAdapter = tunnelMessengerAdapter;
this.excludeIPTransfer = excludeIPTransfer; this.excludeIPTransfer = excludeIPTransfer;
this.accessTransfer = accessTransfer; this.accessTransfer = accessTransfer;
this.clientConfigTransfer = clientConfigTransfer; this.clientConfigTransfer = clientConfigTransfer;
this.tunnelDecenter = tunnelDecenter;
} }
/// <summary> /// <summary>
@@ -51,11 +46,11 @@ namespace linker.plugins.tunnel
public TunnelListInfo Get(ApiControllerParamsInfo param) public TunnelListInfo Get(ApiControllerParamsInfo param)
{ {
ulong hashCode = ulong.Parse(param.Content); 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 return new TunnelListInfo
{ {
List = tunnelConfigTransfer.Config, List = tunnelDecenter.Config,
HashCode = version HashCode = version
}; };
} }
@@ -67,7 +62,7 @@ namespace linker.plugins.tunnel
/// <param name="param"></param> /// <param name="param"></param>
public void Refresh(ApiControllerParamsInfo param) public void Refresh(ApiControllerParamsInfo param)
{ {
tunnelConfigTransfer.RefreshConfig(); tunnelDecenter.Refresh();
} }
/// <summary> /// <summary>
@@ -105,7 +100,7 @@ namespace linker.plugins.tunnel
/// <returns></returns> /// <returns></returns>
public List<TunnelTransportItemInfo> GetTransports(ApiControllerParamsInfo param) public List<TunnelTransportItemInfo> GetTransports(ApiControllerParamsInfo param)
{ {
return tunnelMessengerAdapter.GetTunnelTransports(); return tunnelConfigTransfer.Transports;
} }
/// <summary> /// <summary>
/// 设置打洞协议 /// 设置打洞协议
@@ -116,7 +111,7 @@ namespace linker.plugins.tunnel
public bool SetTransports(ApiControllerParamsInfo param) public bool SetTransports(ApiControllerParamsInfo param)
{ {
List<TunnelTransportItemInfo> info = param.Content.DeJson<List<TunnelTransportItemInfo>>(); List<TunnelTransportItemInfo> info = param.Content.DeJson<List<TunnelTransportItemInfo>>();
tunnelMessengerAdapter.SetTunnelTransports(info, true); tunnelConfigTransfer.SetTransports(info);
return true; return true;
} }

View File

@@ -1,5 +1,4 @@
using linker.config; using linker.libs;
using linker.libs;
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.client; using linker.plugins.client;
using linker.tunnel; using linker.tunnel;
@@ -7,7 +6,6 @@ using linker.tunnel.connection;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using linker.plugins.relay.client; using linker.plugins.relay.client;
using linker.plugins.pcp; using linker.plugins.pcp;
using linker.client.config;
namespace linker.plugins.tunnel namespace linker.plugins.tunnel
{ {

View File

@@ -2,26 +2,22 @@
using linker.config; using linker.config;
using linker.libs; using linker.libs;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.decenter;
using linker.plugins.messenger; using linker.plugins.messenger;
using linker.tunnel; using linker.tunnel;
using linker.tunnel.transport; using linker.tunnel.transport;
using MemoryPack;
using System.Collections.Concurrent;
using System.Net; using System.Net;
using System.Net.Quic; using System.Net.Quic;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
namespace linker.plugins.tunnel 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 int RouteLevel => config.Data.Client.Tunnel.RouteLevel + running.Data.Tunnel.RouteLevelPlus;
public IPAddress[] LocalIPs => config.Data.Client.Tunnel.LocalIPs; public IPAddress[] LocalIPs => config.Data.Client.Tunnel.LocalIPs;
public IPAddress[] RouteIPs => config.Data.Client.Tunnel.RouteIPs; 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 List<TunnelTransportItemInfo> Transports => config.Data.Client.Tunnel.Transports;
public X509Certificate2 Certificate { get; private set; } public X509Certificate2 Certificate { get; private set; }
@@ -32,8 +28,7 @@ namespace linker.plugins.tunnel
private readonly TunnelUpnpTransfer upnpTransfer; private readonly TunnelUpnpTransfer upnpTransfer;
private readonly ClientConfigTransfer clientConfigTransfer; private readonly ClientConfigTransfer clientConfigTransfer;
public VersionManager Version { get; } = new VersionManager(); public Action OnChanged { get; set; } = () => { };
public ConcurrentDictionary<string, TunnelTransportRouteLevelInfo> Config { get; } = new ConcurrentDictionary<string, TunnelTransportRouteLevelInfo>();
public TunnelConfigTransfer(FileConfig config, RunningConfig running, ClientSignInState clientSignInState, IMessengerSender messengerSender, TunnelUpnpTransfer upnpTransfer, ClientConfigTransfer clientConfigTransfer) 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) => clientSignInState.NetworkEnabledHandle += (times) =>
{ {
TimerHelper.Async(RefreshRouteLevel); TimerHelper.Async(RefreshRouteLevel);
RefreshPortMap();
}; };
TestQuic(); 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) public void SetTransports(List<TunnelTransportItemInfo> transports)
{ {
config.Data.Client.Tunnel.Transports = 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.RouteLevel = NetworkHelper.GetRouteLevel(clientConfigTransfer.Server.Host, out List<IPAddress> ips);
config.Data.Client.Tunnel.RouteIPs = ips.ToArray(); config.Data.Client.Tunnel.RouteIPs = ips.ToArray();
config.Data.Client.Tunnel.LocalIPs = NetworkHelper.GetIPV6().Concat(NetworkHelper.GetIPV4()).ToArray(); config.Data.Client.Tunnel.LocalIPs = NetworkHelper.GetIPV6().Concat(NetworkHelper.GetIPV4()).ToArray();
DataVersion.Add(); OnChanged();
} }
/// <summary>
/// 刷新关于隧道的配置信息,也就是获取自己的和别的客户端的,方便查看
/// </summary>
public void RefreshConfig()
{
DataVersion.Add();
}
/// <summary> /// <summary>
/// 修改自己的网关层级信息 /// 修改自己的网关层级信息
/// </summary> /// </summary>
@@ -116,10 +78,9 @@ namespace linker.plugins.tunnel
running.Data.Tunnel.PortMapWan = tunnelTransportFileConfigInfo.PortMapWan; running.Data.Tunnel.PortMapWan = tunnelTransportFileConfigInfo.PortMapWan;
running.Data.Tunnel.PortMapLan = tunnelTransportFileConfigInfo.PortMapLan; running.Data.Tunnel.PortMapLan = tunnelTransportFileConfigInfo.PortMapLan;
running.Data.Update(); running.Data.Update();
GetData(); OnChanged();
DataVersion.Add();
} }
private TunnelTransportRouteLevelInfo GetLocalRouteLevel() public TunnelTransportRouteLevelInfo GetLocalRouteLevel()
{ {
return new TunnelTransportRouteLevelInfo 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);
}
}
} }
} }

View 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();
}
}
}

View File

@@ -2,12 +2,9 @@
using linker.plugins.tunnel.messenger; using linker.plugins.tunnel.messenger;
using linker.startup; using linker.startup;
using linker.tunnel; using linker.tunnel;
using linker.tunnel.adapter;
using linker.tunnel.transport;
using linker.libs; using linker.libs;
using MemoryPack; using MemoryPack;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using System.Net;
using linker.tunnel.wanport; using linker.tunnel.wanport;
using linker.plugins.tunnel.excludeip; using linker.plugins.tunnel.excludeip;
using linker.plugins.client; using linker.plugins.client;
@@ -36,7 +33,6 @@ namespace linker.plugins.tunnel
MemoryPackFormatterProvider.Register(new TunnelTransportInfoFormatter()); MemoryPackFormatterProvider.Register(new TunnelTransportInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter()); MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter());
//管理接口 //管理接口
serviceCollection.AddSingleton<TunnelApiController>(); serviceCollection.AddSingleton<TunnelApiController>();
//命令接口 //命令接口
@@ -44,30 +40,18 @@ namespace linker.plugins.tunnel
//外网端口协议 //外网端口协议
serviceCollection.AddSingleton<TunnelWanPortTransfer>(); serviceCollection.AddSingleton<TunnelWanPortTransfer>();
serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerUdp>();
serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerTcp>();
//打洞协议 //打洞协议
serviceCollection.AddSingleton<TunnelTransfer>(); serviceCollection.AddSingleton<TunnelTransfer>();
serviceCollection.AddSingleton<TunnelTransportTcpNutssb>(); serviceCollection.AddSingleton<TunnelUpnpTransfer>();
serviceCollection.AddSingleton<TransportMsQuic>();
serviceCollection.AddSingleton<TransportTcpP2PNAT>();
serviceCollection.AddSingleton<TransportTcpPortMap>();
serviceCollection.AddSingleton<TransportUdpPortMap>();
serviceCollection.AddSingleton<TransportUdp>();
serviceCollection.AddSingleton<TunnelExcludeIPTransfer>(); serviceCollection.AddSingleton<TunnelExcludeIPTransfer>();
serviceCollection.AddSingleton<TunnelExcludeIPTypesLoader>(); serviceCollection.AddSingleton<TunnelExcludeIPTypesLoader>();
serviceCollection.AddSingleton<TunnelConfigTransfer>(); serviceCollection.AddSingleton<TunnelConfigTransfer>();
serviceCollection.AddSingleton<ITunnelAdapter, TunnelAdapter>();
serviceCollection.AddSingleton<TunnelUpnpTransfer>();
serviceCollection.AddSingleton<TunnelConfigSyncTransports>(); serviceCollection.AddSingleton<TunnelConfigSyncTransports>();
serviceCollection.AddSingleton<TunnelDecenter>();
serviceCollection.AddSingleton<TunnelConfigTransfer>(); serviceCollection.AddSingleton<TunnelAdapter>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
@@ -83,36 +67,14 @@ namespace linker.plugins.tunnel
public void UseClient(ServiceProvider serviceProvider, FileConfig config) 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>(); TunnelExcludeIPTransfer excludeIPTransfer = serviceProvider.GetService<TunnelExcludeIPTransfer>();
TunnelExcludeIPTypesLoader tunnelExcludeIPTypesLoader = serviceProvider.GetService<TunnelExcludeIPTypesLoader>(); TunnelExcludeIPTypesLoader tunnelExcludeIPTypesLoader = serviceProvider.GetService<TunnelExcludeIPTypesLoader>();
ClientConfigTransfer clientConfigTransfer = serviceProvider.GetService<ClientConfigTransfer>(); ClientConfigTransfer clientConfigTransfer = serviceProvider.GetService<ClientConfigTransfer>();
TunnelConfigTransfer tunnelConfigTransfer = serviceProvider.GetService<TunnelConfigTransfer>(); TunnelConfigTransfer tunnelConfigTransfer = serviceProvider.GetService<TunnelConfigTransfer>();
TunnelAdapter tunnelAdapter = serviceProvider.GetService<TunnelAdapter>();
LoggerHelper.Instance.Info($"tunnel route level getting."); LoggerHelper.Instance.Info($"tunnel route level getting.");
tunnelConfigTransfer.RefreshRouteLevel(); tunnelConfigTransfer.RefreshRouteLevel();
LoggerHelper.Instance.Warning($"route ips:{string.Join(",", tunnelConfigTransfer.RouteIPs.Select(c => c.ToString()))}"); LoggerHelper.Instance.Warning($"route ips:{string.Join(",", tunnelConfigTransfer.RouteIPs.Select(c => c.ToString()))}");

View File

@@ -5,7 +5,6 @@ using LiteDB;
using MemoryPack; using MemoryPack;
using System.Net; using System.Net;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using linker.tunnel.adapter;
namespace linker.client.config namespace linker.client.config

View File

@@ -1,8 +1,6 @@
using linker.client.config; using linker.client.config;
using linker.config; using linker.config;
using linker.libs;
using linker.plugins.client; using linker.plugins.client;
using MemoryPack;
namespace linker.plugins.tunnel.excludeip namespace linker.plugins.tunnel.excludeip
{ {

View File

@@ -1,7 +1,6 @@
using linker.config; using linker.config;
using linker.plugins.signin.messenger; using linker.plugins.signin.messenger;
using linker.tunnel; using linker.tunnel;
using linker.tunnel.adapter;
using linker.tunnel.transport; using linker.tunnel.transport;
using linker.libs; using linker.libs;
using MemoryPack; using MemoryPack;

View 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
};
}
}
}

View File

@@ -22,28 +22,30 @@ namespace linker.plugins.tuntap
private readonly IMessengerSender messengerSender; private readonly IMessengerSender messengerSender;
private readonly TuntapTransfer tuntapTransfer; private readonly TuntapTransfer tuntapTransfer;
private readonly ClientSignInState clientSignInState; private readonly ClientSignInState clientSignInState;
private readonly FileConfig config;
private readonly TuntapProxy tuntapProxy; private readonly TuntapProxy tuntapProxy;
private readonly RunningConfig runningConfig;
private readonly TuntapConfigTransfer tuntapConfigTransfer; private readonly TuntapConfigTransfer tuntapConfigTransfer;
private readonly LeaseClientTreansfer leaseClientTreansfer; private readonly LeaseClientTreansfer leaseClientTreansfer;
private readonly TuntapPingTransfer pingTransfer; private readonly TuntapPingTransfer pingTransfer;
private readonly AccessTransfer accessTransfer; private readonly AccessTransfer accessTransfer;
private readonly ClientConfigTransfer clientConfigTransfer; 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.messengerSender = messengerSender;
this.tuntapTransfer = tuntapTransfer; this.tuntapTransfer = tuntapTransfer;
this.clientSignInState = clientSignInState; this.clientSignInState = clientSignInState;
this.config = config;
this.tuntapProxy = tuntapProxy; this.tuntapProxy = tuntapProxy;
this.runningConfig = runningConfig;
this.tuntapConfigTransfer = tuntapConfigTransfer; this.tuntapConfigTransfer = tuntapConfigTransfer;
this.leaseClientTreansfer = leaseClientTreansfer; this.leaseClientTreansfer = leaseClientTreansfer;
this.pingTransfer = pingTransfer; this.pingTransfer = pingTransfer;
this.accessTransfer = accessTransfer; this.accessTransfer = accessTransfer;
this.clientConfigTransfer = clientConfigTransfer; this.clientConfigTransfer = clientConfigTransfer;
this.tuntapDecenter = tuntapDecenter;
this.tuntapAdapter = tuntapAdapter;
} }
public ConnectionListInfo Connections(ApiControllerParamsInfo param) public ConnectionListInfo Connections(ApiControllerParamsInfo param)
@@ -74,11 +76,11 @@ namespace linker.plugins.tuntap
public TuntabListInfo Get(ApiControllerParamsInfo param) public TuntabListInfo Get(ApiControllerParamsInfo param)
{ {
ulong hashCode = ulong.Parse(param.Content); 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 return new TuntabListInfo
{ {
List = tuntapConfigTransfer.Infos, List = tuntapDecenter.Infos,
HashCode = version HashCode = version
}; };
} }
@@ -90,7 +92,7 @@ namespace linker.plugins.tuntap
/// <param name="param"></param> /// <param name="param"></param>
public void Refresh(ApiControllerParamsInfo param) public void Refresh(ApiControllerParamsInfo param)
{ {
tuntapConfigTransfer.RefreshConfig(); tuntapDecenter.Refresh();
} }
/// <summary> /// <summary>
@@ -105,7 +107,7 @@ namespace linker.plugins.tuntap
{ {
if (accessTransfer.HasAccess(ClientApiAccess.TuntapStatusSelf) == false) return false; if (accessTransfer.HasAccess(ClientApiAccess.TuntapStatusSelf) == false) return false;
await tuntapConfigTransfer.RetstartDevice(); await tuntapAdapter.RetstartDevice();
} }
else else
{ {
@@ -131,7 +133,7 @@ namespace linker.plugins.tuntap
if (param.Content == clientConfigTransfer.Id) if (param.Content == clientConfigTransfer.Id)
{ {
if (accessTransfer.HasAccess(ClientApiAccess.TuntapStatusSelf) == false) return false; if (accessTransfer.HasAccess(ClientApiAccess.TuntapStatusSelf) == false) return false;
tuntapConfigTransfer.StopDevice(); tuntapAdapter.StopDevice();
} }
else else
{ {
@@ -160,7 +162,7 @@ namespace linker.plugins.tuntap
if (info.MachineId == clientConfigTransfer.Id) if (info.MachineId == clientConfigTransfer.Id)
{ {
if (accessTransfer.HasAccess(ClientApiAccess.TuntapChangeSelf) == false) return false; if (accessTransfer.HasAccess(ClientApiAccess.TuntapChangeSelf) == false) return false;
tuntapConfigTransfer.UpdateConfig(info); tuntapConfigTransfer.Update(info);
} }
else else
{ {

View File

@@ -1,413 +1,128 @@
using linker.client.config; using linker.client.config;
using linker.config;
using linker.libs; using linker.libs;
using MemoryPack;
using System.Collections.Concurrent;
using System.Net; using System.Net;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.messenger;
using linker.plugins.tuntap.config; using linker.plugins.tuntap.config;
using linker.tun;
using linker.plugins.tuntap.lease; using linker.plugins.tuntap.lease;
using linker.plugins.decenter;
using linker.plugins.tunnel;
namespace linker.plugins.tuntap namespace linker.plugins.tuntap
{ {
public sealed class TuntapConfigTransfer : IDecenter public sealed class TuntapConfigTransfer
{ {
public string Name => "tuntap"; public TuntapConfigInfo Info => runningConfig.Data.Tuntap;
public VersionManager DataVersion { get; } = new VersionManager(); 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"; public string DeviceName => "linker";
private readonly IMessengerSender messengerSender;
private readonly ClientSignInState clientSignInState;
private readonly RunningConfig runningConfig; private readonly RunningConfig runningConfig;
private readonly TuntapTransfer tuntapTransfer;
private readonly LeaseClientTreansfer leaseClientTreansfer; private readonly LeaseClientTreansfer leaseClientTreansfer;
private readonly ClientConfigTransfer clientConfigTransfer; private readonly ClientConfigTransfer clientConfigTransfer;
private readonly TunnelConfigTransfer tunnelConfigTransfer;
private LinkerTunDeviceRouteItem[] routeItems = new LinkerTunDeviceRouteItem[0]; public Action OnUpdate { get; set; } = () => { };
private List<LinkerTunDeviceForwardItem> forwardItems = new List<LinkerTunDeviceForwardItem>(); public Func<Task> OnChanged { get; set; } = async () => { await Task.CompletedTask; };
public VersionManager Version { get; } = new VersionManager(); public TuntapConfigTransfer(RunningConfig runningConfig, LeaseClientTreansfer leaseClientTreansfer, ClientConfigTransfer clientConfigTransfer)
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)
{ {
this.messengerSender = messengerSender;
this.clientSignInState = clientSignInState;
this.runningConfig = runningConfig; this.runningConfig = runningConfig;
this.tuntapTransfer = tuntapTransfer;
this.leaseClientTreansfer = leaseClientTreansfer; this.leaseClientTreansfer = leaseClientTreansfer;
this.clientConfigTransfer = clientConfigTransfer; 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>
/// 更新本机网卡信息 /// 保存启动状态,方便下次启动时自动启动网卡
/// </summary>
/// <param name="running"></param>
public void SetRunning(bool running)
{
Info.Running = running;
runningConfig.Data.Update();
OnUpdate();
}
/// <summary>
/// 更新本机网卡信息,会触发事件
/// </summary> /// </summary>
/// <param name="info"></param> /// <param name="info"></param>
public void UpdateConfig(TuntapInfo info) public void Update(TuntapInfo info)
{ {
TimerHelper.Async(async () => TimerHelper.Async(async () =>
{ {
IPAddress oldIP = configInfo.IP; IPAddress ip = Info.IP;
byte prefixLength = configInfo.PrefixLength; byte prefixLength = Info.PrefixLength;
configInfo.IP = info.IP ?? IPAddress.Any; Info.IP = info.IP ?? IPAddress.Any;
configInfo.Lans = info.Lans; Info.Lans = info.Lans;
configInfo.PrefixLength = info.PrefixLength; Info.PrefixLength = info.PrefixLength;
configInfo.Switch = info.Switch; Info.Switch = info.Switch;
configInfo.Forwards = info.Forwards; Info.Forwards = info.Forwards;
runningConfig.Data.Update(); 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(); 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(); await OnChanged();
}
else
{
AddForward();
} }
GetData(); OnUpdate();
DataVersion.Add();
}); });
} }
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> /// <summary>
/// 刷新IP /// 刷新IP会触发OnChanged事件
/// </summary> /// </summary>
public void RefreshIP() public void RefreshIP()
{ {
TimerHelper.Async(async () => TimerHelper.Async(async () =>
{ {
IPAddress oldIP = configInfo.IP; IPAddress oldIP = Info.IP;
byte prefixLength = configInfo.PrefixLength; byte prefixLength = Info.PrefixLength;
await LeaseIP(); await RefreshIPASync();
while (tuntapTransfer.Status == TuntapStatus.Operating)
if ((oldIP.Equals(Info.IP) == false || prefixLength != Info.PrefixLength) && Info.Running)
{ {
await Task.Delay(1000); await OnChanged();
} }
OnUpdate();
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();
}); });
} }
/// <summary> /// <summary>
/// 租赁IP /// 刷新IP不会触发OnChanged
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public async Task RefreshIPASync()
{
LoadGroupIP();
await LeaseIP();
SetGroupIP();
OnUpdate();
}
private async Task LeaseIP() 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;
if (tuntapGroup2IPInfo.IP.Equals(configInfo.IP) == false || tuntapGroup2IPInfo.PrefixLength != configInfo.PrefixLength) Info.PrefixLength = leaseInfo.PrefixLength;
{
configInfo.IP = tuntapGroup2IPInfo.IP;
configInfo.PrefixLength = tuntapGroup2IPInfo.PrefixLength;
}
}
LeaseInfo leaseInfo = await leaseClientTreansfer.LeaseIp(configInfo.IP, configInfo.PrefixLength);
configInfo.IP = leaseInfo.IP;
configInfo.PrefixLength = leaseInfo.PrefixLength;
runningConfig.Data.Update(); 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()
{
tuntapTransfer.Shutdown();
await LeaseIP();
tuntapTransfer.Setup(configInfo.IP, configInfo.PrefixLength);
}
/// <summary>
/// 关闭网卡
/// </summary>
public void StopDevice()
{
tuntapTransfer.Shutdown();
} }
private void LoadGroupIP()
// <summary>
/// 添加端口转发
/// </summary>
private void AddForward()
{ {
var temp = ParseForwardItems(); if (Info.Group2IP.TryGetValue(clientConfigTransfer.Group.Id, out TuntapGroup2IPInfo tuntapGroup2IPInfo))
var removes = forwardItems.Except(temp, new LinkerTunDeviceForwardItemComparer());
if (removes.Any())
{ {
tuntapTransfer.RemoveForward(removes.ToList()); if (tuntapGroup2IPInfo.IP.Equals(Info.IP) == false || tuntapGroup2IPInfo.PrefixLength != Info.PrefixLength)
{
Info.IP = tuntapGroup2IPInfo.IP;
Info.PrefixLength = tuntapGroup2IPInfo.PrefixLength;
} }
forwardItems = temp;
tuntapTransfer.AddForward(forwardItems);
} }
/// <summary>
/// 删除端口转发
/// </summary>
private void DeleteForward()
{
tuntapTransfer.RemoveForward(forwardItems);
} }
private List<LinkerTunDeviceForwardItem> ParseForwardItems() private void SetGroupIP()
{ {
return configInfo.Forwards.Select(c => new LinkerTunDeviceForwardItem { ListenAddr = c.ListenAddr, ListenPort = c.ListenPort, ConnectAddr = c.ConnectAddr, ConnectPort = c.ConnectPort }).ToList(); TuntapGroup2IPInfo tuntapGroup2IPInfo = new TuntapGroup2IPInfo { IP = Info.IP, PrefixLength = Info.PrefixLength };
Info.Group2IP.AddOrUpdate(clientConfigTransfer.Group.Id, tuntapGroup2IPInfo, (a, b) => tuntapGroup2IPInfo);
} }
/// <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
};
}
} }
} }

View 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();
}
});
}
}
}

View File

@@ -1,28 +1,25 @@
using linker.client.config; using linker.libs;
using linker.libs;
using linker.plugins.tuntap.config; using linker.plugins.tuntap.config;
using linker.tun;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
namespace linker.plugins.tuntap namespace linker.plugins.tuntap
{ {
public sealed class TuntapDeviceStatusTransfer public sealed class TuntapDeviceStatusTransfer
{ {
private readonly RunningConfig runningConfig;
private readonly TuntapTransfer tuntapTransfer; private readonly TuntapTransfer tuntapTransfer;
private readonly TuntapConfigTransfer tuntapConfigTransfer; private readonly TuntapConfigTransfer tuntapConfigTransfer;
private readonly LinkerTunDeviceAdapter linkerTunDeviceAdapter; private readonly TuntapAdapter tuntapAdapter;
private ulong setupTimes = 0; 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.tuntapTransfer = tuntapTransfer;
this.tuntapConfigTransfer = tuntapConfigTransfer; this.tuntapConfigTransfer = tuntapConfigTransfer;
this.linkerTunDeviceAdapter = linkerTunDeviceAdapter; this.tuntapAdapter = tuntapAdapter;
tuntapTransfer.OnSetupSuccess += () => { setupTimes++; }; tuntapTransfer.OnSetupSuccess += () => { setupTimes++; };
CheckTuntapStatusTask(); CheckTuntapStatusTask();
} }
private void CheckTuntapStatusTask() private void CheckTuntapStatusTask()
{ {
@@ -41,11 +38,10 @@ namespace linker.plugins.tuntap
if (await InterfaceAvailable() == false && tuntapTransfer.Status != TuntapStatus.Operating) if (await InterfaceAvailable() == false && tuntapTransfer.Status != TuntapStatus.Operating)
{ {
LoggerHelper.Instance.Error($"tuntap inerface {tuntapConfigTransfer.DeviceName} is down, restarting"); LoggerHelper.Instance.Error($"tuntap inerface {tuntapConfigTransfer.DeviceName} is down, restarting");
linkerTunDeviceAdapter.Shutdown();
await Task.Delay(5000).ConfigureAwait(false); await Task.Delay(5000).ConfigureAwait(false);
if (await InterfaceAvailable() == false && tuntapTransfer.Status != TuntapStatus.Operating) if (await InterfaceAvailable() == false && tuntapTransfer.Status != TuntapStatus.Operating)
{ {
await tuntapConfigTransfer.RetstartDevice(); await tuntapAdapter.RetstartDevice().ConfigureAwait(false);
} }
} }
} }
@@ -53,8 +49,8 @@ namespace linker.plugins.tuntap
{ {
NetworkInterface networkInterface = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(c => c.Name == tuntapConfigTransfer.DeviceName); NetworkInterface networkInterface = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(c => c.Name == tuntapConfigTransfer.DeviceName);
return networkInterface != null && networkInterface.OperationalStatus == OperationalStatus.Up && await InterfacePing(); return networkInterface != null && networkInterface.OperationalStatus == OperationalStatus.Up && await InterfacePing();
}
private async Task<bool> InterfacePing() async Task<bool> InterfacePing()
{ {
try try
{ {
@@ -67,6 +63,7 @@ namespace linker.plugins.tuntap
return false; return false;
} }
} }
}
private void InterfaceOrder() private void InterfaceOrder()
{ {

View File

@@ -1,10 +1,8 @@
using linker.client.config; using linker.libs;
using linker.libs;
using linker.plugins.tuntap.config; using linker.plugins.tuntap.config;
using linker.tunnel.connection; using linker.tunnel.connection;
using System.Net.NetworkInformation; using System.Net.NetworkInformation;
using System.Net; using System.Net;
using linker.config;
using System.Net.Sockets; using System.Net.Sockets;
using linker.libs.extends; using linker.libs.extends;
using linker.plugins.client; using linker.plugins.client;
@@ -17,19 +15,21 @@ namespace linker.plugins.tuntap
private readonly TuntapConfigTransfer tuntapConfigTransfer; private readonly TuntapConfigTransfer tuntapConfigTransfer;
private readonly TuntapProxy tuntapProxy; private readonly TuntapProxy tuntapProxy;
private readonly ClientConfigTransfer clientConfigTransfer; 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.tuntapTransfer = tuntapTransfer;
this.tuntapConfigTransfer = tuntapConfigTransfer; this.tuntapConfigTransfer = tuntapConfigTransfer;
this.tuntapProxy = tuntapProxy; this.tuntapProxy = tuntapProxy;
this.clientConfigTransfer = clientConfigTransfer; this.clientConfigTransfer = clientConfigTransfer;
this.tuntapDecenter = tuntapDecenter;
PingTask(); PingTask();
} }
private readonly LastTicksManager lastTicksManager = new LastTicksManager(); private readonly LastTicksManager lastTicksManager = new LastTicksManager();
private readonly LastTicksManager lastTicksManager1 = new LastTicksManager();
public void SubscribePing() public void SubscribePing()
{ {
lastTicksManager.Update(); lastTicksManager.Update();
@@ -49,7 +49,7 @@ namespace linker.plugins.tuntap
{ {
if (tuntapTransfer.Status == TuntapStatus.Running && (tuntapConfigTransfer.Switch & TuntapSwitch.ShowDelay) == TuntapSwitch.ShowDelay) 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) if ((tuntapConfigTransfer.Switch & TuntapSwitch.AutoConnect) != TuntapSwitch.AutoConnect)
{ {
var connections = tuntapProxy.GetConnections(); var connections = tuntapProxy.GetConnections();
@@ -61,7 +61,7 @@ namespace linker.plugins.tuntap
using Ping ping = new Ping(); using Ping ping = new Ping();
PingReply pingReply = await ping.SendPingAsync(c.IP, 500); PingReply pingReply = await ping.SendPingAsync(c.IP, 500);
c.Delay = pingReply.Status == IPStatus.Success ? (int)pingReply.RoundtripTime : -1; c.Delay = pingReply.Status == IPStatus.Success ? (int)pingReply.RoundtripTime : -1;
tuntapConfigTransfer.Version.Add(); tuntapDecenter.Version.Add();
})); }));
} }
} }

View File

@@ -1,5 +1,4 @@
using linker.config; using linker.tunnel;
using linker.tunnel;
using linker.tunnel.connection; using linker.tunnel.connection;
using linker.libs; using linker.libs;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@@ -9,38 +8,32 @@ using System.Buffers.Binary;
using linker.plugins.client; using linker.plugins.client;
using linker.plugins.tunnel; using linker.plugins.tunnel;
using System.Buffers; using System.Buffers;
using linker.client.config;
using linker.plugins.relay.client; using linker.plugins.relay.client;
using linker.plugins.pcp; using linker.plugins.pcp;
namespace linker.plugins.tuntap 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 uint[] maskValues = Array.Empty<uint>();
private readonly ConcurrentDictionary<uint, string> ip2MachineDic = new ConcurrentDictionary<uint, string>(); private readonly ConcurrentDictionary<uint, string> ip2MachineDic = new ConcurrentDictionary<uint, string>();
private readonly ConcurrentDictionary<uint, ITunnelConnection> ipConnections = new ConcurrentDictionary<uint, ITunnelConnection>(); private readonly ConcurrentDictionary<uint, ITunnelConnection> ipConnections = new ConcurrentDictionary<uint, ITunnelConnection>();
private readonly OperatingMultipleManager operatingMultipleManager = new OperatingMultipleManager(); private readonly OperatingMultipleManager operatingMultipleManager = new OperatingMultipleManager();
protected override string TransactionId => "tuntap";
private readonly LinkerTunDeviceAdapter linkerTunDeviceAdapter;
private HashSet<uint> ipRefreshCache = new HashSet<uint>(); private HashSet<uint> ipRefreshCache = new HashSet<uint>();
protected override string TransactionId => "tuntap";
private readonly ClientSignInTransfer clientSignInTransfer; public TuntapProxy(ClientConfigTransfer clientConfigTransfer,
private readonly TuntapConfigTransfer tuntapConfigTransfer; TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, PcpTransfer pcpTransfer,
ClientSignInTransfer clientSignInTransfer, TuntapTransfer tuntapTransfer, ClientSignInState clientSignInState,
public TuntapProxy(ClientConfigTransfer clientConfigTransfer, TunnelTransfer tunnelTransfer, RelayTransfer relayTransfer, PcpTransfer pcpTransfer, ClientSignInTransfer clientSignInTransfer, LinkerTunDeviceAdapter linkerTunDeviceAdapter, ClientSignInState clientSignInState,RelayClientConfigTransfer relayClientConfigTransfer, TuntapConfigTransfer tuntapConfigTransfer) RelayClientConfigTransfer relayClientConfigTransfer, TuntapConfigTransfer tuntapConfigTransfer)
: base(tunnelTransfer, relayTransfer, pcpTransfer, clientSignInTransfer, clientSignInState, clientConfigTransfer, relayClientConfigTransfer) : 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) protected override void Connected(ITunnelConnection connection)
@@ -64,8 +57,7 @@ namespace linker.plugins.tuntap
/// <returns></returns> /// <returns></returns>
public async Task Receive(ITunnelConnection connection, ReadOnlyMemory<byte> buffer, object state) public async Task Receive(ITunnelConnection connection, ReadOnlyMemory<byte> buffer, object state)
{ {
linkerTunDeviceAdapter.Write(buffer); await OnReceivePacket(connection, buffer).ConfigureAwait(false);
await Task.CompletedTask;
} }
/// <summary> /// <summary>
/// 隧道关闭 /// 隧道关闭
@@ -75,9 +67,8 @@ namespace linker.plugins.tuntap
/// <returns></returns> /// <returns></returns>
public async Task Closed(ITunnelConnection connection, object state) public async Task Closed(ITunnelConnection connection, object state)
{ {
tuntapConfigTransfer.RefreshConfig(); await OnTunnelClose(connection).ConfigureAwait(false);
Version.Add(); Version.Add();
await Task.CompletedTask;
} }
/// <summary> /// <summary>
@@ -85,12 +76,12 @@ namespace linker.plugins.tuntap
/// </summary> /// </summary>
/// <param name="packet"></param> /// <param name="packet"></param>
/// <returns></returns> /// <returns></returns>
public async Task Callback(LinkerTunDevicPacket packet) public async Task InputPacket(LinkerTunDevicPacket packet)
{ {
//IPV4广播组播、IPV6 多播 //IPV4广播组播、IPV6 多播
if (packet.IPV4Broadcast || packet.IPV6Multicast) 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))); 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); 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>
/// 打洞或者中继 /// 打洞或者中继
/// </summary> /// </summary>
@@ -199,7 +143,7 @@ namespace linker.plugins.tuntap
if (ipRefreshCache.Contains(ip) == false) if (ipRefreshCache.Contains(ip) == false)
{ {
ipRefreshCache.Add(ip); ipRefreshCache.Add(ip);
tuntapConfigTransfer.RefreshConfig(); OnIPNotFound(ip);
} }
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG) 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(); ip2MachineDic.Clear();
ipConnections.Clear(); ipConnections.Clear();
@@ -220,5 +167,52 @@ namespace linker.plugins.tuntap
LoggerHelper.Instance.Debug($"tuntap cache clear"); 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 _);
}
}
} }
} }

View File

@@ -36,7 +36,9 @@ namespace linker.plugins.tuntap
serviceCollection.AddSingleton<TuntapPingTransfer>(); serviceCollection.AddSingleton<TuntapPingTransfer>();
serviceCollection.AddSingleton<TuntapDeviceStatusTransfer>(); serviceCollection.AddSingleton<TuntapDeviceStatusTransfer>();
serviceCollection.AddSingleton<TuntapDecenter>();
serviceCollection.AddSingleton<TuntapAdapter>();
} }
public void AddServer(ServiceCollection serviceCollection, FileConfig config) public void AddServer(ServiceCollection serviceCollection, FileConfig config)
@@ -57,7 +59,7 @@ namespace linker.plugins.tuntap
TuntapPingTransfer tuntapPingTransfer = serviceProvider.GetService<TuntapPingTransfer>(); TuntapPingTransfer tuntapPingTransfer = serviceProvider.GetService<TuntapPingTransfer>();
TuntapDeviceStatusTransfer tuntapDeviceStatusTransfer = serviceProvider.GetService<TuntapDeviceStatusTransfer>(); TuntapDeviceStatusTransfer tuntapDeviceStatusTransfer = serviceProvider.GetService<TuntapDeviceStatusTransfer>();
tuntapTransfer.Init(tuntapConfigTransfer.DeviceName, tuntapProxy); TuntapAdapter tuntapAdapter = serviceProvider.GetService<TuntapAdapter>();
} }
public void UseServer(ServiceProvider serviceProvider, FileConfig config) public void UseServer(ServiceProvider serviceProvider, FileConfig config)

View File

@@ -1,7 +1,5 @@
using linker.client.config; using linker.libs;
using linker.libs;
using System.Net; using System.Net;
using linker.plugins.client;
using linker.plugins.tuntap.config; using linker.plugins.tuntap.config;
using linker.tun; using linker.tun;
@@ -28,12 +26,20 @@ namespace linker.plugins.tuntap
this.linkerTunDeviceAdapter = linkerTunDeviceAdapter; this.linkerTunDeviceAdapter = linkerTunDeviceAdapter;
} }
bool inited = false;
public void Init(string name,ILinkerTunDeviceCallback linkerTunDeviceCallback) public void Init(string name,ILinkerTunDeviceCallback linkerTunDeviceCallback)
{ {
if (inited) return;
inited = true;
linkerTunDeviceAdapter.Initialize(name, linkerTunDeviceCallback); linkerTunDeviceAdapter.Initialize(name, linkerTunDeviceCallback);
AppDomain.CurrentDomain.ProcessExit += (s, e) => linkerTunDeviceAdapter.Shutdown(); AppDomain.CurrentDomain.ProcessExit += (s, e) => linkerTunDeviceAdapter.Shutdown();
Console.CancelKeyPress += (s, e) => linkerTunDeviceAdapter.Shutdown(); Console.CancelKeyPress += (s, e) => linkerTunDeviceAdapter.Shutdown();
} }
public bool Write(ReadOnlyMemory<byte> buffer)
{
return linkerTunDeviceAdapter.Write(buffer);
}
/// <summary> /// <summary>
/// 运行网卡 /// 运行网卡

View File

@@ -4,7 +4,6 @@ using System.Net;
using linker.libs; using linker.libs;
using MemoryPack; using MemoryPack;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using linker.libs.extends;
namespace linker.plugins.tuntap.lease namespace linker.plugins.tuntap.lease
{ {

View File

@@ -17,8 +17,10 @@ namespace linker.plugins.tuntap.messenger
private readonly LeaseClientTreansfer leaseClientTreansfer; private readonly LeaseClientTreansfer leaseClientTreansfer;
private readonly TuntapPingTransfer pingTransfer; private readonly TuntapPingTransfer pingTransfer;
private readonly IMessengerSender messengerSender; 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.tuntapTransfer = tuntapTransfer;
this.tuntapConfigTransfer = tuntapConfigTransfer; this.tuntapConfigTransfer = tuntapConfigTransfer;
@@ -26,6 +28,7 @@ namespace linker.plugins.tuntap.messenger
this.leaseClientTreansfer = leaseClientTreansfer; this.leaseClientTreansfer = leaseClientTreansfer;
this.pingTransfer = pingTransfer; this.pingTransfer = pingTransfer;
this.messengerSender = messengerSender; this.messengerSender = messengerSender;
this.tuntapAdapter = tuntapAdapter;
} }
/// <summary> /// <summary>
@@ -35,7 +38,7 @@ namespace linker.plugins.tuntap.messenger
[MessengerId((ushort)TuntapMessengerIds.Run)] [MessengerId((ushort)TuntapMessengerIds.Run)]
public void Run(IConnection connection) public void Run(IConnection connection)
{ {
_ = tuntapConfigTransfer.RetstartDevice(); _ = tuntapAdapter.RetstartDevice();
} }
/// <summary> /// <summary>
@@ -45,7 +48,7 @@ namespace linker.plugins.tuntap.messenger
[MessengerId((ushort)TuntapMessengerIds.Stop)] [MessengerId((ushort)TuntapMessengerIds.Stop)]
public void Stop(IConnection connection) public void Stop(IConnection connection)
{ {
tuntapConfigTransfer.StopDevice(); tuntapAdapter.StopDevice();
} }
/// <summary> /// <summary>
@@ -56,7 +59,7 @@ namespace linker.plugins.tuntap.messenger
public void Update(IConnection connection) public void Update(IConnection connection)
{ {
TuntapInfo info = MemoryPackSerializer.Deserialize<TuntapInfo>(connection.ReceiveRequestWrap.Payload.Span); TuntapInfo info = MemoryPackSerializer.Deserialize<TuntapInfo>(connection.ReceiveRequestWrap.Payload.Span);
tuntapConfigTransfer.UpdateConfig(info); tuntapConfigTransfer.Update(info);
} }
/// <summary> /// <summary>

View File

@@ -1,5 +1,5 @@
v1.6.3 v1.6.3
2024-12-12 00:29:09 2024-12-12 17:37:53
1. 优化UI显示网络计算IP数 1. 优化UI显示网络计算IP数
2. 修复内网穿透不停止直接删除导致的无法再次添加的问题 2. 修复内网穿透不停止直接删除导致的无法再次添加的问题
3. 优化网卡的端口转发 3. 优化网卡的端口转发