重构中继

This commit is contained in:
snltty
2025-11-30 16:23:34 +08:00
parent 28fbe09a69
commit 38705259ee
27 changed files with 626 additions and 168 deletions

View File

@@ -1,5 +1,5 @@
v1.9.6
2025-11-28 18:04:53
2025-11-30 16:23:34
1. 一些累计更新一些BUG修复
2. 优化客户端数据同步,减少服务器流量
3. 去除cdkey改为发电解锁中继速度

View File

@@ -103,14 +103,6 @@ public sealed class JsonArgRelayInfo
/// 事务id
/// </summary>
public string TransactionId { get; set; }
/// <summary>
/// 协议名
/// </summary>
public string TransportName { get; set; }
/// <summary>
/// 流水id
/// </summary>
public ulong FlowingId { get; set; }
}
public sealed class JsonArgSForwardInfo
{

View File

@@ -69,7 +69,7 @@ namespace linker.libs
}
private static string SystemName()
{
string pattern = @"fnos|iphone|samsung|vivo|oppo|google|huawei|xiaomi|ios|android|windows|ubuntu|openwrt|armbian|archlinux|fedora|centos|rocky|alpine|debian|linux|docker";
string pattern = @"ikuai|fnos|iphone|samsung|vivo|oppo|google|huawei|xiaomi|ios|android|windows|ubuntu|openwrt|armbian|archlinux|fedora|centos|rocky|alpine|debian|linux|docker";
return Regex.Match(RuntimeInformation.OSDescription.ToLower(), pattern)?.Value ?? "unknow";
}
private static string VersionNumber()

View File

