新增打洞协议,一种同时打开的TCP打洞方法

This commit is contained in:
snltty
2024-07-03 16:25:49 +08:00
parent f4a7545ae9
commit 1eba41ed73
17 changed files with 98 additions and 58 deletions

View File

@@ -15,8 +15,8 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<Version>1.1.1</Version>
<AssemblyVersion>1.1.1.1</AssemblyVersion>
<FileVersion>1.1.1.1</FileVersion>
<AssemblyVersion>1.1.1.2</AssemblyVersion>
<FileVersion>1.1.1.2</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>

View File

@@ -14,6 +14,16 @@
<PublishAot>true</PublishAot>
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
<EnablePreviewFeatures>true</EnablePreviewFeatures>
<Version>1.1.1</Version>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>snltty</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>snltty service</PackageReleaseNotes>
<AssemblyVersion>1.1.1.2</AssemblyVersion>
<FileVersion>1.1.1.2</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -170,8 +170,8 @@ namespace linker.tunnel
LoggerHelper.Instance.Error($"tunnel {transport.Name} get remote {remoteMachineId} external ip fail ");
break;
}
LoggerHelper.Instance.Info($"tunnel {transport.Name} got local external ip {localInfo.ToJson()}");
LoggerHelper.Instance.Info($"tunnel {transport.Name} got remote external ip {remoteInfo.ToJson()}");
LoggerHelper.Instance.Info($"tunnel {transport.Name} got local external ip {localInfo.Result.ToJson()}");
LoggerHelper.Instance.Info($"tunnel {transport.Name} got remote external ip {remoteInfo.Result.ToJson()}");
tunnelTransportInfo = new TunnelTransportInfo
@@ -265,10 +265,7 @@ namespace linker.tunnel
public void OnFail(TunnelTransportInfo tunnelTransportInfo)
{
ITunnelTransport _transports = transports.FirstOrDefault(c => c.Name == tunnelTransportInfo.TransportName && c.ProtocolType == tunnelTransportInfo.TransportType);
if (_transports != null)
{
_transports.OnFail(tunnelTransportInfo);
}
_transports?.OnFail(tunnelTransportInfo);
}
/// <summary>
/// 收到对方发来的连接成功的消息
@@ -277,10 +274,7 @@ namespace linker.tunnel
public void OnSuccess(TunnelTransportInfo tunnelTransportInfo)
{
ITunnelTransport _transports = transports.FirstOrDefault(c => c.Name == tunnelTransportInfo.TransportName && c.ProtocolType == tunnelTransportInfo.TransportType);
if (_transports != null)
{
_transports.OnSuccess(tunnelTransportInfo);
}
_transports?.OnSuccess(tunnelTransportInfo);
}
/// <summary>
@@ -290,6 +284,7 @@ namespace linker.tunnel
public async Task<TunnelTransportWanPortInfo> GetWanPort(TunnelWanPortProtocolInfo _info)
{
TunnelWanPortInfo info = tunnelAdapter.GetTunnelWanPortProtocols().FirstOrDefault(c => c.Type == _info.Type && c.ProtocolType == _info.ProtocolType);
if (info == null) return null;
return await GetLocalInfo(info).ConfigureAwait(false);
}

View File

@@ -17,8 +17,8 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker tunnel</PackageReleaseNotes>
<AssemblyVersion>1.1.1.1</AssemblyVersion>
<FileVersion>1.1.1.1</FileVersion>
<AssemblyVersion>1.1.1.2</AssemblyVersion>
<FileVersion>1.1.1.2</FileVersion>
</PropertyGroup>
<ItemGroup>

View File

