无缝切换隧道

This commit is contained in:
snltty
2024-09-17 16:31:53 +08:00
parent 045ac1d02f
commit 0537febeeb
6 changed files with 43 additions and 34 deletions

View File

@@ -37,7 +37,7 @@ jobs:
release_name: v1.3.8.${{ steps.date.outputs.today }}
draft: false
prerelease: false
body: "1. 优化隧道连接逻辑,先中继,成功则后台打洞,失败则立即打洞\r\n2. 测试中,请勿更新"
body: "1. 优化隧道连接逻辑,先中继,成功则后台打洞,后台打洞成功则切换隧道,中继失败则立即打洞\r\n2. 虚拟网卡可能会丢失一两个包TCP不会断开连接\r\n3. 端口转发,在发送数据包失败后,会尝试切换隧道再次发送,无缝切换隧道"
- name: upload-win-x86-oss
id: upload-win-x86-oss
uses: tvrcgo/oss-action@v0.1.1

View File

@@ -19,8 +19,9 @@
<Title>linker</Title>
<Authors>snltty</Authors>
<Company>snltty</Company>
<Description>1. 优化隧道连接逻辑,先中继,成功则后台打洞,失败则立即打洞
2. 测试中,请勿更新</Description>
<Description>1. 优化隧道连接逻辑,先中继,成功则后台打洞,后台打洞成功则切换隧道,中继失败则立即打洞
2. 虚拟网卡可能会丢失一两个包TCP不会断开连接
3. 端口转发,在发送数据包失败后,会尝试切换隧道再次发送,无缝切换隧道</Description>
<Copyright>snltty</Copyright>
<PackageProjectUrl>https://github.com/snltty/linker</PackageProjectUrl>
<RepositoryUrl>https://github.com/snltty/linker</RepositoryUrl>

View File

@@ -183,7 +183,9 @@ namespace linker.plugins.forward.proxy
await ConnectTunnelConnection(token).ConfigureAwait(false);
res = await token.Connection.SendAsync(connectData.AsMemory(0, length)).ConfigureAwait(false);
if (res == false)
{
CloseClientSocket(token, 5);
}
}
}
catch (Exception)
@@ -232,6 +234,7 @@ namespace linker.plugins.forward.proxy
Connection = state.Connection,
Socket = state.Socket,
Buffer = new byte[(1 << state.BufferSize) * 1024],
Proxy = new ProxyInfo
{
ConnectId = state.ConnectId,
@@ -345,25 +348,6 @@ namespace linker.plugins.forward.proxy
}
token.Clear();
}
private void CloseClientSocketTcp(ITunnelConnection connection)
{
int hashcode1 = connection.RemoteMachineId.GetHashCode();
int hashcode2 = connection.TransactionId.GetHashCode();
var tokens = tcpConnections.Where(c => c.Key.hashcode1 == hashcode1 && c.Key.hashcode2 == hashcode2).ToList();
foreach (var item in tokens)
{
try
{
if (tcpConnections.TryRemove(item.Key, out AsyncUserToken token))
{
token.Clear();
}
}
catch (Exception)
{
}
}
}
private void StopTcp()
{

View File

@@ -89,12 +89,20 @@ namespace linker.plugins.forward.proxy
/// <returns></returns>
private async ValueTask<bool> ConnectTunnelConnection(AsyncUserToken token)
{
if (caches.TryGetValue(token.ListenPort, out ForwardProxyCacheInfo cache))
if (token.ListenPort > 0)
{
token.Proxy.TargetEP = cache.TargetEP;
cache.Connection = await ConnectTunnel(cache.MachineId, TunnelProtocolType.Udp).ConfigureAwait(false);
token.Connection = cache.Connection;
if (caches.TryGetValue(token.ListenPort, out ForwardProxyCacheInfo cache))
{
token.Proxy.TargetEP = cache.TargetEP;
cache.Connection = await ConnectTunnel(cache.MachineId, TunnelProtocolType.Udp).ConfigureAwait(false);
token.Connection = cache.Connection;
}
}
else if (token.Connection != null)
{
token.Connection = await ConnectTunnel(token.Connection.RemoteMachineId, TunnelProtocolType.Udp).ConfigureAwait(false);
}
return true;
}
/// <summary>
@@ -104,12 +112,20 @@ namespace linker.plugins.forward.proxy
/// <returns></returns>
private async ValueTask ConnectTunnelConnection(AsyncUserUdpToken token)
{
if (caches.TryGetValue(token.ListenPort, out ForwardProxyCacheInfo cache))
if (token.ListenPort > 0)
{
token.Proxy.TargetEP = cache.TargetEP;
cache.Connection = await ConnectTunnel(cache.MachineId, TunnelProtocolType.Udp).ConfigureAwait(false);
token.Connection = cache.Connection;
if (caches.TryGetValue(token.ListenPort, out ForwardProxyCacheInfo cache))
{
token.Proxy.TargetEP = cache.TargetEP;
cache.Connection = await ConnectTunnel(cache.MachineId, TunnelProtocolType.Udp).ConfigureAwait(false);
token.Connection = cache.Connection;
}
}
else if (token.Connection != null)
{
token.Connection = await ConnectTunnel(token.Connection.RemoteMachineId, TunnelProtocolType.Udp).ConfigureAwait(false);
}
}
/// <summary>

View File

@@ -32,7 +32,14 @@ namespace linker.plugins.tuntap.proxy
protected override void Connected(ITunnelConnection connection)
{
connection.BeginReceive(this, null);
ipConnections.Clear();
//有哪些目标IP用了相同目标隧道更新一下
List<uint> keys = ipConnections.Where(c => c.Value.RemoteMachineId == connection.RemoteMachineId).Select(c => c.Key).ToList();
foreach (uint ip in keys)
{
ipConnections.AddOrUpdate(ip, connection, (a, b) => connection);
};
//ipConnections.Clear();
}
/// <summary>
/// 收到隧道数据

View File

@@ -1,4 +1,5 @@
v1.3.8
2024-09-17 14:57:51
1. 优化隧道连接逻辑,先中继,成功则后台打洞,失败则立即打洞
2. 测试中,请勿更新
2024-09-17 16:31:53
1. 优化隧道连接逻辑,先中继,成功则后台打洞,后台打洞成功则切换隧道,中继失败则立即打洞
2. 虚拟网卡可能会丢失一两个包TCP不会断开连接
3. 端口转发,在发送数据包失败后,会尝试切换隧道再次发送,无缝切换隧道