@@ -15,12 +15,9 @@ namespace linker.messenger.access
public bool Force => Accesss.Count < 2;
/// <summary>
/// 各个设备的权限列表
/// </summary>
public ConcurrentDictionary<string, BitArray> Accesss { get; } = new ConcurrentDictionary<string, BitArray>();
private readonly ISignInClientStore signInClientStore;
private readonly IAccessStore accessStore;
@@ -33,11 +30,8 @@ namespace linker.messenger.access
signInClientState.OnSignInSuccess += (times) => PushVersion.Increment();
accessStore.OnChanged += PushVersion.Increment;
}
/// <summary>
/// 刷新同步
/// </summary>
public void Refresh()
{
PushVersion.Increment();
@@ -53,7 +47,18 @@ namespace linker.messenger.access
}
public void AddData(List<ReadOnlyMemory<byte>> data)
{
List<AccessBitsInfo> list = data.Select(c => serializer.Deserialize<AccessBitsInfo>(c.Span)).ToList();
List<AccessBitsInfo> list = data.Select(c =>
{
try
{
return serializer.Deserialize<AccessBitsInfo>(c.Span);
}
catch (Exception)
{
}
return null;
}).Where(c => c != null).ToList();
foreach (var item in list)
{
Accesss.AddOrUpdate(item.MachineId, item.Access, (a, b) => item.Access);

View File

@@ -47,14 +47,24 @@ namespace linker.messenger.decenter
{
Addata(item);
}
}
public void AddData(List<ReadOnlyMemory<byte>> data)
{
List<List<ValueTuple<string, string, int>>> list = data.Select(c => serializer.Deserialize<List<ValueTuple<string, string, int>>>(c.Span)).ToList();
List<List<ValueTuple<string, string, int>>> list = data.Select(c =>
{
try
{
return serializer.Deserialize<List<ValueTuple<string, string, int>>>(c.Span);
}
catch (Exception)
{
}
return new List<ValueTuple<string, string, int>>();
}).ToList();
foreach (var info in list)
{
foreach (var item in info)
foreach (var item in info.Where(c => string.IsNullOrWhiteSpace(c.Item1) == false))
{
Addata(item);
}

View File

@@ -10,9 +10,6 @@ using linker.tunnel.transport;
namespace linker.messenger.relay.client
{
/// <summary>
/// 中继管理接口
/// </summary>
public sealed class RelayApiController : IApiController
{
private readonly RelayClientTestTransfer relayTestTransfer;
@@ -54,11 +51,6 @@ namespace linker.messenger.relay.client
}
}
/// <summary>
/// 连接
/// </summary>
/// <param name="param"></param>
/// <returns></returns>
public bool Connect(ApiControllerParamsInfo param)
{
RelayConnectInfo relayConnectInfo = param.Content.DeJson<RelayConnectInfo>();
@@ -82,5 +74,4 @@ namespace linker.messenger.relay.client
public string TransactionId { get; set; }
public string NodeId { get; set; }
}
}

View File

@@ -27,22 +27,17 @@ namespace linker.messenger.relay.messenger
private readonly RelayServerValidatorTransfer relayValidatorTransfer;
private readonly ISerializer serializer;
private readonly RelayServerReportResolver relayServerReportResolver;
private readonly RelayServerNodeTransfer relayServerNodeTransfer;
private readonly RelayServerMasterTransfer relayServerMasterTransfer;
private readonly RelayServerConnectionTransfer relayServerConnectionTransfer;
private readonly RelayServerNodeReportTransfer relayServerNodeReportTransfer;
public RelayServerMessenger(SignInServerCaching signCaching, ISerializer serializer, RelayServerValidatorTransfer relayValidatorTransfer,
RelayServerReportResolver relayServerReportResolver, RelayServerNodeTransfer relayServerNodeTransfer, RelayServerMasterTransfer relayServerMasterTransfer,
RelayServerConnectionTransfer relayServerConnectionTransfer, RelayServerNodeReportTransfer relayServerNodeReportTransfer)
RelayServerReportResolver relayServerReportResolver, RelayServerMasterTransfer relayServerMasterTransfer, RelayServerNodeReportTransfer relayServerNodeReportTransfer)
{
this.signCaching = signCaching;
this.relayValidatorTransfer = relayValidatorTransfer;
this.serializer = serializer;
this.relayServerReportResolver = relayServerReportResolver;
this.relayServerNodeTransfer = relayServerNodeTransfer;
this.relayServerMasterTransfer = relayServerMasterTransfer;
this.relayServerConnectionTransfer = relayServerConnectionTransfer;
this.relayServerNodeReportTransfer = relayServerNodeReportTransfer;
}
@@ -78,12 +73,12 @@ namespace linker.messenger.relay.messenger
return;
}
connection.Write(serializer.Serialize(new RelayAskResultInfo { Nodes = nodes, MasterId = relayServerNodeTransfer.Config.NodeId }));
connection.Write(serializer.Serialize(new RelayAskResultInfo { Nodes = nodes, MasterId = relayServerNodeReportTransfer.Config.NodeId }));
}
private async Task<List<RelayServerNodeStoreInfo>> GetNodes(SignCacheInfo from)
{
return await relayServerMasterTransfer.GetNodes(from.Super, from.UserId, from.MachineId);
return await relayServerNodeReportTransfer.GetNodes(from.Super, from.UserId, from.MachineId);
}
@@ -109,9 +104,15 @@ namespace linker.messenger.relay.messenger
[MessengerId((ushort)RelayMessengerIds.SignIn)]
public async Task SignIn(IConnection connection)
{
string id = serializer.Deserialize<string>(connection.ReceiveRequestWrap.Payload.Span);
connection.Id = id;
relayServerConnectionTransfer.TryAdd(connection.Id, connection);
KeyValuePair<string, string> kv = serializer.Deserialize<KeyValuePair<string, string>>(connection.ReceiveRequestWrap.Payload.Span);
if (await relayServerNodeReportTransfer.SignIn(kv.Key, kv.Value, connection).ConfigureAwait(false))
{
connection.Write(Helper.TrueArray);
}
else
{
connection.Write(Helper.FalseArray);
}
}
[MessengerId((ushort)RelayMessengerIds.Report)]
public async Task Report(IConnection connection)
@@ -121,7 +122,6 @@ namespace linker.messenger.relay.messenger
}
[MessengerId((ushort)RelayMessengerIds.NodeReport)]
public async Task NodeReport(IConnection connection)
{
@@ -135,12 +135,7 @@ namespace linker.messenger.relay.messenger
info.EndPoint.Address = connection.Address.Address;
}
await relayServerMasterTransfer.AddNode(new RelayServerNodeStoreInfo
{
NodeId = info.Id,
Name = info.Name,
Host = info.EndPoint.ToString(),
}).ConfigureAwait(false);
await relayServerNodeReportTransfer.Report(info.Id, info.Name, info.EndPoint.ToString()).ConfigureAwait(false);
}
catch (Exception)
{

View File

@@ -7,6 +7,8 @@ namespace linker.messenger.relay.server
{
public interface IRelayServerConfigStore
{
public int ServicePort { get; }
/// <summary>
/// 节点信息
/// </summary>
@@ -28,6 +30,9 @@ namespace linker.messenger.relay.server
/// </summary>
/// <param name="value"></param>
public void SetDataRemain(long value);
public void SetShareKey(string shareKey);
/// <summary>
/// 提交保存
/// </summary>
@@ -41,14 +46,13 @@ namespace linker.messenger.relay.server
private string name = Dns.GetHostName().SubStr(0, 32);
public string Name { get => name; set { name = value.SubStr(0, 32); } }
public string Host { get; set; } = string.Empty;
public TunnelProtocolType Protocol { get; set; } = TunnelProtocolType.Tcp;
public int Connections { get; set; } = 1000;
public int Bandwidth { get; set; } = 50;
public int DataEachMonth { get; set; } = 100;
public int Bandwidth { get; set; }
public int DataEachMonth { get; set; }
public long DataRemain { get; set; }
public string Url { get; set; } = "https://linker.snltty.com";
public string Logo { get; set; } = "https://linker.snltty.com/img/logo.png";
}
@@ -57,6 +61,7 @@ namespace linker.messenger.relay.server
{
public string ShareKey { get; set; } = string.Empty;
public int DataMonth { get; set; }
public string Domain { get; set; } = string.Empty;
}
public class RelayServerNodeReportInfo : RelayServerNodeInfo
@@ -64,6 +69,30 @@ namespace linker.messenger.relay.server
public string Version { get; set; } = string.Empty;
public int ConnectionsRatio { get; set; }
public double BandwidthRatio { get; set; }
public IPEndPoint[] Servers { get; set; } = Array.Empty<IPEndPoint>();
}
public sealed class RelayServerNodeStoreInfo : RelayServerNodeReportInfo
{
public int Id { get; set; }
public string Host { get; set; } = string.Empty;
public int BandwidthEachConnection { get; set; } = 50;
public bool Public { get; set; }
public long LastTicks { get; set; }
public int Delay { get; set; }
}
public class RelayServerNodeShareInfo
{
public string NodeId { get; set; } = string.Empty;
public string Host { get; set; } = string.Empty;
public string Name { get; set; } = string.Empty;
}
public partial class RelayServerNodeReportInfoOld

View File

@@ -8,15 +8,5 @@
public Task<bool> Report(RelayServerNodeReportInfo info);
}
public sealed class RelayServerNodeStoreInfo : RelayServerNodeReportInfo
{
public int Id { get; set; }
public int BandwidthEachConnection { get; set; } = 50;
public bool Public { get; set; }
public long LastTicks { get; set; }
public int Delay { get; set; }
}
}