@@ -224,11 +224,6 @@ namespace linker.tunnel.proxy
{
if (token.Proxy.TargetEP == null) return;
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Warning($"connect {token.Proxy.ConnectId} {token.Proxy.TargetEP}");
}
Socket socket = new Socket(token.Proxy.TargetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.KeepAlive();
@@ -258,11 +253,7 @@ namespace linker.tunnel.proxy
token.Socket.EndConnect(result);
token.Socket.KeepAlive();
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Warning($"connect {token.Proxy.ConnectId} {token.Proxy.TargetEP} success");
}
if (state.Data.Length > 0)
{
await token.Socket.SendAsync(state.Data.AsMemory(0, state.Length), SocketFlags.None).ConfigureAwait(false);

View File

@@ -18,9 +18,9 @@ namespace linker.tunnel.transport
public string Label => "TCP、同时打开";
public TunnelProtocolType ProtocolType => TunnelProtocolType.Tcp;
public TunnelWanPortProtocolType AllowWanPortProtocolType => TunnelWanPortProtocolType.Tcp;
public bool Reverse => false;
public bool Reverse => true;
public bool DisableReverse => true;
public bool DisableReverse => false;
public bool SSL => true;
@@ -65,7 +65,10 @@ namespace linker.tunnel.transport
{
return null;
}
await Task.Delay(50).ConfigureAwait(false);
if(tunnelTransportInfo.Direction == TunnelDirection.Reverse)
{
await Task.Delay(50).ConfigureAwait(false);
}
ITunnelConnection connection = await ConnectForward(tunnelTransportInfo, TunnelMode.Client).ConfigureAwait(false);
if (connection != null)
{

View File

@@ -68,6 +68,7 @@ namespace linker.tunnel.wanport
{
public TunnelWanPortType Value { get; set; }
public string Name { get; set; }
public Dictionary<int, string> Protocols { get; set; } = new Dictionary<int, string>();
}
public sealed class TunnelWanPortTypeInfoEqualityComparer : IEqualityComparer<TunnelWanPortTypeInfo>

View File

@@ -75,8 +75,8 @@ namespace linker.tunnel.wanport
try
{
Socket socket = new Socket(server.AddressFamily, SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
socket.Reuse(true);
await socket.ConnectAsync(server).ConfigureAwait(false);
await socket.SendAsync(new byte[] { 0 });
int length = await socket.ReceiveAsync(buffer.AsMemory(), SocketFlags.None).ConfigureAwait(false);

View File

@@ -1,4 +1,5 @@
using linker.libs;
using linker.libs.extends;
using System.Diagnostics;
using System.Net;
@@ -27,7 +28,14 @@ namespace linker.tunnel.wanport
public List<TunnelWanPortTypeInfo> GetTypes()
{
return tunnelWanPorts.Select(c => new TunnelWanPortTypeInfo { Value = c.Type, Name = c.Type.ToString() }).Distinct(new TunnelWanPortTypeInfoEqualityComparer()).ToList();
List<TunnelWanPortTypeInfo> res = tunnelWanPorts.Select(c => new TunnelWanPortTypeInfo
{
Value = c.Type,
Name = c.Type.ToString(),
Protocols = tunnelWanPorts
.Where(d => d.Type == c.Type).ToList().Select(d => d.ProtocolType).Distinct().ToDictionary(c => (int)c, d => d.ToString()),
}).Distinct(new TunnelWanPortTypeInfoEqualityComparer()).ToList();
return res;
}
/// <summary>
@@ -39,6 +47,7 @@ namespace linker.tunnel.wanport
{
if (info == null) return null;
var tunnelWanPort = tunnelWanPorts.FirstOrDefault(c => c.Type == info.Type && c.ProtocolType == info.ProtocolType);
if (tunnelWanPort == null) return null;
try
{
Stopwatch sw = new Stopwatch();
@@ -49,11 +58,11 @@ namespace linker.tunnel.wanport
{
LoggerHelper.Instance.Warning($"get domain ip time:{sw.ElapsedMilliseconds}ms");
}
TunnelWanPortEndPoint WanPort = await tunnelWanPort.GetAsync(server).ConfigureAwait(false);
if (WanPort != null)
TunnelWanPortEndPoint wanPort = await tunnelWanPort.GetAsync(server).ConfigureAwait(false);
if (wanPort != null)
{
WanPort.Local.Address = localIP;
return WanPort;
wanPort.Local.Address = localIP;
return wanPort;
}
}
catch (Exception ex)

View File

@@ -21,7 +21,7 @@
<template #default="scope">
<div>
<el-select v-model="scope.row.ProtocolType" placeholder="Select" size="small" @change="handleEditBlur(scope.row, 'ProtocolType')">
<el-option v-for="(item,index) in state.protocolTypes" :key="+index" :label="item" :value="+index"/>
<el-option v-for="(item,index) in scope.row.Protocols" :key="+index" :label="item" :value="+index"/>
</el-select>
</div>
@@ -87,17 +87,26 @@ import { computed, onMounted, reactive } from 'vue'
export default {
setup(props) {
const globalData = injectGlobalData();
const list = ((globalData.value.config.Running.Tunnel || {Servers:[]}).Servers || []).sort((a,b)=>a.Disabled - b.Disabled);
const state = reactive({
list:((globalData.value.config.Running.Tunnel || {Servers:[]}).Servers || []).sort((a,b)=>a.Disabled - b.Disabled),
list:list,
types:[],
height: computed(()=>globalData.value.height-130),
sync:true,
protocolTypes:{1:'tcp',2:'udp'},
sync:true
});
const _getTunnelTypes = ()=>{
getTunnelTypes().then((res)=>{
state.types = res;
initProtocols(state.list);
});
}
const initProtocols = (list)=>{
list.forEach(c=>{
c.Protocols = state.types.filter(d=>d.Value == c.Type)[0].Protocols;
if(!c.Protocols[c.ProtocolType]){
c.ProtocolType = +Object.keys(c.Protocols)[0];
}
});
}
@@ -105,6 +114,7 @@ export default {
handleEdit(row, column.property);
}
const handleEdit = (row, p) => {
initProtocols([row])
state.list.forEach(c => {
c[`NameEditing`] = false;
c[`TypeEditing`] = false;
@@ -114,6 +124,7 @@ export default {
row[`${p}Editing`] = true;
}
const handleEditBlur = (row, p) => {
initProtocols([row])
row[`${p}Editing`] = false;
handleSave();
}
@@ -126,7 +137,10 @@ export default {
if(state.list.filter(c=>c.Host == '' || c.Name == '').length > 0){
return;
}
state.list.splice(index+1,0,{Name:'',Host:'',Type:0,Disabled:false,ProtocolType:2});
const row = {Name:'',Host:'',Type:0,Disabled:false,ProtocolType:2};
initProtocols([row]);
state.list.splice(index+1,0,row);
handleSave();
}

View File

@@ -25,8 +25,8 @@
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>
<PackageReleaseNotes>linker</PackageReleaseNotes>
<AssemblyVersion>1.1.1.1</AssemblyVersion>
<FileVersion>1.1.1.1</FileVersion>
<AssemblyVersion>1.1.1.2</AssemblyVersion>
<FileVersion>1.1.1.2</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">

View File

@@ -42,11 +42,11 @@ namespace linker.plugins.tunnel
public List<TunnelWanPortInfo> GetTunnelWanPortProtocols()
{
return running.Data.Tunnel.Servers.ToList();
return running.Data.Tunnel.Servers;
}
public void SetTunnelWanPortProtocols(List<TunnelWanPortInfo> compacts)
{
running.Data.Tunnel.Servers = compacts.ToArray();
running.Data.Tunnel.Servers = compacts;
running.Data.Update();
}

View File

@@ -82,7 +82,7 @@ namespace linker.plugins.tunnel
{
SetServersParamInfo info = param.Content.DeJson<SetServersParamInfo>();
tunnelMessengerAdapter.SetTunnelWanPortProtocols(info.List.ToList());
tunnelMessengerAdapter.SetTunnelWanPortProtocols(info.List);
if (info.Sync)
{
await messengerSender.SendOnly(new MessageRequestWrap
@@ -179,7 +179,7 @@ namespace linker.plugins.tunnel
public sealed class SetServersParamInfo
{
public bool Sync { get; set; }
public TunnelWanPortInfo[] List { get; set; } = Array.Empty<TunnelWanPortInfo>();
public List<TunnelWanPortInfo> List { get; set; } =new List<TunnelWanPortInfo>();
}
public sealed class SetTransportsParamInfo

View File

@@ -33,17 +33,27 @@ namespace linker.plugins.tunnel
GetRemoveRouteLevel();
};
if (running.Data.Tunnel.Servers.Length == 0)
if (running.Data.Tunnel.Servers.FirstOrDefault(c => c.Type == TunnelWanPortType.Linker && c.ProtocolType == TunnelWanPortProtocolType.Udp) == null)
{
running.Data.Tunnel.Servers = new TunnelWanPortInfo[]
running.Data.Tunnel.Servers.Add(new TunnelWanPortInfo
{
new TunnelWanPortInfo{
Name="Linker Udp",
Type= TunnelWanPortType.Linker,
Disabled = false,
Host = running.Data.Client.Servers.FirstOrDefault().Host,
}
};
Name = "Linker Udp",
Type = TunnelWanPortType.Linker,
ProtocolType = TunnelWanPortProtocolType.Udp,
Disabled = false,
Host = running.Data.Client.Servers.FirstOrDefault().Host,
});
}
if (running.Data.Tunnel.Servers.FirstOrDefault(c => c.Type == TunnelWanPortType.Linker && c.ProtocolType == TunnelWanPortProtocolType.Tcp) == null)
{
running.Data.Tunnel.Servers.Add(new TunnelWanPortInfo
{
Name = "Linker Tcp",
Type = TunnelWanPortType.Linker,
ProtocolType = TunnelWanPortProtocolType.Tcp,
Disabled = false,
Host = running.Data.Client.Servers.FirstOrDefault().Host,
});
}
}

View File

@@ -34,6 +34,8 @@ namespace linker.plugins.tunnel
MemoryPackFormatterProvider.Register(new TunnelTransportWanPortInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportItemInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter());
//管理接口
serviceCollection.AddSingleton<TunnelApiController>();
@@ -43,6 +45,7 @@ namespace linker.plugins.tunnel
//外网端口协议
serviceCollection.AddSingleton<TunnelWanPortTransfer>();
serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerUdp>();
serviceCollection.AddSingleton<TunnelWanPortProtocolLinkerTcp>();
serviceCollection.AddSingleton<TunnelWanPortProtocolStun>();
//打洞协议
@@ -69,6 +72,7 @@ namespace linker.plugins.tunnel
MemoryPackFormatterProvider.Register(new TunnelTransportWanPortInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportItemInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelTransportInfoFormatter());
MemoryPackFormatterProvider.Register(new TunnelWanPortProtocolInfoFormatter());
serviceCollection.AddSingleton<TunnelServerMessenger>();
}

View File

@@ -19,7 +19,7 @@ namespace linker.client.config
public sealed class TunnelRunningInfo
{
public ObjectId Id { get; set; }
public TunnelWanPortInfo[] Servers { get; set; } = Array.Empty<TunnelWanPortInfo>();
public List<TunnelWanPortInfo> Servers { get; set; } = new List<TunnelWanPortInfo>();
public int RouteLevelPlus { get; set; } = 0;
public ExcludeIPItem[] ExcludeIPs { get; set; } = Array.Empty<ExcludeIPItem>();
@@ -128,6 +128,9 @@ namespace linker.config
[MemoryPackInclude]
TunnelWanPortType Type => tunnelCompactInfo.Type;
[MemoryPackInclude]
TunnelWanPortProtocolType ProtocolType => tunnelCompactInfo.ProtocolType;
[MemoryPackInclude]
string Host => tunnelCompactInfo.Host;
@@ -135,9 +138,9 @@ namespace linker.config
bool Disabled => tunnelCompactInfo.Disabled;
[MemoryPackConstructor]
SerializableTunnelWanPortInfo(string name, TunnelWanPortType type, string host, bool disabled)
SerializableTunnelWanPortInfo(string name, TunnelWanPortType type, TunnelWanPortProtocolType protocolType, string host, bool disabled)
{
var tunnelCompactInfo = new TunnelWanPortInfo { Name = name, Type = type, Host = host, Disabled = disabled };
var tunnelCompactInfo = new TunnelWanPortInfo { Name = name, Type = type, ProtocolType = protocolType, Host = host, Disabled = disabled };
this.tunnelCompactInfo = tunnelCompactInfo;
}

View File

@@ -95,8 +95,8 @@ namespace linker.plugins.tunnel.messenger
[MessengerId((ushort)TunnelMessengerIds.Servers)]
public void Servers(IConnection connection)
{
TunnelWanPortInfo[] servers = MemoryPackSerializer.Deserialize<TunnelWanPortInfo[]>(connection.ReceiveRequestWrap.Payload.Span);
tunnelMessengerAdapter.SetTunnelWanPortProtocols(servers.ToList());
List<TunnelWanPortInfo> servers = MemoryPackSerializer.Deserialize<List<TunnelWanPortInfo>>(connection.ReceiveRequestWrap.Payload.Span);
tunnelMessengerAdapter.SetTunnelWanPortProtocols(servers);
}
[MessengerId((ushort)TunnelMessengerIds.ExcludeIPs)]