mirror of
https://github.com/snltty/linker.git
synced 2026-03-31 10:40:50 +08:00
修复TCP代理BUG
This commit is contained in:
@@ -30,7 +30,7 @@ for %%r in (win-x86,win-x64,win-arm64) do (
|
||||
echo F|xcopy "src\\linker\\wintun-%%r.dll" "public\\extends\\%%r\\linker-%%r\\wintun.dll" /s /f /h /y
|
||||
)
|
||||
|
||||
for %%r in (win-x86,win-x64,win-arm64,linux-x64,linux-arm,linux-arm64,linux-musl-x64,linux-musl-arm,linux-musl-arm64,osx-x64,osx-arm64) do (
|
||||
for %%r in (win-x86,win-x64,win-arm64,linux-x64,linux-arm,linux-arm64,linux-musl-x64,linux-musl-arm,linux-musl-arm64) do (
|
||||
|
||||
dotnet publish ./src/linker -c release -f net8.0 -o ./public/publish/%%r/linker-%%r -r %%r -p:PublishSingleFile=true --self-contained true -p:TrimMode=partial -p:TieredPGO=true -p:DebugType=full -p:EventSourceSupport=false -p:DebugSymbols=true -p:EnableCompressionInSingleFile=true -p:DebuggerSupport=false -p:EnableUnsafeBinaryFormatterSerialization=false -p:EnableUnsafeUTF7Encoding=false -p:HttpActivityPropagationSupport=false -p:InvariantGlobalization=true -p:MetadataUpdaterSupport=false -p:UseSystemResourceKeys=true -p:MetricsSupport=false -p:StackTraceSupport=false -p:XmlResolverIsNetworkingEnabledByDefault=false
|
||||
echo F|xcopy "public\\extends\\%%r\\linker-%%r\\*" "public\\publish\\%%r\\linker-%%r\\*" /s /f /h /y
|
||||
|
||||
@@ -56,7 +56,11 @@ namespace linker.libs
|
||||
using Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
|
||||
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
|
||||
socket.Bind(new IPEndPoint(IPAddress.Any, 0));
|
||||
return (ushort)(socket.LocalEndPoint as IPEndPoint).Port;
|
||||
ushort port = (ushort)(socket.LocalEndPoint as IPEndPoint).Port;
|
||||
|
||||
socket.SafeClose();
|
||||
|
||||
return port;
|
||||
}
|
||||
|
||||
public static IPAddress GetDomainIp(string domain)
|
||||
|
||||
@@ -10,26 +10,32 @@
|
||||
/// </summary>
|
||||
/// <param name="userid"></param>
|
||||
/// <returns></returns>
|
||||
public Task<List<string>> Get(string userid);
|
||||
public Task<List<RelayWhiteListItem>> GetNodes(string userid);
|
||||
/// <summary>
|
||||
/// 是否存在于白名单
|
||||
/// 获取白名单
|
||||
/// </summary>
|
||||
/// <param name="userid"></param>
|
||||
/// <param name="nodeid"></param>
|
||||
/// <returns></returns>
|
||||
public Task<bool> Contains(string userid, string nodeid);
|
||||
public Task<List<double>> GetBandwidth(string userid,string nodeid);
|
||||
}
|
||||
|
||||
public sealed class RelayServerWhiteListStore : IRelayServerWhiteListStore
|
||||
{
|
||||
public async Task<bool> Contains(string userid, string nodeid)
|
||||
public async Task<List<RelayWhiteListItem>> GetNodes(string userid)
|
||||
{
|
||||
return await Task.FromResult(false);
|
||||
return await Task.FromResult(new List<RelayWhiteListItem>());
|
||||
}
|
||||
|
||||
public async Task<List<string>> Get(string userid)
|
||||
public async Task<List<double>> GetBandwidth(string userid, string nodeid)
|
||||
{
|
||||
return await Task.FromResult(new List<string>());
|
||||
return await Task.FromResult(new List<double>());
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RelayWhiteListItem
|
||||
{
|
||||
public string[] Nodes { get; set; } = [];
|
||||
public double Bandwidth { get; set; } = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using linker.libs;
|
||||
using linker.libs.extends;
|
||||
using linker.libs.timer;
|
||||
using linker.messenger.relay.client.transport;
|
||||
using linker.messenger.relay.messenger;
|
||||
@@ -54,7 +53,7 @@ namespace linker.messenger.relay.server
|
||||
ToId = to.Id,
|
||||
ToName = to.MachineName,
|
||||
GroupId = to.GroupId,
|
||||
Validated = from.Super,
|
||||
Super = from.Super,
|
||||
UserId = from.UserId,
|
||||
};
|
||||
if (relayCaching.TryAdd($"{cache.FromId}->{cache.ToId}->{flowingId}", cache, 15000) == false)
|
||||
@@ -68,11 +67,20 @@ namespace linker.messenger.relay.server
|
||||
{
|
||||
if (relayCaching.TryGetValue(key, out RelayCacheInfo cache) && reports.TryGetValue(nodeid, out var node))
|
||||
{
|
||||
cache.Validated = cache.Validated || await relayServerWhiteListStore.Contains(cache.UserId, node.Id);
|
||||
if (cache.Validated == false)
|
||||
var bandwidth = await relayServerWhiteListStore.GetBandwidth(cache.UserId, node.Id);
|
||||
if (bandwidth.Any(c => c < 0))
|
||||
{
|
||||
cache.Cdkey = (await relayServerCdkeyStore.GetAvailable(cache.UserId).ConfigureAwait(false)).Select(c => new RelayCdkeyInfo { Bandwidth = c.Bandwidth, Id = c.Id, LastBytes = c.LastBytes }).ToList();
|
||||
if (cache.Cdkey.Count == 0 && node.Public == false) return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
cache.Bandwidth = bandwidth.Count > 0
|
||||
? bandwidth.Any(c => c == 0) ? 0 : bandwidth.Max()
|
||||
: cache.Super ? 0 : node.MaxBandwidth;
|
||||
|
||||
cache.Cdkey = (await relayServerCdkeyStore.GetAvailable(cache.UserId).ConfigureAwait(false)).Select(c => new RelayCdkeyInfo { Bandwidth = c.Bandwidth, Id = c.Id, LastBytes = c.LastBytes }).ToList();
|
||||
if (cache.Cdkey.Count == 0 && node.Public == false && cache.Super == false && bandwidth.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
@@ -179,7 +187,7 @@ namespace linker.messenger.relay.server
|
||||
/// <returns></returns>
|
||||
public async Task<List<RelayServerNodeReportInfo188>> GetNodes(bool validated, string userid)
|
||||
{
|
||||
var nodes = await relayServerWhiteListStore.Get(userid);
|
||||
var nodes = (await relayServerWhiteListStore.GetNodes(userid)).Where(c => c.Bandwidth >= 0).SelectMany(c => c.Nodes);
|
||||
|
||||
var result = reports.Values
|
||||
.Where(c => Environment.TickCount64 - c.LastTicks < 15000)
|
||||
@@ -216,8 +224,6 @@ namespace linker.messenger.relay.server
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 消耗流量
|
||||
/// </summary>
|
||||
|
||||
@@ -72,7 +72,12 @@ namespace linker.messenger.relay.server
|
||||
}).ConfigureAwait(false);
|
||||
if (resp.Code == MessageResponeCodes.OK && resp.Data.Length > 0)
|
||||
{
|
||||
return serializer.Deserialize<RelayCacheInfo>(resp.Data.Span);
|
||||
RelayCacheInfo result = serializer.Deserialize<RelayCacheInfo>(resp.Data.Span);
|
||||
if (result.Bandwidth < 0)
|
||||
{
|
||||
result.Bandwidth = Node.MaxBandwidth;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -136,12 +141,6 @@ namespace linker.messenger.relay.server
|
||||
/// <returns></returns>
|
||||
public bool Validate(RelayCacheInfo relayCache)
|
||||
{
|
||||
//已认证的没有流量限制
|
||||
if (relayCache.Validated) return true;
|
||||
if (Node.Public == false) return false;
|
||||
//流量卡有的,就能继续用
|
||||
if (relayCache.Cdkey.Any(c => c.LastBytes > 0)) return true;
|
||||
|
||||
return ValidateConnection(relayCache) && ValidateBytes(relayCache);
|
||||
}
|
||||
/// <summary>
|
||||
@@ -192,8 +191,6 @@ namespace linker.messenger.relay.server
|
||||
/// <returns></returns>
|
||||
public bool NeedLimit(RelayTrafficCacheInfo relayCache)
|
||||
{
|
||||
if (relayCache.Cache.Validated) return false;
|
||||
//if (relayCache.CurrentCdkey != null) return false;
|
||||
return limitTotal.NeedLimit();
|
||||
}
|
||||
/// <summary>
|
||||
@@ -242,9 +239,6 @@ namespace linker.messenger.relay.server
|
||||
{
|
||||
Interlocked.Add(ref bytes, length);
|
||||
|
||||
//验证过的,不消耗流量
|
||||
if (cache.Cache.Validated) return true;
|
||||
//节点无流量限制的,不消耗流量
|
||||
if (Node.MaxGbTotal == 0) return true;
|
||||
|
||||
Interlocked.Add(ref cache.Sendt, length);
|
||||
@@ -261,23 +255,24 @@ namespace linker.messenger.relay.server
|
||||
/// <param name="relayCache"></param>
|
||||
private void SetLimit(RelayTrafficCacheInfo relayCache)
|
||||
{
|
||||
relayCache.CurrentCdkey = relayCache.Cache.Cdkey.Where(c => c.LastBytes > 0).OrderByDescending(c => c.Bandwidth).FirstOrDefault();
|
||||
//黑白名单
|
||||
if (relayCache.Cache.Bandwidth >= 0)
|
||||
{
|
||||
relayCache.Limit.SetLimit((uint)Math.Ceiling(relayCache.Cache.Bandwidth * 1024 * 1024 / 8.0));
|
||||
return;
|
||||
}
|
||||
|
||||
//无限制
|
||||
if (relayCache.Cache.Validated || Node.MaxBandwidth == 0)
|
||||
if (relayCache.Cache.Super || Node.MaxBandwidth == 0)
|
||||
{
|
||||
relayCache.Limit.SetLimit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
RelayCdkeyInfo currentCdkey = relayCache.Cache.Cdkey.Where(c => c.LastBytes > 0).OrderByDescending(c => c.Bandwidth).FirstOrDefault();
|
||||
//有cdkey,且带宽大于节点带宽,就用cdkey的带宽
|
||||
if (currentCdkey != null && (currentCdkey.Bandwidth == 0 || currentCdkey.Bandwidth >= Node.MaxBandwidth || Node.MaxGbTotalLastBytes == 0))
|
||||
{
|
||||
relayCache.CurrentCdkey = currentCdkey;
|
||||
relayCache.Limit.SetLimit((uint)Math.Ceiling((relayCache.CurrentCdkey.Bandwidth * 1024 * 1024) / 8.0));
|
||||
return;
|
||||
}
|
||||
relayCache.CurrentCdkey = null;
|
||||
relayCache.Limit.SetLimit((uint)Math.Ceiling((Node.MaxBandwidth * 1024 * 1024) / 8.0));
|
||||
//配置或cdkey,最大的
|
||||
double banwidth = double.Max(Node.MaxBandwidth, relayCache.CurrentCdkey?.Bandwidth ?? 1);
|
||||
relayCache.Limit.SetLimit((uint)Math.Ceiling(banwidth * 1024 * 1024 / 8.0));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -319,7 +314,7 @@ namespace linker.messenger.relay.server
|
||||
}
|
||||
private async Task UploadBytes()
|
||||
{
|
||||
var cdkeys = trafficDict.Values.Where(c => c.CurrentCdkey != null && c.Sendt > 0).ToList();
|
||||
var cdkeys = trafficDict.Values.Where(c => c.CurrentCdkey != null && c.Sendt > 0 && c.CurrentCdkey.Id > 0).ToList();
|
||||
Dictionary<int, long> id2sent = cdkeys.GroupBy(c => c.CurrentCdkey.Id).ToDictionary(c => c.Key, d => d.Sum(d => { d.SendtCache = d.Sendt; return d.SendtCache; }));
|
||||
if (id2sent.Count == 0) return;
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace linker.messenger.relay.server
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
RelayUdpStep step = (RelayUdpStep)memory.Span[0];
|
||||
memory = memory.Slice(1);
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace linker.messenger.relay.server
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
using IMemoryOwner<byte> buffer = MemoryPool<byte>.Shared.Rent(16);
|
||||
buffer.Memory.Span[0] = 0;
|
||||
buffer.Memory.Span[1] = 1;
|
||||
@@ -78,7 +78,7 @@ namespace linker.messenger.relay.server
|
||||
byte flagLength = memory.Span[0];
|
||||
if (memory.Length < flagLength + 1 || memory.Slice(1, flagLength).Span.SequenceEqual(relayFlag) == false)
|
||||
{
|
||||
await socket.SendToAsync(buffer.Memory.Slice(1,1), ep).ConfigureAwait(false);
|
||||
await socket.SendToAsync(buffer.Memory.Slice(1, 1), ep).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace linker.messenger.relay.server
|
||||
{
|
||||
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||
LoggerHelper.Instance.Error($"relay {relayMessage.Type} get cache fail,flowid:{relayMessage.FlowId}");
|
||||
await socket.SendAsync(buffer.Memory.Slice(1,1)).ConfigureAwait(false);
|
||||
await socket.SendAsync(buffer.Memory.Slice(1, 1)).ConfigureAwait(false);
|
||||
socket.SafeClose();
|
||||
return;
|
||||
}
|
||||
@@ -430,9 +430,11 @@ namespace linker.messenger.relay.server
|
||||
public string ToId { get; set; }
|
||||
public string ToName { get; set; }
|
||||
public string GroupId { get; set; }
|
||||
public bool Validated { get; set; }
|
||||
public bool Super { get; set; }
|
||||
public List<RelayCdkeyInfo> Cdkey { get; set; } = [];
|
||||
|
||||
public double Bandwidth { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 仅本地缓存可用
|
||||
/// </summary>
|
||||
|
||||
@@ -752,14 +752,17 @@ namespace linker.messenger.serializer.memorypack
|
||||
string GroupId => info.GroupId;
|
||||
|
||||
[MemoryPackInclude]
|
||||
bool Validated => info.Validated;
|
||||
bool Super => info.Super;
|
||||
|
||||
|
||||
[MemoryPackInclude, MemoryPackAllowSerialize]
|
||||
List<RelayCdkeyInfo> Cdkey => info.Cdkey;
|
||||
|
||||
[MemoryPackInclude]
|
||||
double Bandwidth => info.Bandwidth;
|
||||
|
||||
[MemoryPackConstructor]
|
||||
SerializableRelayCacheInfo(ulong flowId, string fromId, string fromName, string toId, string toName, string groupId, bool validated, List<RelayCdkeyInfo> cdkey)
|
||||
SerializableRelayCacheInfo(ulong flowId, string fromId, string fromName, string toId, string toName, string groupId, bool super, List<RelayCdkeyInfo> cdkey, double bandwidth)
|
||||
{
|
||||
var info = new RelayCacheInfo
|
||||
{
|
||||
@@ -770,7 +773,8 @@ namespace linker.messenger.serializer.memorypack
|
||||
ToId = toId,
|
||||
ToName = toName,
|
||||
Cdkey = cdkey,
|
||||
Validated = validated
|
||||
Super = super,
|
||||
Bandwidth = bandwidth
|
||||
};
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
@@ -532,14 +532,17 @@ namespace linker.messenger.serializer.memorypack
|
||||
string GroupId => info.GroupId;
|
||||
|
||||
[MemoryPackInclude]
|
||||
bool Validated => info.Validated;
|
||||
bool Validated => info.Super;
|
||||
|
||||
|
||||
[MemoryPackInclude, MemoryPackAllowSerialize]
|
||||
List<SForwardCdkeyInfo> Cdkey => info.Cdkey;
|
||||
|
||||
[MemoryPackInclude]
|
||||
double Bandwidth => info.Bandwidth;
|
||||
|
||||
[MemoryPackConstructor]
|
||||
SerializableSForwardAddInfo191(string domain, int remotePort, string nodeid, string machineid, string groupid, bool validated, List<SForwardCdkeyInfo> cdkey)
|
||||
SerializableSForwardAddInfo191(string domain, int remotePort, string nodeid, string machineid, string groupid, bool validated, double bandwidth, List<SForwardCdkeyInfo> cdkey)
|
||||
{
|
||||
this.info = new SForwardAddInfo191
|
||||
{
|
||||
@@ -549,7 +552,8 @@ namespace linker.messenger.serializer.memorypack
|
||||
GroupId = groupid,
|
||||
MachineId = machineid,
|
||||
Cdkey = cdkey,
|
||||
Validated = validated
|
||||
Super = validated,
|
||||
Bandwidth = bandwidth
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,8 @@ namespace linker.messenger.sforward
|
||||
public string MachineId { get; set; } = string.Empty;
|
||||
public string GroupId { get; set; } = string.Empty;
|
||||
|
||||
public bool Validated { get; set; }
|
||||
public bool Super { get; set; }
|
||||
public double Bandwidth { get; set; }
|
||||
public List<SForwardCdkeyInfo> Cdkey { get; set; } = [];
|
||||
}
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ namespace linker.plugins.sforward.messenger
|
||||
result.Message = error;
|
||||
return;
|
||||
}
|
||||
Add(sForwardAddInfo, cache.MachineId, cache.GroupId, result, false, []);
|
||||
Add(sForwardAddInfo, cache.MachineId, cache.GroupId, result, sForwardAddInfo191.Super, sForwardAddInfo191.Bandwidth, []);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -369,7 +369,7 @@ namespace linker.plugins.sforward.messenger
|
||||
{
|
||||
Remove((SForwardAddInfo)sForwardAddInfo, sForwardAddInfo.MachineId, result);
|
||||
}
|
||||
public void Add(SForwardAddInfo sForwardAddInfo, string machineId, string groupid, SForwardAddResultInfo result, bool validated, List<SForwardCdkeyInfo> cdkeys)
|
||||
public void Add(SForwardAddInfo sForwardAddInfo, string machineId, string groupid, SForwardAddResultInfo result, bool super,double bandwidth, List<SForwardCdkeyInfo> cdkeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -384,7 +384,7 @@ namespace linker.plugins.sforward.messenger
|
||||
if (sForwardServerCahing.TryAdd(port, machineId))
|
||||
{
|
||||
proxy.Stop(port);
|
||||
result.Message = proxy.Start(port, 3, groupid, validated, cdkeys);
|
||||
result.Message = proxy.Start(port, 3, groupid, super, bandwidth, cdkeys);
|
||||
if (string.IsNullOrWhiteSpace(result.Message) == false)
|
||||
{
|
||||
LoggerHelper.Instance.Error(result.Message);
|
||||
@@ -404,7 +404,7 @@ namespace linker.plugins.sforward.messenger
|
||||
else
|
||||
{
|
||||
|
||||
proxy.AddHttp($"{sForwardAddInfo.Domain}.{sForwardServerNodeTransfer.Node.Domain}", validated, cdkeys);
|
||||
proxy.AddHttp($"{sForwardAddInfo.Domain}.{sForwardServerNodeTransfer.Node.Domain}", super, bandwidth, cdkeys);
|
||||
result.Message = $"domain 【{sForwardAddInfo.Domain}】 add success";
|
||||
}
|
||||
}
|
||||
@@ -423,7 +423,7 @@ namespace linker.plugins.sforward.messenger
|
||||
else
|
||||
{
|
||||
proxy.Stop(sForwardAddInfo.RemotePort);
|
||||
string msg = proxy.Start(sForwardAddInfo.RemotePort, 3, groupid, validated, cdkeys);
|
||||
string msg = proxy.Start(sForwardAddInfo.RemotePort, 3, groupid, super,bandwidth, cdkeys);
|
||||
if (string.IsNullOrWhiteSpace(msg) == false)
|
||||
{
|
||||
result.Success = false;
|
||||
@@ -447,7 +447,7 @@ namespace linker.plugins.sforward.messenger
|
||||
}
|
||||
public void Add(SForwardAddInfo191 sForwardAddInfo, SForwardAddResultInfo result)
|
||||
{
|
||||
Add((SForwardAddInfo)sForwardAddInfo, sForwardAddInfo.MachineId, sForwardAddInfo.GroupId, result, sForwardAddInfo.Validated, sForwardAddInfo.Cdkey);
|
||||
Add((SForwardAddInfo)sForwardAddInfo, sForwardAddInfo.MachineId, sForwardAddInfo.GroupId, result, sForwardAddInfo.Super, sForwardAddInfo.Bandwidth, sForwardAddInfo.Cdkey);
|
||||
}
|
||||
private static bool PortRange(string str, out int min, out int max)
|
||||
{
|
||||
|
||||
@@ -21,11 +21,11 @@ namespace linker.plugins.sforward.proxy
|
||||
{
|
||||
}
|
||||
|
||||
public string Start(int port, byte bufferSize, string groupid, bool validated, List<SForwardCdkeyInfo> cdkeys)
|
||||
public string Start(int port, byte bufferSize, string groupid, bool super,double bandwidth, List<SForwardCdkeyInfo> cdkeys)
|
||||
{
|
||||
try
|
||||
{
|
||||
SForwardTrafficCacheInfo sForwardTrafficCacheInfo = sForwardServerNodeTransfer.AddTrafficCache(validated, cdkeys);
|
||||
SForwardTrafficCacheInfo sForwardTrafficCacheInfo = sForwardServerNodeTransfer.AddTrafficCache(super, bandwidth, cdkeys);
|
||||
StartTcp(port, false, bufferSize, groupid, sForwardTrafficCacheInfo);
|
||||
StartUdp(port, bufferSize, groupid, sForwardTrafficCacheInfo);
|
||||
return string.Empty;
|
||||
|
||||
@@ -201,9 +201,9 @@ namespace linker.plugins.sforward.proxy
|
||||
}
|
||||
|
||||
|
||||
public void AddHttp(string host, bool validated, List<SForwardCdkeyInfo> cdkeys)
|
||||
public void AddHttp(string host, bool super,double bandwidth, List<SForwardCdkeyInfo> cdkeys)
|
||||
{
|
||||
SForwardTrafficCacheInfo sForwardTrafficCacheInfo = sForwardServerNodeTransfer.AddTrafficCache(validated, cdkeys);
|
||||
SForwardTrafficCacheInfo sForwardTrafficCacheInfo = sForwardServerNodeTransfer.AddTrafficCache(super, bandwidth, cdkeys);
|
||||
httpCaches.AddOrUpdate(host, sForwardTrafficCacheInfo, (a, b) => sForwardTrafficCacheInfo);
|
||||
}
|
||||
public void RemoveHttp(string host)
|
||||
|
||||
@@ -10,26 +10,20 @@
|
||||
/// </summary>
|
||||
/// <param name="userid"></param>
|
||||
/// <returns></returns>
|
||||
public Task<List<string>> Get(string userid);
|
||||
/// <summary>
|
||||
/// 是否存在于白名单
|
||||
/// </summary>
|
||||
/// <param name="userid"></param>
|
||||
/// <param name="nodeid"></param>
|
||||
/// <returns></returns>
|
||||
public Task<bool> Contains(string userid, string nodeid);
|
||||
public Task<List<SForwardWhiteListItem>> GetNodes(string userid);
|
||||
}
|
||||
|
||||
public sealed class SForwardServerWhiteListStore : ISForwardServerWhiteListStore
|
||||
{
|
||||
public async Task<bool> Contains(string userid, string nodeid)
|
||||
public async Task<List<SForwardWhiteListItem>> GetNodes(string userid)
|
||||
{
|
||||
return await Task.FromResult(false);
|
||||
}
|
||||
|
||||
public async Task<List<string>> Get(string userid)
|
||||
{
|
||||
return await Task.FromResult(new List<string>());
|
||||
return await Task.FromResult(new List<SForwardWhiteListItem>());
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SForwardWhiteListItem
|
||||
{
|
||||
public string[] Nodes { get; set; } = [];
|
||||
public double Bandwidth { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using linker.libs.timer;
|
||||
using linker.messenger.signin;
|
||||
using linker.plugins.sforward.messenger;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace linker.messenger.sforward.server
|
||||
@@ -109,25 +110,37 @@ namespace linker.messenger.sforward.server
|
||||
};
|
||||
}
|
||||
|
||||
List<string> sforward = await sForwardServerWhiteListStore.Get(from.UserId);
|
||||
List<SForwardWhiteListItem> sforward = await sForwardServerWhiteListStore.GetNodes(from.UserId);
|
||||
string target = string.IsNullOrWhiteSpace(info.Domain) ? info.RemotePort.ToString() : info.Domain;
|
||||
info.Validated = from.Super || (sforward.Contains($"sfp->{target}") || sforward.Contains($"sfp->*")) && (sforward.Contains(info.NodeId) || sforward.Contains($"*"));
|
||||
info.Super = from.Super;
|
||||
|
||||
if (info.Validated == false)
|
||||
var bandwidth = sforward.Where(c => (c.Nodes.Contains($"sfp->{target}") || c.Nodes.Contains($"sfp->*")) && (c.Nodes.Contains(info.NodeId) || c.Nodes.Contains($"*"))).ToList();
|
||||
if(bandwidth.Any(c=>c.Bandwidth < 0))
|
||||
{
|
||||
var cdkeys = await sForwardServerCdkeyStore.GetAvailable(from.UserId, $"sfp->{target}").ConfigureAwait(false);
|
||||
var anyCdkeys = await sForwardServerCdkeyStore.GetAvailable(from.UserId, $"sfp->*").ConfigureAwait(false);
|
||||
info.Cdkey = cdkeys.Concat(anyCdkeys).Select(c => new SForwardCdkeyInfo { Bandwidth = c.Bandwidth, Id = c.Id, LastBytes = c.LastBytes }).ToList();
|
||||
|
||||
if (info.Cdkey.Count <= 0 && node.Public == false)
|
||||
return new SForwardAddResultInfo
|
||||
{
|
||||
return new SForwardAddResultInfo
|
||||
{
|
||||
BufferSize = 1,
|
||||
Message = "need super key or white list or cdkey",
|
||||
Success = false
|
||||
};
|
||||
}
|
||||
BufferSize = 1,
|
||||
Message = "white list deney",
|
||||
Success = false
|
||||
};
|
||||
}
|
||||
|
||||
info.Bandwidth = bandwidth.Count > 0
|
||||
? bandwidth.Any(c => c.Bandwidth == 0) ? 0 : bandwidth.Max(c => c.Bandwidth)
|
||||
: info.Super ? 0 : node.MaxBandwidth;
|
||||
|
||||
var cdkeys = await sForwardServerCdkeyStore.GetAvailable(from.UserId, $"sfp->{target}").ConfigureAwait(false);
|
||||
var anyCdkeys = await sForwardServerCdkeyStore.GetAvailable(from.UserId, $"sfp->*").ConfigureAwait(false);
|
||||
info.Cdkey = cdkeys.Concat(anyCdkeys).Select(c => new SForwardCdkeyInfo { Bandwidth = c.Bandwidth, Id = c.Id, LastBytes = c.LastBytes }).ToList();
|
||||
|
||||
if (info.Cdkey.Count ==0 && node.Public == false && info.Super == false && bandwidth.Count == 0)
|
||||
{
|
||||
return new SForwardAddResultInfo
|
||||
{
|
||||
BufferSize = 1,
|
||||
Message = "need super key or white list or cdkey",
|
||||
Success = false
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -175,7 +188,7 @@ namespace linker.messenger.sforward.server
|
||||
Success = false
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取节点列表
|
||||
@@ -184,7 +197,7 @@ namespace linker.messenger.sforward.server
|
||||
/// <returns></returns>
|
||||
public async Task<List<SForwardServerNodeReportInfo>> GetNodes(bool validated, string userid)
|
||||
{
|
||||
List<string> sforward = await sForwardServerWhiteListStore.Get(userid);
|
||||
List<string> sforward = (await sForwardServerWhiteListStore.GetNodes(userid)).Where(c=>c.Bandwidth>=0).SelectMany(c=>c.Nodes).ToList();
|
||||
|
||||
var result = reports.Values
|
||||
.Where(c => Environment.TickCount64 - c.LastTicks < 15000)
|
||||
|
||||
@@ -111,7 +111,6 @@ namespace linker.messenger.sforward.server
|
||||
/// <returns></returns>
|
||||
public bool NeedLimit(SForwardTrafficCacheInfo relayCache)
|
||||
{
|
||||
if (relayCache.Cache.Validated) return false;
|
||||
return limitTotal.NeedLimit();
|
||||
}
|
||||
/// <summary>
|
||||
@@ -135,13 +134,16 @@ namespace linker.messenger.sforward.server
|
||||
/// <summary>
|
||||
/// 开始计算流量
|
||||
/// </summary>
|
||||
/// <param name="validated"></param>
|
||||
/// <param name="super"></param>
|
||||
/// <param name="cdkeys"></param>
|
||||
/// <returns></returns>
|
||||
public SForwardTrafficCacheInfo AddTrafficCache(bool validated, List<SForwardCdkeyInfo> cdkeys)
|
||||
public SForwardTrafficCacheInfo AddTrafficCache(bool super, double bandwidth, List<SForwardCdkeyInfo> cdkeys)
|
||||
{
|
||||
SForwardTrafficCacheInfo cache = new SForwardTrafficCacheInfo { Cache = new SForwardCacheInfo { Cdkey = cdkeys, FlowId = ns.Increment(), Validated = validated }, Limit = new SForwardSpeedLimit(), Sendt = 0, SendtCache = 0 };
|
||||
|
||||
SForwardTrafficCacheInfo cache = new SForwardTrafficCacheInfo { Cache = new SForwardCacheInfo { Cdkey = cdkeys, FlowId = ns.Increment(), Super = super, Bandwidth = bandwidth }, Limit = new SForwardSpeedLimit(), Sendt = 0, SendtCache = 0 };
|
||||
if (cache.Cache.Bandwidth < 0)
|
||||
{
|
||||
cache.Cache.Bandwidth = Node.MaxBandwidth;
|
||||
}
|
||||
SetLimit(cache);
|
||||
trafficDict.TryAdd(cache.Cache.FlowId, cache);
|
||||
|
||||
@@ -160,9 +162,6 @@ namespace linker.messenger.sforward.server
|
||||
{
|
||||
Interlocked.Add(ref bytes, length);
|
||||
|
||||
//验证过的,不消耗流量
|
||||
if (cache.Cache.Validated) return true;
|
||||
//节点无流量限制的,不消耗流量
|
||||
if (Node.MaxGbTotal == 0) return true;
|
||||
|
||||
Interlocked.Add(ref cache.Sendt, length);
|
||||
@@ -176,26 +175,27 @@ namespace linker.messenger.sforward.server
|
||||
/// <summary>
|
||||
/// 设置限速
|
||||
/// </summary>
|
||||
/// <param name="relayCache"></param>
|
||||
private void SetLimit(SForwardTrafficCacheInfo relayCache)
|
||||
/// <param name="cache"></param>
|
||||
private void SetLimit(SForwardTrafficCacheInfo cache)
|
||||
{
|
||||
//无限制
|
||||
if (relayCache.Cache.Validated || Node.MaxBandwidth == 0)
|
||||
cache.CurrentCdkey = cache.Cache.Cdkey.Where(c => c.LastBytes > 0).OrderByDescending(c => c.Bandwidth).FirstOrDefault();
|
||||
//黑白名单
|
||||
if (cache.Cache.Bandwidth >= 0)
|
||||
{
|
||||
relayCache.Limit.SetLimit(0);
|
||||
cache.Limit.SetLimit((uint)Math.Ceiling(cache.Cache.Bandwidth * 1024 * 1024 / 8.0));
|
||||
return;
|
||||
}
|
||||
|
||||
SForwardCdkeyInfo currentCdkey = relayCache.Cache.Cdkey.Where(c => c.LastBytes > 0).OrderByDescending(c => c.Bandwidth).FirstOrDefault();
|
||||
//有cdkey,且带宽大于节点带宽,就用cdkey的带宽
|
||||
if (currentCdkey != null && (currentCdkey.Bandwidth == 0 || currentCdkey.Bandwidth >= Node.MaxBandwidth || Node.MaxGbTotalLastBytes == 0))
|
||||
//无限制
|
||||
if (cache.Cache.Super || Node.MaxBandwidth == 0)
|
||||
{
|
||||
relayCache.CurrentCdkey = currentCdkey;
|
||||
relayCache.Limit.SetLimit((uint)Math.Ceiling((relayCache.CurrentCdkey.Bandwidth * 1024 * 1024) / 8.0));
|
||||
cache.Limit.SetLimit(0);
|
||||
return;
|
||||
}
|
||||
relayCache.CurrentCdkey = null;
|
||||
relayCache.Limit.SetLimit((uint)Math.Ceiling((Node.MaxBandwidth * 1024 * 1024) / 8.0));
|
||||
|
||||
//配置或cdkey,最大的
|
||||
double banwidth = double.Max(Node.MaxBandwidth, cache.CurrentCdkey?.Bandwidth ?? 1);
|
||||
cache.Limit.SetLimit((uint)Math.Ceiling(banwidth * 1024 * 1024 / 8.0));
|
||||
}
|
||||
|
||||
|
||||
@@ -460,7 +460,8 @@ namespace linker.messenger.sforward.server
|
||||
public sealed partial class SForwardCacheInfo
|
||||
{
|
||||
public ulong FlowId { get; set; }
|
||||
public bool Validated { get; set; }
|
||||
public bool Super { get; set; }
|
||||
public double Bandwidth { get; set; } = double.MinValue;
|
||||
public List<SForwardCdkeyInfo> Cdkey { get; set; } = [];
|
||||
}
|
||||
public class SForwardSpeedLimit
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace linker.messenger.store.file
|
||||
|
||||
public ConfigInfo Data { get; private set; } = new ConfigInfo();
|
||||
|
||||
public FileConfig(FileConfigInitParams? initParams = null)
|
||||
public FileConfig(FileConfigInitParams initParams = null)
|
||||
{
|
||||
if (initParams != null)
|
||||
{
|
||||
|
||||
@@ -36,10 +36,10 @@ namespace linker.messenger.store.file.wlist
|
||||
return await Task.FromResult(liteCollection.Delete(id)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<List<string>> Get(string type, string userid)
|
||||
public async Task<List<WhiteListInfo>> Get(string type, string userid)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(type) || string.IsNullOrWhiteSpace(userid)) return [];
|
||||
return await Task.FromResult(liteCollection.Find(c => c.Type == type && c.UserId == userid).SelectMany(c => c.Nodes).ToList()).ConfigureAwait(false);
|
||||
return await Task.FromResult(liteCollection.Find(c => c.Type == type && c.UserId == userid).ToList()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<WhiteListPageResultInfo> Page(WhiteListPageRequestInfo info)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
public Task<bool> Add(WhiteListInfo info);
|
||||
public Task<bool> Del(int id);
|
||||
|
||||
public Task<List<string>> Get(string type, string userid);
|
||||
public Task<List<WhiteListInfo>> Get(string type, string userid);
|
||||
}
|
||||
public sealed partial class WhiteListDelInfo
|
||||
{
|
||||
@@ -42,5 +42,9 @@
|
||||
public DateTime AddTime { get; set; } = DateTime.Now;
|
||||
|
||||
public string[] Nodes { get; set; } = [];
|
||||
|
||||
public double Bandwidth { get; set; } = 0;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,16 +9,13 @@ namespace linker.messenger.wlist
|
||||
{
|
||||
this.whiteListServerStore = whiteListServerStore;
|
||||
}
|
||||
|
||||
public async Task<bool> Contains(string userid, string nodeid)
|
||||
public async Task<List<RelayWhiteListItem>> GetNodes(string userid)
|
||||
{
|
||||
var list = await whiteListServerStore.Get("Relay", userid).ConfigureAwait(false);
|
||||
return list.Contains(nodeid);
|
||||
return (await whiteListServerStore.Get("Relay", userid).ConfigureAwait(false)).Select(c => new RelayWhiteListItem { Nodes = c.Nodes, Bandwidth = c.Bandwidth }).ToList();
|
||||
}
|
||||
|
||||
public async Task<List<string>> Get(string userid)
|
||||
public async Task<List<double>> GetBandwidth(string userid, string nodeid)
|
||||
{
|
||||
return await whiteListServerStore.Get("Relay", userid).ConfigureAwait(false);
|
||||
return (await whiteListServerStore.Get("Relay", userid).ConfigureAwait(false)).Where(c => c.Nodes.Contains(nodeid)).Select(c => c.Bandwidth).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,16 +9,9 @@ namespace linker.messenger.wlist
|
||||
{
|
||||
this.whiteListServerStore = whiteListServerStore;
|
||||
}
|
||||
|
||||
public async Task<bool> Contains(string userid, string nodeid)
|
||||
public async Task<List<SForwardWhiteListItem>> GetNodes(string userid)
|
||||
{
|
||||
var list = await whiteListServerStore.Get("SForward", userid).ConfigureAwait(false);
|
||||
return list.Contains(nodeid);
|
||||
}
|
||||
|
||||
public async Task<List<string>> Get(string userid)
|
||||
{
|
||||
return await whiteListServerStore.Get("SForward", userid).ConfigureAwait(false);
|
||||
return (await whiteListServerStore.Get("SForward", userid).ConfigureAwait(false)).Select(c => new SForwardWhiteListItem { Nodes = c.Nodes, Bandwidth = c.Bandwidth }).ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace linker.nat
|
||||
listenSocketTcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
listenSocketTcp.Bind(new IPEndPoint(IPAddress.Any, 0));
|
||||
listenSocketTcp.Listen(int.MaxValue);
|
||||
|
||||
|
||||
proxySrc = NetworkHelper.ToNetworkValue(srcAddr, prefixLength);
|
||||
tunIp = NetworkHelper.ToValue(srcAddr);
|
||||
proxyPort = (ushort)(listenSocketTcp.LocalEndPoint as IPEndPoint).Port;
|
||||
@@ -118,7 +118,6 @@ namespace linker.nat
|
||||
state.ReadPacket.PayloadChecksum = 1;
|
||||
connections.TryAdd(key, state);
|
||||
|
||||
|
||||
state.ReadPacket.Flags = LinkerSrcProxyFlags.Syn;
|
||||
state.ReadPacket.TotalLength = 40;
|
||||
state.ReadPacket.Length = 44;
|
||||
@@ -127,7 +126,7 @@ namespace linker.nat
|
||||
await state.Tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(15000)).ConfigureAwait(false);
|
||||
|
||||
state.ReadPacket.Flags = LinkerSrcProxyFlags.Psh;
|
||||
await Task.WhenAll(Sender(state), Rcver(state, buffer)).ConfigureAwait(false);
|
||||
await Task.WhenAny(Rcver(state, buffer),Sender(state)).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -238,7 +237,7 @@ namespace linker.nat
|
||||
await callback.Callback(state.ReadPacket).ConfigureAwait(false);
|
||||
|
||||
state.ReadPacket.Flags = LinkerSrcProxyFlags.Psh;
|
||||
await Task.WhenAll(Sender(state), Rcver(state, buffer)).ConfigureAwait(false);
|
||||
await Task.WhenAny(Rcver(state, buffer),Sender(state)).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -272,13 +271,9 @@ namespace linker.nat
|
||||
try
|
||||
{
|
||||
state.Sending = window > 0;
|
||||
|
||||
ReadOnlyMemory<byte> memory = packet.Slice(40);
|
||||
if (memory.Length > 0)
|
||||
{
|
||||
await state.Pipe.Writer.WriteAsync(memory).ConfigureAwait(false);
|
||||
state.AddReceived(memory.Length);
|
||||
}
|
||||
await state.Pipe.Writer.WriteAsync(memory).ConfigureAwait(false);
|
||||
state.AddReceived(memory.Length);
|
||||
|
||||
if (state.NeedPause) await SendWindow(state, 0).ConfigureAwait(false);
|
||||
}
|
||||
@@ -296,7 +291,6 @@ namespace linker.nat
|
||||
LoggerHelper.Instance.Error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private async Task SendWindow(ConnectionState state, ushort window)
|
||||
@@ -334,7 +328,7 @@ namespace linker.nat
|
||||
ReadOnlySequence<byte> buffer = result.Buffer;
|
||||
foreach (ReadOnlyMemory<byte> memoryBlock in result.Buffer)
|
||||
{
|
||||
await state.Socket.SendAsync(memoryBlock, SocketFlags.None).ConfigureAwait(false);
|
||||
int length = await state.Socket.SendAsync(memoryBlock, SocketFlags.None).ConfigureAwait(false);
|
||||
state.AddReceived(-memoryBlock.Length);
|
||||
if (state.NeedResume) await SendWindow(state, 1).ConfigureAwait(false);
|
||||
}
|
||||
@@ -350,7 +344,7 @@ namespace linker.nat
|
||||
state.ReadPacket.TotalLength = bytesRead + 40;
|
||||
state.ReadPacket.Length = bytesRead + 44;
|
||||
await callback.Callback(state.ReadPacket).ConfigureAwait(false);
|
||||
|
||||
|
||||
if (state.Sending == false)
|
||||
{
|
||||
while (state.Sending == false && state.Socket != null)
|
||||
@@ -369,7 +363,6 @@ namespace linker.nat
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public unsafe bool Read(ReadOnlyMemory<byte> packet, ref bool send, ref bool writeBack)
|
||||
{
|
||||
if (Running == false) return true;
|
||||
@@ -407,6 +400,7 @@ namespace linker.nat
|
||||
{
|
||||
if (srcProxyPacket.TcpOnlySyn == false) return true; //往下走
|
||||
if (callback.Callback(srcProxyPacket.DstAddr) == false) return true;//不支持代理
|
||||
|
||||
//1、10.18.18.2:11111->10.18.18.3:5201 [SYN] 新连接
|
||||
cache = new SrcCacheInfo
|
||||
{
|
||||
@@ -421,7 +415,6 @@ namespace linker.nat
|
||||
}
|
||||
if (srcProxyPacket.TcpFinOrRst) cache.Fin = true;
|
||||
cache.LastTime = Environment.TickCount64;
|
||||
|
||||
//2、10.18.18.2:11111->10.18.18.3:5201 改为 10.18.18.0:22222->10.18.18.2:33333 包括[SYN/PSH+ACK/ACK/FIN/RST]的任意包
|
||||
srcProxyPacket.DstAddr = srcProxyPacket.SrcAddr;
|
||||
srcProxyPacket.DstPort = proxyPort;
|
||||
@@ -440,9 +433,9 @@ namespace linker.nat
|
||||
{
|
||||
TimerHelper.SetIntervalLong(() =>
|
||||
{
|
||||
foreach (var item in srcMap.Where(c => c.Value.Fin && Environment.TickCount64 - c.Value.LastTime > 60 * 1000).Select(c => c.Key).ToList())
|
||||
foreach (var item in srcMap.Where(c => c.Value.Fin && Environment.TickCount64 - c.Value.LastTime > 60 * 1000).ToList())
|
||||
{
|
||||
srcMap.TryRemove(item, out _);
|
||||
srcMap.TryRemove(item.Key, out _);
|
||||
}
|
||||
}, 30000);
|
||||
}
|
||||
@@ -486,7 +479,6 @@ namespace linker.nat
|
||||
public bool NeedPause => Received > 512 * 1024 && Receiving;
|
||||
public bool NeedResume => Received < 128 * 1024 && Receiving == false;
|
||||
|
||||
|
||||
public void Disponse()
|
||||
{
|
||||
Pipe?.Writer.Complete();
|
||||
@@ -509,13 +501,13 @@ namespace linker.nat
|
||||
public readonly uint DstAddr => BinaryPrimitives.ReverseEndianness(*(uint*)(ptr + 16));
|
||||
public readonly ushort DstPort => BinaryPrimitives.ReverseEndianness(*(ushort*)(PayloadPtr + 2));
|
||||
|
||||
public readonly uint Seq => BinaryPrimitives.ReverseEndianness(*(uint*)(ptr + IPHeadLength + 4));
|
||||
public readonly uint Cq => BinaryPrimitives.ReverseEndianness(*(uint*)(ptr + IPHeadLength + 8));
|
||||
public readonly uint Seq => BinaryPrimitives.ReverseEndianness(*(uint*)(PayloadPtr + 4));
|
||||
public readonly uint Cq => BinaryPrimitives.ReverseEndianness(*(uint*)(PayloadPtr + 8));
|
||||
|
||||
|
||||
public byte DataOffset => (byte)((*(PayloadPtr + 12) >> 4) & 0b1111);
|
||||
public int HeadLength => DataOffset * 4;
|
||||
public readonly LinkerSrcProxyFlags Flag => (LinkerSrcProxyFlags)(*(ptr + IPHeadLength + 13));
|
||||
public readonly LinkerSrcProxyFlags Flag => (LinkerSrcProxyFlags)(*(PayloadPtr + 13));
|
||||
|
||||
public ushort WindowSize => BinaryPrimitives.ReverseEndianness(*(ushort*)(PayloadPtr + 14));
|
||||
|
||||
@@ -553,17 +545,6 @@ namespace linker.nat
|
||||
*(uint*)(ptr + 12) = BinaryPrimitives.ReverseEndianness(value);
|
||||
}
|
||||
}
|
||||
public readonly ushort SrcPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return BinaryPrimitives.ReverseEndianness(*(ushort*)(PayloadPtr));
|
||||
}
|
||||
set
|
||||
{
|
||||
*(ushort*)(PayloadPtr) = BinaryPrimitives.ReverseEndianness(value);
|
||||
}
|
||||
}
|
||||
public readonly uint DstAddr
|
||||
{
|
||||
get
|
||||
@@ -575,6 +556,41 @@ namespace linker.nat
|
||||
*(uint*)(ptr + 16) = BinaryPrimitives.ReverseEndianness(value);
|
||||
}
|
||||
}
|
||||
public readonly ushort SrcPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return BinaryPrimitives.ReverseEndianness(*(ushort*)(PayloadPtr));
|
||||
}
|
||||
set
|
||||
{
|
||||
*(ushort*)(PayloadPtr) = BinaryPrimitives.ReverseEndianness(value);
|
||||
}
|
||||
}
|
||||
public readonly ushort DstPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return BinaryPrimitives.ReverseEndianness(*(ushort*)(PayloadPtr + 2));
|
||||
}
|
||||
set
|
||||
{
|
||||
*(ushort*)(PayloadPtr + 2) = BinaryPrimitives.ReverseEndianness(value);
|
||||
}
|
||||
}
|
||||
|
||||
public byte DataOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return (byte)((*(PayloadPtr + 12) >> 4) & 0b1111);
|
||||
}
|
||||
set
|
||||
{
|
||||
*(PayloadPtr + 12) = (byte)((*(PayloadPtr + 12) & 0b00001111) | ((value & 0b1111) << 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const byte fin = 1;
|
||||
const byte syn = 2;
|
||||
@@ -582,7 +598,17 @@ namespace linker.nat
|
||||
const byte psh = 8;
|
||||
const byte ack = 16;
|
||||
const byte urg = 32;
|
||||
public readonly byte TcpFlag => *(ptr + IPHeadLength + 13);
|
||||
public readonly byte TcpFlag
|
||||
{
|
||||
get
|
||||
{
|
||||
return *(PayloadPtr + 13);
|
||||
}
|
||||
set
|
||||
{
|
||||
*(PayloadPtr + 13) = value;
|
||||
}
|
||||
}
|
||||
public readonly bool TcpFlagFin => (TcpFlag & fin) != 0;
|
||||
public readonly bool TcpFlagSyn => (TcpFlag & syn) != 0;
|
||||
public readonly bool TcpFlagRst => (TcpFlag & rst) != 0;
|
||||
@@ -596,17 +622,7 @@ namespace linker.nat
|
||||
public readonly bool TcpSynAck => TcpFlag == (syn | ack);
|
||||
public readonly bool TcpFinOrRst => (TcpFlag & (fin | rst)) != 0;
|
||||
|
||||
public readonly ushort DstPort
|
||||
{
|
||||
get
|
||||
{
|
||||
return BinaryPrimitives.ReverseEndianness(*(ushort*)(PayloadPtr + 2));
|
||||
}
|
||||
set
|
||||
{
|
||||
*(ushort*)(PayloadPtr + 2) = BinaryPrimitives.ReverseEndianness(value);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly ushort IPChecksum
|
||||
{
|
||||
get
|
||||
@@ -726,7 +742,7 @@ namespace linker.nat
|
||||
}
|
||||
set
|
||||
{
|
||||
*(ptr + 6) = (byte)((*ptr & 0b00011111) | ((value & 0b111) << 5));
|
||||
*(ptr + 6) = (byte)((*(ptr + 6) & 0b00011111) | ((value & 0b111) << 5));
|
||||
}
|
||||
}
|
||||
public ushort FragmentOffset
|
||||
@@ -853,7 +869,7 @@ namespace linker.nat
|
||||
}
|
||||
set
|
||||
{
|
||||
*(PayloadPtr + 12) = (byte)((*ptr & 0b00001111) | ((value & 0b1111) << 4));
|
||||
*(PayloadPtr + 12) = (byte)((*(PayloadPtr + 12) & 0b00001111) | ((value & 0b1111) << 4));
|
||||
}
|
||||
}
|
||||
public int HeadLength
|
||||
@@ -875,7 +891,7 @@ namespace linker.nat
|
||||
}
|
||||
set
|
||||
{
|
||||
*(PayloadPtr + 12) = (byte)((*ptr & 0b11110001) | ((value & 0b111) << 1));
|
||||
*(PayloadPtr + 12) = (byte)((*(PayloadPtr + 12) & 0b11110001) | ((value & 0b111) << 1));
|
||||
}
|
||||
}
|
||||
public LinkerSrcProxyFlags Flags
|
||||
|
||||
@@ -313,7 +313,10 @@ namespace linker.tun
|
||||
}
|
||||
|
||||
packet.Unpacket(buffer, 0, length);
|
||||
if (packet.DstIp.Length == 0 || packet.Version != 4) continue;
|
||||
if (packet.DstIp.Length == 0 || packet.Version != 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool send = true, writeBack = false;
|
||||
for (int i = 0; i < readHooks.Length; i++)
|
||||
@@ -323,9 +326,13 @@ namespace linker.tun
|
||||
ChecksumHelper.ChecksumWithZero(packet.RawPacket);
|
||||
|
||||
if (writeBack)
|
||||
{
|
||||
linkerTunDevice.Write(packet.RawPacket);
|
||||
}
|
||||
if (send)
|
||||
{
|
||||
await linkerTunDeviceCallback.Callback(packet).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -352,8 +359,8 @@ namespace linker.tun
|
||||
for (int i = 0; i < writeHooks.Length; i++)
|
||||
{
|
||||
(bool next, bool _write) = await writeHooks[i].WriteAsync(buffer, dstIp, srcId).ConfigureAwait(false);
|
||||
if (next == false) break;
|
||||
write &= _write;
|
||||
if (next == false) break;
|
||||
}
|
||||
ChecksumHelper.ChecksumWithZero(buffer);
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ namespace linker.tun.hook
|
||||
}
|
||||
public async ValueTask<(bool next, bool write)> WriteAsync(ReadOnlyMemory<byte> packet, uint originDstIp, string srcId)
|
||||
{
|
||||
bool write = await LinkerSrcProxy.WriteAsync(packet,originDstIp).ConfigureAwait(false);
|
||||
return await ValueTask.FromResult((write, write));
|
||||
bool write = await LinkerSrcProxy.WriteAsync(packet, originDstIp).ConfigureAwait(false);
|
||||
return (write, write);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
v1.9.3
|
||||
2025-10-12 17:17:51
|
||||
2025-10-19 16:03:22
|
||||
1. 一些累计更新,一些BUG修复
|
||||
2. 虚拟网卡TCP转代理,为TCP隧道提速
|
||||
3. 重写代理模块
|
||||
|
||||
Reference in New Issue
Block a user