View File

@@ -23,7 +23,6 @@ namespace linker.messenger.relay.server
public async Task Resolve(Socket socket, Memory<byte> memory)
{
byte[] buffer = ArrayPool<byte>.Shared.Rent(1024);
try
{
await messengerResolver.BeginReceiveServer(socket, Helper.EmptyArray).ConfigureAwait(false);
@@ -36,10 +35,6 @@ namespace linker.messenger.relay.server
}
socket.SafeClose();
}
finally
{
ArrayPool<byte>.Shared.Return(buffer);
}
}
public async Task Resolve(Socket socket, IPEndPoint ep, Memory<byte> memory)

View File

@@ -10,14 +10,12 @@ namespace linker.messenger.relay.server
{
private readonly IRelayServerCaching relayCaching;
private readonly IRelayServerWhiteListStore relayServerWhiteListStore;
private readonly IRelayServerNodeStore relayServerNodeStore;
public RelayServerMasterTransfer(IRelayServerCaching relayCaching, IRelayServerWhiteListStore relayServerWhiteListStore, IRelayServerNodeStore relayServerNodeStore)
private readonly RelayServerConnectionTransfer relayServerConnectionTransfer;
public RelayServerMasterTransfer(IRelayServerCaching relayCaching, IRelayServerWhiteListStore relayServerWhiteListStore, RelayServerConnectionTransfer relayServerConnectionTransfer)
{
this.relayCaching = relayCaching;
this.relayServerWhiteListStore = relayServerWhiteListStore;
this.relayServerNodeStore = relayServerNodeStore;
this.relayServerConnectionTransfer = relayServerConnectionTransfer;
}
public bool AddRelay(SignCacheInfo from, SignCacheInfo to, uint flowid)
@@ -37,6 +35,11 @@ namespace linker.messenger.relay.server
}
public async Task<RelayCacheInfo> TryGetRelayCache(string key, string nodeid)
{
if (relayServerConnectionTransfer.TryGet(nodeid, out IConnection connection) == false)
{
return null;
}
if (relayCaching.TryGetValue(key, out RelayCacheInfo cache))
{
List<double> bandwidth = await relayServerWhiteListStore.GetBandwidth(cache.UserId, cache.FromId, cache.ToId, nodeid);
@@ -53,51 +56,7 @@ namespace linker.messenger.relay.server
}
return null;
}
public async Task<List<RelayServerNodeStoreInfo>> GetNodes(bool validated, string userid, string machineId)
{
var nodes = (await relayServerWhiteListStore.GetNodes(userid, machineId)).Where(c => c.Bandwidth >= 0).SelectMany(c => c.Nodes);
var result = (await relayServerNodeStore.GetAll())
.Where(c => Environment.TickCount64 - c.LastTicks < 15000)
.Where(c =>
{
return validated || nodes.Contains(c.NodeId) || nodes.Contains("*")
|| (c.Public && c.ConnectionsRatio < c.Connections && (c.DataEachMonth == 0 || (c.DataEachMonth > 0 && c.DataRemain > 0)));
})
.OrderByDescending(c => c.LastTicks);
return result.OrderByDescending(x => x.Connections == 0 ? int.MaxValue : x.Connections)
.ThenBy(x => x.ConnectionsRatio)
.ThenBy(x => x.BandwidthRatio)
.ThenByDescending(x => x.BandwidthEachConnection == 0 ? int.MaxValue : x.BandwidthEachConnection)
.ThenByDescending(x => x.Bandwidth == 0 ? int.MaxValue : x.Bandwidth)
.ThenByDescending(x => x.DataEachMonth == 0 ? int.MaxValue : x.DataEachMonth)
.ThenByDescending(x => x.DataRemain == 0 ? long.MaxValue : x.DataRemain)
.ToList();
}
public async Task<List<RelayServerNodeStoreInfo>> GetPublicNodes()
{
var result = (await relayServerNodeStore.GetAll())
.Where(c => Environment.TickCount64 - c.LastTicks < 15000)
.Where(c => c.Public)
.OrderByDescending(c => c.LastTicks);
return result.OrderByDescending(x => x.Connections == 0 ? int.MaxValue : x.Connections)
.ThenBy(x => x.ConnectionsRatio)
.ThenBy(x => x.BandwidthRatio)
.ThenByDescending(x => x.BandwidthEachConnection == 0 ? int.MaxValue : x.BandwidthEachConnection)
.ThenByDescending(x => x.Bandwidth == 0 ? int.MaxValue : x.Bandwidth)
.ThenByDescending(x => x.DataEachMonth == 0 ? int.MaxValue : x.DataEachMonth)
.ThenByDescending(x => x.DataRemain == 0 ? long.MaxValue : x.DataRemain)
.ToList();
}
public async Task<bool> AddNode(RelayServerNodeStoreInfo info)
{
return await relayServerNodeStore.Add(info).ConfigureAwait(false);
}
}
public sealed partial class RelayCacheInfo

View File

