mirror of
https://github.com/snltty/linker.git
synced 2025-09-27 05:25:57 +08:00
修复优化socks5,解决CPU爆炸问题,支持域名和HTTP代理
This commit is contained in:
@@ -63,6 +63,7 @@
|
|||||||
- **网段映射:** 当多个设备不同的局域网使用相同的内网网段(如`192.168.1.0/24`)存在冲突时,网段映射可以让你继续顺利的使用点对网和网对网,例如配置`192.168.188.0/24->192.168.1.0/24`,就可以使用`192.168.188.2`访问`192.168.1.2`。
|
- **网段映射:** 当多个设备不同的局域网使用相同的内网网段(如`192.168.1.0/24`)存在冲突时,网段映射可以让你继续顺利的使用点对网和网对网,例如配置`192.168.188.0/24->192.168.1.0/24`,就可以使用`192.168.188.2`访问`192.168.1.2`。
|
||||||
- **应用层NAT:** 内置了使用`WinDivert`实现的应用层NAT,即使在`win7/8,win server2008/2012`这样的老系统无法使用系统NAT时也可以顺利使用点对网和网对网。
|
- **应用层NAT:** 内置了使用`WinDivert`实现的应用层NAT,即使在`win7/8,win server2008/2012`这样的老系统无法使用系统NAT时也可以顺利使用点对网和网对网。
|
||||||
- **应用层防火墙:** 内置了防火墙功能,应用于虚拟网卡、端口转发、socks5,可以精细控制客户端的访问权限,例如只允许A访问B的3389,其它客户端无法访问
|
- **应用层防火墙:** 内置了防火墙功能,应用于虚拟网卡、端口转发、socks5,可以精细控制客户端的访问权限,例如只允许A访问B的3389,其它客户端无法访问
|
||||||
|
- **远程唤醒:** 可以通过`WOL魔术包、USB COM继电器、USB HID继电器`远程唤醒局域网内的设备
|
||||||
|
|
||||||
##### 其它特性
|
##### 其它特性
|
||||||
- **UI管理:** 简洁明了的web管理页面
|
- **UI管理:** 简洁明了的web管理页面
|
||||||
@@ -86,11 +87,13 @@
|
|||||||
<details>
|
<details>
|
||||||
<summary><strong>感谢名单</strong></summary>
|
<summary><strong>感谢名单</strong></summary>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
- 米多贝克&米多网络工程
|
- 米多贝克&米多网络工程
|
||||||
- 阳阳
|
- 阳阳
|
||||||
- 谢幕____(海那边的白月光)
|
- 谢幕____(海那边的白月光)
|
||||||
- swayer.
|
- swayer.
|
||||||
- 浅浅
|
- 浅浅
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
@@ -9,10 +9,12 @@ sidebar_position: 96
|
|||||||
<details>
|
<details>
|
||||||
<summary><strong>感谢名单</strong></summary>
|
<summary><strong>感谢名单</strong></summary>
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
- 米多贝克&米多网络工程
|
- 米多贝克&米多网络工程
|
||||||
- 阳阳
|
- 阳阳
|
||||||
- 谢幕____(海那边的白月光)
|
- 谢幕____(海那边的白月光)
|
||||||
- swayer.
|
- swayer.
|
||||||
- 浅浅
|
- 浅浅
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</details>
|
</details>
|
@@ -34,7 +34,7 @@ namespace linker.messenger.socks5
|
|||||||
this.signInClientTransfer = signInClientTransfer;
|
this.signInClientTransfer = signInClientTransfer;
|
||||||
this.linkerFirewall = linkerFirewall;
|
this.linkerFirewall = linkerFirewall;
|
||||||
TaskUdp();
|
TaskUdp();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -97,6 +97,9 @@ namespace linker.messenger.socks5
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte[] hostBytes = Encoding.UTF8.GetBytes("Host: ");
|
||||||
|
byte[] newlineBytes = Encoding.UTF8.GetBytes("\r\n");
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// tcp连接隧道
|
/// tcp连接隧道
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -112,7 +115,27 @@ namespace linker.messenger.socks5
|
|||||||
token.Proxy.Data = token.Buffer.AsMemory(0, length);
|
token.Proxy.Data = token.Buffer.AsMemory(0, length);
|
||||||
token.Proxy.TargetEP = null;
|
token.Proxy.TargetEP = null;
|
||||||
|
|
||||||
|
if (token.Proxy.Data.Span.IndexOf(hostBytes) >= 0)
|
||||||
|
{
|
||||||
|
return await ProcessHttp(token).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
return await ProcessSocks5(token).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
private async Task<bool> ProcessHttp(AsyncUserToken token)
|
||||||
|
{
|
||||||
|
int start = token.Proxy.Data.Span.IndexOf(hostBytes) + hostBytes.Length;
|
||||||
|
int end = token.Proxy.Data.Span.Slice(start).IndexOf(newlineBytes);
|
||||||
|
string host = Encoding.UTF8.GetString(token.Proxy.Data.Span.Slice(start, end));
|
||||||
|
|
||||||
|
IPEndPoint target = await NetworkHelper.GetEndPointAsync(host, 80);
|
||||||
|
token.Proxy.TargetEP = target;
|
||||||
|
uint targetIp = NetworkHelper.ToValue(target.Address);
|
||||||
|
token.Connection = await ConnectTunnel(targetIp).ConfigureAwait(false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
private async Task<bool> ProcessSocks5(AsyncUserToken token)
|
||||||
|
{
|
||||||
//步骤,request
|
//步骤,request
|
||||||
token.Proxy.Rsv = (byte)Socks5EnumStep.Request;
|
token.Proxy.Rsv = (byte)Socks5EnumStep.Request;
|
||||||
if (await ReceiveCommandData(token).ConfigureAwait(false) == false)
|
if (await ReceiveCommandData(token).ConfigureAwait(false) == false)
|
||||||
@@ -121,7 +144,6 @@ namespace linker.messenger.socks5
|
|||||||
}
|
}
|
||||||
await token.Socket.SendAsync(new byte[] { 0x05, 0x00 }).ConfigureAwait(false);
|
await token.Socket.SendAsync(new byte[] { 0x05, 0x00 }).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
||||||
//步骤,command
|
//步骤,command
|
||||||
token.Proxy.Data = Helper.EmptyArray;
|
token.Proxy.Data = Helper.EmptyArray;
|
||||||
token.Proxy.Rsv = (byte)Socks5EnumStep.Command;
|
token.Proxy.Rsv = (byte)Socks5EnumStep.Command;
|
||||||
@@ -137,7 +159,6 @@ namespace linker.messenger.socks5
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//获取远端地址
|
//获取远端地址
|
||||||
uint targetIp;
|
uint targetIp;
|
||||||
ReadOnlyMemory<byte> ipArray = Socks5Parser.GetRemoteEndPoint(token.Proxy.Data, out Socks5EnumAddressType addressType, out ushort port, out int index);
|
ReadOnlyMemory<byte> ipArray = Socks5Parser.GetRemoteEndPoint(token.Proxy.Data, out Socks5EnumAddressType addressType, out ushort port, out int index);
|
||||||
@@ -152,7 +173,8 @@ namespace linker.messenger.socks5
|
|||||||
//解析域名
|
//解析域名
|
||||||
if (addressType == Socks5EnumAddressType.Domain)
|
if (addressType == Socks5EnumAddressType.Domain)
|
||||||
{
|
{
|
||||||
if (IPAddress.TryParse(Encoding.UTF8.GetString(ipArray.Span), out IPAddress ip) == false)
|
IPAddress ip = NetworkHelper.GetDomainIp(Encoding.UTF8.GetString(ipArray.Span));
|
||||||
|
if (ip == null)
|
||||||
{
|
{
|
||||||
byte[] response1 = Socks5Parser.MakeConnectResponse(new IPEndPoint(IPAddress.Any, 0), (byte)Socks5EnumResponseCommand.AddressNotAllow);
|
byte[] response1 = Socks5Parser.MakeConnectResponse(new IPEndPoint(IPAddress.Any, 0), (byte)Socks5EnumResponseCommand.AddressNotAllow);
|
||||||
await token.Socket.SendAsync(response1.AsMemory()).ConfigureAwait(false);
|
await token.Socket.SendAsync(response1.AsMemory()).ConfigureAwait(false);
|
||||||
@@ -166,7 +188,6 @@ namespace linker.messenger.socks5
|
|||||||
token.Proxy.TargetEP = new IPEndPoint(new IPAddress(ipArray.Span), port);
|
token.Proxy.TargetEP = new IPEndPoint(new IPAddress(ipArray.Span), port);
|
||||||
targetIp = BinaryPrimitives.ReadUInt32BigEndian(ipArray.Span);
|
targetIp = BinaryPrimitives.ReadUInt32BigEndian(ipArray.Span);
|
||||||
}
|
}
|
||||||
|
|
||||||
//连接隧道
|
//连接隧道
|
||||||
token.Connection = await ConnectTunnel(targetIp).ConfigureAwait(false);
|
token.Connection = await ConnectTunnel(targetIp).ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -177,6 +198,7 @@ namespace linker.messenger.socks5
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// udp连接隧道
|
/// udp连接隧道
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -252,7 +274,9 @@ namespace linker.messenger.socks5
|
|||||||
//太短
|
//太短
|
||||||
while ((validate & EnumProxyValidateDataResult.TooShort) == EnumProxyValidateDataResult.TooShort)
|
while ((validate & EnumProxyValidateDataResult.TooShort) == EnumProxyValidateDataResult.TooShort)
|
||||||
{
|
{
|
||||||
totalLength += await token.Socket.ReceiveAsync(token.Buffer.AsMemory(totalLength), SocketFlags.None).ConfigureAwait(false);
|
int length = await token.Socket.ReceiveAsync(token.Buffer.AsMemory(totalLength), SocketFlags.None).ConfigureAwait(false);
|
||||||
|
if (length == 0) return false;
|
||||||
|
totalLength += length;
|
||||||
token.Proxy.Data = token.Buffer.AsMemory(0, totalLength);
|
token.Proxy.Data = token.Buffer.AsMemory(0, totalLength);
|
||||||
validate = ValidateData(token.Proxy);
|
validate = ValidateData(token.Proxy);
|
||||||
}
|
}
|
||||||
|
@@ -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.299" ProductVersion="0.0.0.299" 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.301" ProductVersion="0.0.0.301" 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"/>
|
||||||
|
BIN
src/linker.tray.win/dist/linker.tray.win.exe
vendored
BIN
src/linker.tray.win/dist/linker.tray.win.exe
vendored
Binary file not shown.
@@ -83,11 +83,14 @@ mainForm.showPopmenu = function(){
|
|||||||
tray.message = 0xACCF;
|
tray.message = 0xACCF;
|
||||||
mainForm.popmenu=win.ui.popmenu(mainForm);
|
mainForm.popmenu=win.ui.popmenu(mainForm);
|
||||||
|
|
||||||
mainForm.popmenu.add(mainForm.ckAutoStart.checked ? '取消托盘自启动':'开启托盘自启动',function(id){mainForm.runAsTaskCommand()});
|
mainForm.popmenu.add(mainForm.ckAutoStart.checked ? '取消自启动':'开启自启动',function(id){mainForm.runAsTaskCommand()});
|
||||||
|
mainForm.popmenu.add('-------------',function(id){});
|
||||||
mainForm.popmenu.add(service.isRunning(mainForm.serviceName) ? '停止服务':'运行服务',function(id){mainForm.runCommand()});
|
mainForm.popmenu.add(service.isRunning(mainForm.serviceName) ? '停止服务':'运行服务',function(id){mainForm.runCommand()});
|
||||||
mainForm.popmenu.add(service.isExist(mainForm.serviceName) ? '卸载服务':'安装服务',function(id){mainForm.installCommand()});
|
mainForm.popmenu.add(service.isExist(mainForm.serviceName) ? '卸载服务':'安装服务',function(id){mainForm.installCommand()});
|
||||||
|
mainForm.popmenu.add('-------------',function(id){});
|
||||||
mainForm.popmenu.add('管理(简单)',function(id){mainForm.showNetFrm();});
|
mainForm.popmenu.add('管理(简单)',function(id){mainForm.showNetFrm();});
|
||||||
mainForm.popmenu.add('管理(专业)',function(id){mainForm.showFullFrm();});
|
mainForm.popmenu.add('管理(专业)',function(id){mainForm.showFullFrm();});
|
||||||
|
mainForm.popmenu.add('-------------',function(id){});
|
||||||
mainForm.popmenu.add('退出托盘',function(id){
|
mainForm.popmenu.add('退出托盘',function(id){
|
||||||
win.quitMessage();
|
win.quitMessage();
|
||||||
mainForm.close();
|
mainForm.close();
|
||||||
@@ -265,14 +268,6 @@ mainForm.setInterval(
|
|||||||
if(io.exist(io._exefile+".temp"))
|
if(io.exist(io._exefile+".temp"))
|
||||||
{
|
{
|
||||||
mainForm.reStart();
|
mainForm.reStart();
|
||||||
/*
|
|
||||||
var prcs = process.popen.cmd("tasklist | findstr "+mainForm.serviceName);
|
|
||||||
var str = prcs.readAll();
|
|
||||||
if(!!!string.indexOf(str,mainForm.serviceName))
|
|
||||||
{
|
|
||||||
mainForm.reStart();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}catch(e)
|
}catch(e)
|
||||||
{
|
{
|
||||||
@@ -286,12 +281,10 @@ mainForm.setInterval(
|
|||||||
return true;
|
return true;
|
||||||
},1000
|
},1000
|
||||||
)
|
)
|
||||||
|
|
||||||
mainForm.show();
|
mainForm.show();
|
||||||
win.setTopmost(mainForm.hwnd);
|
win.setTopmost(mainForm.hwnd);
|
||||||
if(_ARGV["task"])
|
if(_ARGV["task"])
|
||||||
{
|
{
|
||||||
mainForm.show(false);
|
mainForm.show(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return win.loopMessage();
|
return win.loopMessage();
|
@@ -80,13 +80,12 @@ namespace linker
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
json = JsonDocument.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(args[0])));
|
json = JsonDocument.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(args[0])));
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
if (args.Length > 0)
|
if (args.Length > 0)
|
||||||
{
|
{
|
||||||
LoggerHelper.Instance.Error(Encoding.UTF8.GetString(Convert.FromBase64String(args[0])));
|
LoggerHelper.Instance.Error(args[0]);
|
||||||
LoggerHelper.Instance.Error($"args parse fail {ex}");
|
LoggerHelper.Instance.Error($"args parse fail {ex}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
v1.8.2
|
v1.8.2
|
||||||
2025-06-07 22:43:27
|
2025-06-09 16:34:38
|
||||||
1. 一些累计更新
|
1. 一些累计更新
|
||||||
2. 重建权限存储,ulong改为BitArray,同组所有客户端需保持版本一致
|
2. 重建权限存储,ulong改为BitArray,同组所有客户端需保持版本一致
|
||||||
3. 增加唤醒功能,支持WOL,COM继电器,HID继电器
|
3. 增加唤醒功能,支持WOL,COM继电器,HID继电器
|
||||||
|
Reference in New Issue
Block a user