@@ -1,15 +1,22 @@
using linker.libs;
using linker.libs.extends;
using linker.libs.timer;
using linker.messenger.relay.messenger;
using System.Net;
using System.Net.Sockets;
namespace linker.messenger.relay.server
{
public sealed class RelayServerNodeReportTransfer
{
public RelayServerConfigInfo Config => relayServerConfigStore.Config;
private int connectionNum = 0;
private ulong bytes = 0;
private ulong lastBytes = 0;
private readonly ICrypto crypto = CryptoFactory.CreateSymmetric(Helper.GlobalString);
public int ConnectionNum => connectionNum;
private readonly RelayServerConnectionTransfer relayServerConnectionTransfer;
@@ -17,17 +24,22 @@ namespace linker.messenger.relay.server
private readonly ISerializer serializer;
private readonly IMessengerSender messengerSender;
private readonly IRelayServerNodeStore relayServerNodeStore;
private readonly IRelayServerWhiteListStore relayServerWhiteListStore;
private readonly IMessengerResolver messengerResolver;
public RelayServerNodeReportTransfer(RelayServerConnectionTransfer relayServerConnectionTransfer, IRelayServerConfigStore relayServerConfigStore,
ISerializer serializer, IMessengerSender messengerSender, IRelayServerNodeStore relayServerNodeStore)
ISerializer serializer, IMessengerSender messengerSender, IRelayServerNodeStore relayServerNodeStore, IRelayServerWhiteListStore relayServerWhiteListStore, IMessengerResolver messengerResolver)
{
this.relayServerConnectionTransfer = relayServerConnectionTransfer;
this.relayServerConfigStore = relayServerConfigStore;
this.serializer = serializer;
this.messengerSender = messengerSender;
this.relayServerNodeStore = relayServerNodeStore;
this.relayServerWhiteListStore = relayServerWhiteListStore;
this.messengerResolver = messengerResolver;
ReportTask();
_ = ReportTask();
SignInTask();
}
@@ -35,57 +47,159 @@ namespace linker.messenger.relay.server
{
Interlocked.Increment(ref connectionNum);
}
public void DecrementConnectionNum()
{
Interlocked.Decrement(ref connectionNum);
}
public void AddBytes(long length)
{
Interlocked.Add(ref bytes, (ulong)length);
}
public async Task<bool> Report(string id, string name, string host)
{
return await relayServerNodeStore.Add(new RelayServerNodeStoreInfo
{
NodeId = id,
Name = name,
Host = host
}).ConfigureAwait(false);
}
public async Task<bool> Report(RelayServerNodeReportInfo info)
{
if (relayServerConnectionTransfer.TryGet(info.NodeId, out IConnection connection) == false) return false;
return await relayServerNodeStore.Report(info).ConfigureAwait(false);
}
private void ReportTask()
public async Task<bool> SignIn(string serverId, string nodeId, IConnection connection)
{
if (nodeId != Config.NodeId)
{
return false;
}
connection.Id = serverId;
relayServerConnectionTransfer.TryAdd(connection.Id, connection);
return true;
}
public async Task<List<RelayServerNodeStoreInfo>> GetNodes(bool validated, string userid, string machineId)
{
var nodes = (await relayServerWhiteListStore.GetNodes(userid, machineId)).Where(c => c.Bandwidth >= 0).SelectMany(c => c.Nodes);
var result = (await relayServerNodeStore.GetAll())
.Where(c => Environment.TickCount64 - c.LastTicks < 15000)
.Where(c =>
{
return validated || nodes.Contains(c.NodeId) || nodes.Contains("*")
|| (c.Public && c.ConnectionsRatio < c.Connections && (c.DataEachMonth == 0 || (c.DataEachMonth > 0 && c.DataRemain > 0)));
})
.OrderByDescending(c => c.LastTicks);
return result.OrderByDescending(x => x.Connections == 0 ? int.MaxValue : x.Connections)
.ThenBy(x => x.ConnectionsRatio)
.ThenBy(x => x.BandwidthRatio)
.ThenByDescending(x => x.BandwidthEachConnection == 0 ? int.MaxValue : x.BandwidthEachConnection)
.ThenByDescending(x => x.Bandwidth == 0 ? int.MaxValue : x.Bandwidth)
.ThenByDescending(x => x.DataEachMonth == 0 ? int.MaxValue : x.DataEachMonth)
.ThenByDescending(x => x.DataRemain == 0 ? long.MaxValue : x.DataRemain)
.ToList();
}
public async Task<List<RelayServerNodeStoreInfo>> GetPublicNodes()
{
var result = (await relayServerNodeStore.GetAll())
.Where(c => Environment.TickCount64 - c.LastTicks < 15000)
.Where(c => c.Public)
.OrderByDescending(c => c.LastTicks);
return result.OrderByDescending(x => x.Connections == 0 ? int.MaxValue : x.Connections)
.ThenBy(x => x.ConnectionsRatio)
.ThenBy(x => x.BandwidthRatio)
.ThenByDescending(x => x.BandwidthEachConnection == 0 ? int.MaxValue : x.BandwidthEachConnection)
.ThenByDescending(x => x.Bandwidth == 0 ? int.MaxValue : x.Bandwidth)
.ThenByDescending(x => x.DataEachMonth == 0 ? int.MaxValue : x.DataEachMonth)
.ThenByDescending(x => x.DataRemain == 0 ? long.MaxValue : x.DataRemain)
.ToList();
}
private async Task BuildShareKey()
{
try
{
await relayServerNodeStore.Add(new RelayServerNodeStoreInfo
{
NodeId = Config.NodeId,
Name = Config.Name,
Host = $"{IPAddress.Loopback}:{relayServerConfigStore.ServicePort}"
}).ConfigureAwait(false);
string host = Config.Domain;
if (string.IsNullOrWhiteSpace(host))
{
using HttpClient httpClient = new HttpClient();
host = await httpClient.GetStringAsync($"https://ifconfig.me/ip").WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
}
RelayServerNodeShareInfo shareKeyInfo = new RelayServerNodeShareInfo
{
NodeId = Config.NodeId,
Host = $"{host}:{relayServerConfigStore.ServicePort}",
Name = Config.Name
};
string shareKey = Convert.ToBase64String(crypto.Encode(serializer.Serialize(shareKeyInfo)));
relayServerConfigStore.SetShareKey(shareKey);
relayServerConfigStore.Confirm();
LoggerHelper.Instance.Warning($"build relay share key : {shareKey}");
}
catch (Exception ex)
{
LoggerHelper.Instance.Error($"build relay share key error : {ex}");
}
}
private async Task ReportTask()
{
await BuildShareKey().ConfigureAwait(false);
TimerHelper.SetIntervalLong(async () =>
{
try
{
double diff = (bytes - lastBytes) * 8 / 1024.0 / 1024.0;
lastBytes = bytes;
var connections = relayServerConnectionTransfer.Get();
if (connections.Any())
{
double diff = (bytes - lastBytes) * 8 / 1024.0 / 1024.0;
lastBytes = bytes;
var config = relayServerConfigStore.Config;
RelayServerNodeReportInfo info = new RelayServerNodeReportInfo
{
Bandwidth = config.Bandwidth,
Connections = config.Connections,
DataEachMonth = config.DataEachMonth,
DataRemain = config.DataRemain,
Host = config.Host,
Logo = config.Logo,
Name = config.Name,
NodeId = config.NodeId,
Protocol = config.Protocol,
Url = config.Url,
ConnectionsRatio = connectionNum,
BandwidthRatio = Math.Round(diff / 5, 2),
Version = VersionHelper.Version,
};
byte[] memory = serializer.Serialize(info);
var tasks = relayServerConnectionTransfer.Get().Select(c => messengerSender.SendOnly(new MessageRequestWrap
{
Connection = c,
MessengerId = (ushort)RelayMessengerIds.Report,
Payload = memory,
Timeout = 5000
})).ToList();
await Task.WhenAll(tasks).ConfigureAwait(false);
var config = relayServerConfigStore.Config;
RelayServerNodeReportInfo info = new RelayServerNodeReportInfo
{
Bandwidth = config.Bandwidth,
Connections = config.Connections,
DataEachMonth = config.DataEachMonth,
DataRemain = config.DataRemain,
Logo = config.Logo,
Name = config.Name,
NodeId = config.NodeId,
Protocol = config.Protocol,
Url = config.Url,
ConnectionsRatio = connectionNum,
BandwidthRatio = Math.Round(diff / 5, 2),
Version = VersionHelper.Version,
Servers = connections.Select(c => c.Address).ToArray()
};
byte[] memory = serializer.Serialize(info);
var tasks = connections.Select(c => messengerSender.SendOnly(new MessageRequestWrap
{
Connection = c,
MessengerId = (ushort)RelayMessengerIds.Report,
Payload = memory,
Timeout = 5000
})).ToList();
await Task.WhenAll(tasks).ConfigureAwait(false);
}
}
catch (Exception ex)
{
@@ -96,5 +210,56 @@ namespace linker.messenger.relay.server
}
}, 5000);
}
private void SignInTask()
{
TimerHelper.SetIntervalLong(async () =>
{
try
{
var nodes = (await relayServerNodeStore.GetAll()).Where(c =>
{
return relayServerConnectionTransfer.TryGet(c.NodeId, out IConnection connection) == false || connection == null || connection.Connected == false;
}).ToList();
if (nodes.Count != 0)
{
var tasks = nodes.Select(async c =>
{
IPEndPoint remote = await NetworkHelper.GetEndPointAsync(c.Host, 1802).ConfigureAwait(false);
Socket socket = new Socket(remote.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.KeepAlive();
await socket.ConnectAsync(remote).WaitAsync(TimeSpan.FromMilliseconds(5000)).ConfigureAwait(false);
var connection = await messengerResolver.BeginReceiveClient(socket, true, (byte)ResolverType.RelayConnection, Helper.EmptyArray).ConfigureAwait(false);
var resp = await messengerSender.SendReply(new MessageRequestWrap
{
Connection = connection,
MessengerId = (ushort)RelayMessengerIds.SignIn,
Payload = serializer.Serialize(new KeyValuePair<string, string>(Config.NodeId, c.NodeId)),
Timeout = 5000
}).ConfigureAwait(false);
if (resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray))
{
Console.WriteLine($"relay sign in to node {c.NodeId} success");
relayServerConnectionTransfer.TryAdd(c.NodeId, connection);
}
else
{
socket.SafeClose();
}
});
await Task.WhenAll(tasks).ConfigureAwait(false);
}
}
catch (Exception ex)
{
if (LoggerHelper.Instance.LoggerLevel <= LoggerTypes.DEBUG)
{
LoggerHelper.Instance.Error($"relay sign in : {ex}");
}
}
}, 10000);
}
}
}

View File

@@ -12,7 +12,7 @@ namespace linker.messenger.relay.server
/// </summary>
public class RelayServerNodeTransfer
{
public RelayServerConfigInfo Config => relayServerConfigStore.Config;
private RelayServerConfigInfo Config => relayServerNodeReportTransfer.Config;
private readonly RelaySpeedLimit limitTotal = new RelaySpeedLimit();

View File

@@ -129,6 +129,8 @@ namespace linker.messenger.relay.server
Socket answerSocket = await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(15000)).ConfigureAwait(false);
await answerSocket.SendAsync(Helper.TrueArray).ConfigureAwait(false);
LoggerHelper.Instance.Error($"relay start {socket.RemoteEndPoint} to {answerSocket.RemoteEndPoint}");
string flowKey = relayMessage.Type == RelayMessengerType.Ask ? $"{relayMessage.FromId}->{relayMessage.ToId}" : $"{relayMessage.ToId}->{relayMessage.FromId}";
RelayTrafficCacheInfo trafficCacheInfo = new RelayTrafficCacheInfo { Cache = relayCache, Sendt = 0, Limit = new RelaySpeedLimit(), Key = flowKey };
relayServerNodeTransfer.AddTrafficCache(trafficCacheInfo);
@@ -136,6 +138,8 @@ namespace linker.messenger.relay.server
await Task.WhenAll(CopyToAsync(trafficCacheInfo, socket, answerSocket), CopyToAsync(trafficCacheInfo, answerSocket, socket)).ConfigureAwait(false);
relayServerNodeTransfer.DecrementConnectionNum();
relayServerNodeTransfer.RemoveTrafficCache(trafficCacheInfo);
LoggerHelper.Instance.Error($"relay end {socket.RemoteEndPoint} to {answerSocket.RemoteEndPoint}");
}
catch (Exception ex)
{

View File

@@ -8,14 +8,14 @@ namespace linker.messenger.relay.webapi
{
public string Path => "/relay/nodes.json";
private readonly RelayServerMasterTransfer relayServerMasterTransfer;
public WebApiRelayNodesController(RelayServerMasterTransfer relayServerMasterTransfer)
private readonly RelayServerNodeReportTransfer relayServerNodeReportTransfer;
public WebApiRelayNodesController(RelayServerNodeReportTransfer relayServerNodeReportTransfer)
{
this.relayServerMasterTransfer = relayServerMasterTransfer;
this.relayServerNodeReportTransfer = relayServerNodeReportTransfer;
}
public async Task<Memory<byte>> Handle(string query)
{
return (await relayServerMasterTransfer.GetPublicNodes().ConfigureAwait(false)).Select(c =>
return (await relayServerNodeReportTransfer.GetPublicNodes().ConfigureAwait(false)).Select(c =>
{
return new
{

View File

@@ -65,6 +65,10 @@ namespace linker.messenger.serializer.memorypack
MemoryPackFormatterProvider.Register(new RelayCacheInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayMessageInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeStoreInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeShareInfoFormatter());
MemoryPackFormatterProvider.Register(new RelayServerNodeReportInfoFormatterOld());
MemoryPackFormatterProvider.Register(new AccessUpdateInfoFormatter());

View File

@@ -217,9 +217,297 @@ namespace linker.messenger.serializer.memorypack
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerNodeReportInfo
{
[MemoryPackIgnore]
public readonly RelayServerNodeReportInfo info;
[MemoryPackInclude]
string NodeId => info.NodeId;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
TunnelProtocolType Protocol => info.Protocol;
[MemoryPackInclude]
int Connections => info.Connections;
[MemoryPackInclude]
int Bandwidth => info.Bandwidth;
[MemoryPackInclude]
int DataEachMonth => info.DataEachMonth;
[MemoryPackInclude]
long DataRemain => info.DataRemain;
[MemoryPackInclude]
string Url => info.Url;
[MemoryPackInclude]
string Logo => info.Logo;
[MemoryPackInclude]
string Version => info.Version;
[MemoryPackInclude]
int ConnectionsRatio => info.ConnectionsRatio;
[MemoryPackInclude]
double BandwidthRatio => info.BandwidthRatio;
[MemoryPackInclude]
IPEndPoint[] Servers => info.Servers;
[MemoryPackConstructor]
SerializableRelayServerNodeReportInfo(string nodeId, string name, TunnelProtocolType protocol, int connections, int bandwidth, int dataEachMonth,
long dataRemain, string url, string logo, string version, int connectionsRatio, double bandwidthRatio, IPEndPoint[] servers)
{
var info = new RelayServerNodeReportInfo
{
NodeId = nodeId,
Name = name,
Protocol = protocol,
Connections = connections,
Bandwidth = bandwidth,
DataEachMonth = dataEachMonth,
DataRemain = dataRemain,
Url = url,
Logo = logo,
Version = version,
ConnectionsRatio = connectionsRatio,
BandwidthRatio = bandwidthRatio,
Servers = servers
};
this.info = info;
}
public SerializableRelayServerNodeReportInfo(RelayServerNodeReportInfo info)
{
this.info = info;
}
}
public class RelayServerNodeReportInfoFormatter : MemoryPackFormatter<RelayServerNodeReportInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerNodeReportInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerNodeReportInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerNodeReportInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
value = new RelayServerNodeReportInfo();
reader.TryReadObjectHeader(out byte count);
value.NodeId = reader.ReadValue<string>();
value.Name = reader.ReadValue<string>();
value.Protocol = reader.ReadValue<TunnelProtocolType>();
value.Connections = reader.ReadValue<int>();
value.Bandwidth = reader.ReadValue<int>();
value.DataEachMonth = reader.ReadValue<int>();
value.DataRemain = reader.ReadValue<long>();
value.Url = reader.ReadValue<string>();
value.Logo = reader.ReadValue<string>();
value.Version = reader.ReadValue<string>();
value.ConnectionsRatio = reader.ReadValue<int>();
value.BandwidthRatio = reader.ReadValue<double>();
value.Servers = reader.ReadValue<IPEndPoint[]>();
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerNodeStoreInfo
{
[MemoryPackIgnore]
public readonly RelayServerNodeStoreInfo info;
[MemoryPackInclude]
string NodeId => info.NodeId;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackInclude]
TunnelProtocolType Protocol => info.Protocol;
[MemoryPackInclude]
int Connections => info.Connections;
[MemoryPackInclude]
int Bandwidth => info.Bandwidth;
[MemoryPackInclude]
int DataEachMonth => info.DataEachMonth;
[MemoryPackInclude]
long DataRemain => info.DataRemain;
[MemoryPackInclude]
string Url => info.Url;
[MemoryPackInclude]
string Logo => info.Logo;
[MemoryPackInclude]
string Version => info.Version;
[MemoryPackInclude]
int ConnectionsRatio => info.ConnectionsRatio;
[MemoryPackInclude]
double BandwidthRatio => info.BandwidthRatio;
[MemoryPackInclude]
IPEndPoint[] Servers => info.Servers;
[MemoryPackInclude]
int Id => info.Id;
[MemoryPackInclude]
string Host => info.Host;
[MemoryPackInclude]
int BandwidthEachConnection => info.BandwidthEachConnection;
[MemoryPackInclude]
bool Public => info.Public;
[MemoryPackInclude]
long LastTicks => info.LastTicks;
[MemoryPackConstructor]
SerializableRelayServerNodeStoreInfo(string nodeId, string name, TunnelProtocolType protocol, int connections, int bandwidth, int dataEachMonth,
long dataRemain, string url, string logo, string version, int connectionsRatio, double bandwidthRatio, IPEndPoint[] servers,
int id, string host, int bandwidthEachConnection, bool Public, long lastTicks)
{
var info = new RelayServerNodeStoreInfo
{
NodeId = nodeId,
Name = name,
Protocol = protocol,
Connections = connections,
Bandwidth = bandwidth,
DataEachMonth = dataEachMonth,
DataRemain = dataRemain,
Url = url,
Logo = logo,
Version = version,
ConnectionsRatio = connectionsRatio,
BandwidthRatio = bandwidthRatio,
Servers = servers,
Id = id,
Host = host,
BandwidthEachConnection = bandwidthEachConnection,
Public = Public,
LastTicks = lastTicks
};
this.info = info;
}
public SerializableRelayServerNodeStoreInfo(RelayServerNodeStoreInfo info)
{
this.info = info;
}
}
public class RelayServerNodeStoreInfoFormatter : MemoryPackFormatter<RelayServerNodeStoreInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerNodeStoreInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerNodeStoreInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerNodeStoreInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
value = new RelayServerNodeStoreInfo();
reader.TryReadObjectHeader(out byte count);
value.NodeId = reader.ReadValue<string>();
value.Name = reader.ReadValue<string>();
value.Protocol = reader.ReadValue<TunnelProtocolType>();
value.Connections = reader.ReadValue<int>();
value.Bandwidth = reader.ReadValue<int>();
value.DataEachMonth = reader.ReadValue<int>();
value.DataRemain = reader.ReadValue<long>();
value.Url = reader.ReadValue<string>();
value.Logo = reader.ReadValue<string>();
value.Version = reader.ReadValue<string>();
value.ConnectionsRatio = reader.ReadValue<int>();
value.BandwidthRatio = reader.ReadValue<double>();
value.Servers = reader.ReadValue<IPEndPoint[]>();
value.Id = reader.ReadValue<int>();
value.Host = reader.ReadValue<string>();
value.BandwidthEachConnection = reader.ReadValue<int>();
value.Public = reader.ReadValue<bool>();
value.LastTicks = reader.ReadValue<long>();
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerNodeShareInfo
{
[MemoryPackIgnore]
public readonly RelayServerNodeShareInfo info;
[MemoryPackInclude]
string NodeId => info.NodeId;
[MemoryPackInclude]
string Host => info.Host;
[MemoryPackInclude]
string Name => info.Name;
[MemoryPackConstructor]
SerializableRelayServerNodeShareInfo(string nodeId, string host, string name)
{
var info = new RelayServerNodeShareInfo
{
NodeId= nodeId,
Host= host,
Name= name
};
this.info = info;
}
public SerializableRelayServerNodeShareInfo(RelayServerNodeShareInfo info)
{
this.info = info;
}
}
public class RelayServerNodeShareInfoFormatter : MemoryPackFormatter<RelayServerNodeShareInfo>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerNodeShareInfo value)
{
if (value == null)
{
writer.WriteNullObjectHeader();
return;
}
writer.WritePackable(new SerializableRelayServerNodeShareInfo(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerNodeShareInfo value)
{
if (reader.PeekIsNull())
{
reader.Advance(1); // skip null block
value = null;
return;
}
value = new RelayServerNodeShareInfo();
reader.TryReadObjectHeader(out byte count);
value.NodeId = reader.ReadValue<string>();
value.Host = reader.ReadValue<string>();
value.Name = reader.ReadValue<string>();
}
}
[MemoryPackable]
public readonly partial struct SerializableRelayServerNodeReportInfoOld
{
[MemoryPackIgnore]
public readonly RelayServerNodeReportInfoOld info;
@@ -263,7 +551,7 @@ namespace linker.messenger.serializer.memorypack
[MemoryPackConstructor]
SerializableRelayServerNodeReportInfo(
SerializableRelayServerNodeReportInfoOld(
string id, string name,
int maxConnection, double maxBandwidth, double maxBandwidthTotal,
double maxGbTotal, long maxGbTotalLastBytes,
@@ -294,12 +582,12 @@ namespace linker.messenger.serializer.memorypack
this.info = info;
}
public SerializableRelayServerNodeReportInfo(RelayServerNodeReportInfoOld info)
public SerializableRelayServerNodeReportInfoOld(RelayServerNodeReportInfoOld info)
{
this.info = info;
}
}
public class RelayServerNodeReportInfoFormatter : MemoryPackFormatter<RelayServerNodeReportInfoOld>
public class RelayServerNodeReportInfoFormatterOld : MemoryPackFormatter<RelayServerNodeReportInfoOld>
{
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref RelayServerNodeReportInfoOld value)
{
@@ -309,7 +597,7 @@ namespace linker.messenger.serializer.memorypack
return;
}
writer.WritePackable(new SerializableRelayServerNodeReportInfo(value));
writer.WritePackable(new SerializableRelayServerNodeReportInfoOld(value));
}
public override void Deserialize(ref MemoryPackReader reader, scoped ref RelayServerNodeReportInfoOld value)

View File

@@ -63,7 +63,18 @@ namespace linker.messenger.socks5
}
public void AddData(List<ReadOnlyMemory<byte>> data)
{
List<Socks5Info> list = data.Select(c => serializer.Deserialize<Socks5Info>(c.Span)).ToList();
List<Socks5Info> list = data.Select(c =>
{
try
{
return serializer.Deserialize<Socks5Info>(c.Span);
}
catch (Exception)
{
}
return null;
}).Where(c => c != null).ToList();
foreach (var item in list)
{
socks5Infos.AddOrUpdate(item.MachineId, item, (a, b) => item);

View File

@@ -4,8 +4,11 @@ namespace linker.messenger.store.file.relay
{
public sealed class RelayServerConfigStore : IRelayServerConfigStore
{
public int ServicePort => config.Data.Server.ServicePort;
public RelayServerConfigInfo Config => config.Data.Server.Relay;
private readonly FileConfig config;
public RelayServerConfigStore(FileConfig config)
{

View File

@@ -44,7 +44,6 @@ namespace linker.messenger.store.file.relay
BandwidthRatio = info.BandwidthRatio,
Url = info.Url,
Logo = info.Logo,
Host = info.Host,
DataEachMonth = info.DataEachMonth,
DataRemain = info.DataRemain,
Name = info.Name,

View File

@@ -42,7 +42,17 @@ namespace linker.messenger.tunnel
}
public void AddData(List<ReadOnlyMemory<byte>> data)
{
List<TunnelRouteLevelInfo> list = data.Select(c => serializer.Deserialize<TunnelRouteLevelInfo>(c.Span)).ToList();
List<TunnelRouteLevelInfo> list = data.Select(c =>
{
try
{
return serializer.Deserialize<TunnelRouteLevelInfo>(c.Span);
}
catch (Exception)
{
}
return null;
}).Where(c => c != null).ToList();
foreach (var item in list)
{
Config.AddOrUpdate(item.MachineId, item, (a, b) => item);
@@ -67,7 +77,7 @@ namespace linker.messenger.tunnel
PortMapWan = tunnelClientStore.PortMapPublic,
RouteLevelPlus = tunnelClientStore.RouteLevelPlus,
Net = tunnelClientStore.Network.Net
};
};
}
}
}

View File

@@ -0,0 +1,5 @@
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<!-- 在此编辑您的SVG代码 -->
<rect x="0" y="0" width="100" height="100" fill="#088ccc" rx="10" ry="10" />
<text x="50" y="85" font-family="Arial" font-size="100" fill="white" text-anchor="middle">iK</text>
</svg>

After

Width:  |  Height:  |  Size: 292 B

View File

@@ -1,5 +1,5 @@
<template>
<template v-if="item.MachineName">
<template v-if="item.MachineName !== undefined">
<AccessBoolean value="RenameSelf,RenameOther">
<template #default="{values}">
<a href="javascript:;" @click="handleEdit(values)" :title="item.IP" class="a-line">

View File

@@ -88,6 +88,7 @@ export const provideDevices = () => {
getSignInList(devices.page.Request).then((res) => {
devices.page.Request = res.Request;
devices.page.Count = res.Count;
console.log(res);
for (let j in res.List) {
Object.assign(res.List[j], {
showDel: machineId.value != res.List[j].MachineId && res.List[j].Connected == false,

View File

@@ -34,6 +34,7 @@ export default {
const _setRelaySubscribe = ()=>{
clearTimeout(state.timer);
setRelaySubscribe().then((res)=>{
console.log(res);
state.nodes = res;
nodes.value = res;
state.timer = setTimeout(_setRelaySubscribe,1000);

View File

@@ -19,7 +19,7 @@ export const provideTuntap = () => {
});
provide(tuntapSymbol, tuntap);
const reg = /fnos|iphone|samsung|vivo|oppo|google|huawei|xiaomi|ios|android|windows|ubuntu|openwrt|armbian|archlinux|fedora|centos|rocky|alpine|debian|linux|docker/g;
const reg = /ikuai|fnos|iphone|samsung|vivo|oppo|google|huawei|xiaomi|ios|android|windows|ubuntu|openwrt|armbian|archlinux|fedora|centos|rocky|alpine|debian|linux|docker/g;
const tuntapDataFn = () => {
return new Promise((resolve, reject) => {

View File

@@ -76,6 +76,7 @@ namespace linker
private static JsonDocument ParseArgs(string[] args)
{
JsonDocument json = null;
try
{