mirror of
https://github.com/snltty/linker.git
synced 2025-10-28 19:31:50 +08:00
IPV6
This commit is contained in:
@@ -3,9 +3,4 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<_LastSelectedProfileId>D:\desktop\cmonitor\cmonitor.viewer.server.win\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
|
<_LastSelectedProfileId>D:\desktop\cmonitor\cmonitor.viewer.server.win\Properties\PublishProfiles\FolderProfile.pubxml</_LastSelectedProfileId>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
|
||||||
<Compile Update="MainForm.cs">
|
|
||||||
<SubType>Form</SubType>
|
|
||||||
</Compile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -13,18 +13,18 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="body flex flex-1">
|
<div class="body flex flex-1">
|
||||||
<div class="private">
|
<div class="private">
|
||||||
<CheckBoxWrap ref="privateProcess" :data="state.privateProcess" :items="state.privateProcessItems" label="Name" text="Name" title="私有程序组"></CheckBoxWrap>
|
<CheckBoxWrap v-if="state.showCheck" ref="privateProcess" :data="state.privateProcess" :items="state.privateProcessItems" label="Name" text="Name" title="私有程序组"></CheckBoxWrap>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1"></div>
|
<div class="flex-1"></div>
|
||||||
<div class="public">
|
<div class="public">
|
||||||
<CheckBoxWrap ref="publicProcess" :data="state.publicProcess" :items="state.publicProcessItems" label="Name" text="Name" title="公共程序组"></CheckBoxWrap>
|
<CheckBoxWrap v-if="state.showCheck" ref="publicProcess" :data="state.publicProcess" :items="state.publicProcessItems" label="Name" text="Name" title="公共程序组"></CheckBoxWrap>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { computed, reactive, ref, watch } from 'vue';
|
import { computed, nextTick, reactive, ref, watch } from 'vue';
|
||||||
import CheckBoxWrap from '../../../boxs/CheckBoxWrap.vue'
|
import CheckBoxWrap from '../../../boxs/CheckBoxWrap.vue'
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { updateRule } from '../../../../../apis/hijack'
|
import { updateRule } from '../../../../../apis/hijack'
|
||||||
@@ -78,6 +78,18 @@ export default {
|
|||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
watch(()=>state.privateProcessItems,()=>{
|
||||||
|
state.showCheck = false;
|
||||||
|
nextTick(()=>{
|
||||||
|
state.showCheck = true;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
watch(()=>state.publicProcessItems,()=>{
|
||||||
|
state.showCheck = false;
|
||||||
|
nextTick(()=>{
|
||||||
|
state.showCheck = true;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
const privateProcess = ref(null);
|
const privateProcess = ref(null);
|
||||||
const publicProcess = ref(null);
|
const publicProcess = ref(null);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ namespace cmonitor.config
|
|||||||
{
|
{
|
||||||
PluginNames = value.ToList().Concat(new List<string>
|
PluginNames = value.ToList().Concat(new List<string>
|
||||||
{
|
{
|
||||||
"client","server","api","web","plugins.signin",
|
"client","server","api","web","serializes","plugins.signin",
|
||||||
"plugins.watch","plugins.devices","plugins.report",
|
"plugins.watch","plugins.devices","plugins.report",
|
||||||
"plugins.share","plugins.rule","plugins.modes",
|
"plugins.share","plugins.rule","plugins.modes",
|
||||||
}).Select(c => $".{c}.").ToArray();
|
}).Select(c => $".{c}.").ToArray();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using common.libs.winapis;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using common.libs;
|
using common.libs;
|
||||||
|
using common.libs.extends;
|
||||||
|
|
||||||
namespace cmonitor.plugins.hijack.report.hijack
|
namespace cmonitor.plugins.hijack.report.hijack
|
||||||
{
|
{
|
||||||
@@ -256,7 +257,6 @@ namespace cmonitor.plugins.hijack.report.hijack
|
|||||||
IPHostEntry entry = await Dns.GetHostEntryAsync(domain);
|
IPHostEntry entry = await Dns.GetHostEntryAsync(domain);
|
||||||
foreach (IPAddress item in entry.AddressList)
|
foreach (IPAddress item in entry.AddressList)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (domainIPs.ContainsKey(item) == false)
|
if (domainIPs.ContainsKey(item) == false)
|
||||||
domainIPs[item] = AllowType.Denied;
|
domainIPs[item] = AllowType.Denied;
|
||||||
}
|
}
|
||||||
@@ -372,7 +372,7 @@ namespace cmonitor.plugins.hijack.report.hijack
|
|||||||
|
|
||||||
ushort type = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
ushort type = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
||||||
index += 2; //type
|
index += 2; //type
|
||||||
if (type != 1)
|
if (type != 1 && type != 28)
|
||||||
{
|
{
|
||||||
return null; //不是A查询
|
return null; //不是A查询
|
||||||
}
|
}
|
||||||
@@ -391,7 +391,7 @@ namespace cmonitor.plugins.hijack.report.hijack
|
|||||||
int dataLength = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
int dataLength = BinaryPrimitives.ReadUInt16BigEndian(span.Slice(index));
|
||||||
index += 2;
|
index += 2;
|
||||||
|
|
||||||
if (type == 1) //是A回应,其它的不要
|
if (type == 1 || type == 28) //是A回应,其它的不要
|
||||||
{
|
{
|
||||||
ips[i] = new IPAddress(span.Slice(index, dataLength));
|
ips[i] = new IPAddress(span.Slice(index, dataLength));
|
||||||
}
|
}
|
||||||
@@ -423,7 +423,6 @@ namespace cmonitor.plugins.hijack.report.hijack
|
|||||||
|
|
||||||
if (ip != null && domainIPs.TryGetValue(ip, out type))
|
if (ip != null && domainIPs.TryGetValue(ip, out type))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (type == AllowType.Denied && domainKill)
|
if (type == AllowType.Denied && domainKill)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace cmonitor.plugins.share.report
|
|||||||
public ShareReport(Config config, ShareMemory shareMemory)
|
public ShareReport(Config config, ShareMemory shareMemory)
|
||||||
{
|
{
|
||||||
#if RELEASE
|
#if RELEASE
|
||||||
if (config.Common.BlueProtect && OperatingSystem.IsWindows())
|
//if (config.Data.Common.BlueProtect && OperatingSystem.IsWindows())
|
||||||
{
|
{
|
||||||
//ProcessBlueProtection.Protect();
|
//ProcessBlueProtection.Protect();
|
||||||
//SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
//SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
using cmonitor.config;
|
using cmonitor.config;
|
||||||
using cmonitor.plugins.tunnel.compact;
|
using cmonitor.plugins.tunnel.compact;
|
||||||
|
using cmonitor.plugins.tunnel.messenger;
|
||||||
using cmonitor.plugins.tunnel.server;
|
using cmonitor.plugins.tunnel.server;
|
||||||
|
using cmonitor.plugins.tunnel.transport;
|
||||||
using cmonitor.startup;
|
using cmonitor.startup;
|
||||||
using common.libs;
|
using common.libs;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace cmonitor.plugins.tunnel
|
namespace cmonitor.plugins.tunnel
|
||||||
@@ -14,11 +17,22 @@ namespace cmonitor.plugins.tunnel
|
|||||||
{
|
{
|
||||||
serviceCollection.AddSingleton<CompactTransfer>();
|
serviceCollection.AddSingleton<CompactTransfer>();
|
||||||
serviceCollection.AddSingleton<CompactSelfHost>();
|
serviceCollection.AddSingleton<CompactSelfHost>();
|
||||||
|
|
||||||
|
serviceCollection.AddSingleton<TunnelClientMessenger>();
|
||||||
|
|
||||||
|
serviceCollection.AddSingleton<TunnelBindServer>();
|
||||||
|
serviceCollection.AddSingleton<ITransport, TransportTcpNutssb>();
|
||||||
|
|
||||||
|
Logger.Instance.Info($"tunnel route level getting.");
|
||||||
|
config.Data.Client.Tunnel.RouteLevel = NetworkHelper.GetRouteLevel(out List<IPAddress> ips);
|
||||||
|
Logger.Instance.Info($"tunnel route level:{config.Data.Client.Tunnel.RouteLevel}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
{
|
{
|
||||||
serviceCollection.AddSingleton<TunnelServer>();
|
serviceCollection.AddSingleton<TunnelServer>();
|
||||||
|
|
||||||
|
serviceCollection.AddSingleton<TunnelServerMessenger>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using common.libs.extends;
|
using cmonitor.plugins.tunnel.server;
|
||||||
|
using common.libs.extends;
|
||||||
|
using MemoryPack;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|
||||||
@@ -8,7 +10,7 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
{
|
{
|
||||||
public string Type => "self";
|
public string Type => "self";
|
||||||
|
|
||||||
public async Task<CompactIPEndPoint> GetTcpExternalIPAsync(IPEndPoint server)
|
public async Task<TunnelCompactIPEndPoint> GetTcpExternalIPAsync(IPEndPoint server)
|
||||||
{
|
{
|
||||||
Socket socket = new Socket(server.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
Socket socket = new Socket(server.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
socket.Reuse(true);
|
socket.Reuse(true);
|
||||||
@@ -17,47 +19,31 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
|
|
||||||
byte[] bytes = new byte[20];
|
byte[] bytes = new byte[20];
|
||||||
int length = await socket.ReceiveAsync(bytes.AsMemory(), SocketFlags.None);
|
int length = await socket.ReceiveAsync(bytes.AsMemory(), SocketFlags.None);
|
||||||
if (length == 0) return null;
|
if (length == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return new CompactIPEndPoint { Local = socket.LocalEndPoint as IPEndPoint, Remote = ReadData(bytes) };
|
TunnelExternalIPInfo tunnelExternalIPInfo = MemoryPackSerializer.Deserialize<TunnelExternalIPInfo>(bytes.AsSpan(0,length));
|
||||||
|
|
||||||
|
return new TunnelCompactIPEndPoint { Local = socket.LocalEndPoint as IPEndPoint, Remote = tunnelExternalIPInfo.ExternalIP };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CompactIPEndPoint> GetUdpExternalIPAsync(IPEndPoint server)
|
public async Task<TunnelCompactIPEndPoint> GetUdpExternalIPAsync(IPEndPoint server)
|
||||||
{
|
{
|
||||||
|
|
||||||
using UdpClient udpClient = new UdpClient();
|
using UdpClient udpClient = new UdpClient();
|
||||||
udpClient.Client.Reuse(true);
|
udpClient.Client.Reuse(true);
|
||||||
await udpClient.SendAsync(new byte[1] { 0 }, server);
|
await udpClient.SendAsync(new byte[1] { 0 }, server);
|
||||||
var result = await udpClient.ReceiveAsync().WaitAsync(TimeSpan.FromSeconds(5));
|
var result = await udpClient.ReceiveAsync().WaitAsync(TimeSpan.FromSeconds(5));
|
||||||
if (result.Buffer.Length == 0) return null;
|
if (result.Buffer.Length == 0)
|
||||||
|
|
||||||
return new CompactIPEndPoint { Local = udpClient.Client.LocalEndPoint as IPEndPoint, Remote = ReadData(result.Buffer) };
|
|
||||||
}
|
|
||||||
|
|
||||||
private IPEndPoint ReadData(byte[] bytes)
|
|
||||||
{
|
|
||||||
int index = 0;
|
|
||||||
AddressFamily family = (AddressFamily)bytes[index];
|
|
||||||
index++;
|
|
||||||
|
|
||||||
int ipLength = family switch
|
|
||||||
{
|
{
|
||||||
AddressFamily.InterNetwork => 4,
|
return null;
|
||||||
AddressFamily.InterNetworkV6 => 16,
|
|
||||||
_ => 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (ipLength > 0)
|
|
||||||
{
|
|
||||||
IPAddress ip = new IPAddress(bytes.AsSpan(0, ipLength));
|
|
||||||
index += ipLength;
|
|
||||||
|
|
||||||
ushort port = bytes.AsSpan(index).ToUInt16();
|
|
||||||
IPEndPoint iPEndPoint = new IPEndPoint(ip, port);
|
|
||||||
return iPEndPoint;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
TunnelExternalIPInfo tunnelExternalIPInfo = MemoryPackSerializer.Deserialize<TunnelExternalIPInfo>(result.Buffer);
|
||||||
|
|
||||||
|
return new TunnelCompactIPEndPoint { Local = udpClient.Client.LocalEndPoint as IPEndPoint, Remote = tunnelExternalIPInfo.ExternalIP };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
Logger.Instance.Warning($"load tunnel compacts:{string.Join(",", compacts.Select(c => c.Type))}");
|
Logger.Instance.Warning($"load tunnel compacts:{string.Join(",", compacts.Select(c => c.Type))}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CompactIPEndPoint[]> GetExternalIPAsync(ProtocolType protocolType)
|
public async Task<TunnelCompactIPEndPoint[]> GetExternalIPAsync(ProtocolType protocolType)
|
||||||
{
|
{
|
||||||
CompactIPEndPoint[] endpoints = new CompactIPEndPoint[config.Data.Client.Tunnel.Servers.Length];
|
TunnelCompactIPEndPoint[] endpoints = new TunnelCompactIPEndPoint[config.Data.Client.Tunnel.Servers.Length];
|
||||||
|
|
||||||
for (int i = 0; i < config.Data.Client.Tunnel.Servers.Length; i++)
|
for (int i = 0; i < config.Data.Client.Tunnel.Servers.Length; i++)
|
||||||
{
|
{
|
||||||
@@ -46,12 +46,12 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
IPEndPoint server = NetworkHelper.GetEndPoint(item.Host, 3478);
|
IPEndPoint server = NetworkHelper.GetEndPoint(item.Host, 3478);
|
||||||
if (protocolType == ProtocolType.Tcp)
|
if (protocolType == ProtocolType.Tcp)
|
||||||
{
|
{
|
||||||
CompactIPEndPoint externalIP = await compact.GetTcpExternalIPAsync(server);
|
TunnelCompactIPEndPoint externalIP = await compact.GetTcpExternalIPAsync(server);
|
||||||
endpoints[i] = externalIP;
|
endpoints[i] = externalIP;
|
||||||
}
|
}
|
||||||
else if (protocolType == ProtocolType.Udp)
|
else if (protocolType == ProtocolType.Udp)
|
||||||
{
|
{
|
||||||
CompactIPEndPoint externalIP = await compact.GetUdpExternalIPAsync(server);
|
TunnelCompactIPEndPoint externalIP = await compact.GetUdpExternalIPAsync(server);
|
||||||
endpoints[i] = externalIP;
|
endpoints[i] = externalIP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
public interface ICompact
|
public interface ICompact
|
||||||
{
|
{
|
||||||
public string Type { get; }
|
public string Type { get; }
|
||||||
public Task<CompactIPEndPoint> GetTcpExternalIPAsync(IPEndPoint server);
|
public Task<TunnelCompactIPEndPoint> GetTcpExternalIPAsync(IPEndPoint server);
|
||||||
public Task<CompactIPEndPoint> GetUdpExternalIPAsync(IPEndPoint server);
|
public Task<TunnelCompactIPEndPoint> GetUdpExternalIPAsync(IPEndPoint server);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class CompactIPEndPoint
|
public sealed class TunnelCompactIPEndPoint
|
||||||
{
|
{
|
||||||
public IPEndPoint Local { get; set; }
|
public IPEndPoint Local { get; set; }
|
||||||
public IPEndPoint Remote { get; set; }
|
public IPEndPoint Remote { get; set; }
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace cmonitor.config
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace cmonitor.config
|
||||||
{
|
{
|
||||||
public partial class ConfigClientInfo
|
public partial class ConfigClientInfo
|
||||||
{
|
{
|
||||||
@@ -15,6 +17,9 @@
|
|||||||
{
|
{
|
||||||
new TunnelCompactInfo { Type="self", Host="127.0.0.1:1804" }
|
new TunnelCompactInfo { Type="self", Host="127.0.0.1:1804" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public int RouteLevel { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class TunnelConfigServerInfo
|
public sealed class TunnelConfigServerInfo
|
||||||
|
|||||||
@@ -1,12 +1,66 @@
|
|||||||
using cmonitor.server;
|
using cmonitor.config;
|
||||||
|
using cmonitor.plugins.signin.messenger;
|
||||||
|
using cmonitor.plugins.tunnel.transport;
|
||||||
|
using cmonitor.server;
|
||||||
|
using MemoryPack;
|
||||||
|
using System.Buffers;
|
||||||
|
|
||||||
namespace cmonitor.plugins.tunnel.messenger
|
namespace cmonitor.plugins.tunnel.messenger
|
||||||
{
|
{
|
||||||
public sealed class TunnelMessenger : IMessenger
|
public sealed class TunnelClientMessenger : IMessenger
|
||||||
{
|
{
|
||||||
public TunnelMessenger()
|
private readonly ITransport transport;
|
||||||
|
private readonly Config config;
|
||||||
|
public TunnelClientMessenger(ITransport transport, Config config)
|
||||||
{
|
{
|
||||||
|
this.transport = transport;
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MessengerId((ushort)TunnelMessengerIds.Begin)]
|
||||||
|
public async Task Begin(IConnection connection)
|
||||||
|
{
|
||||||
|
TunnelTransportInfo tunnelTransportInfo = MemoryPackSerializer.Deserialize<TunnelTransportInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
tunnelTransportInfo.RouteLevel = config.Data.Client.Tunnel.RouteLevel;
|
||||||
|
TunnelTransportInfo info = await transport.OnBegin(tunnelTransportInfo);
|
||||||
|
connection.Write(MemoryPackSerializer.Serialize(info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public sealed class TunnelServerMessenger : IMessenger
|
||||||
|
{
|
||||||
|
private readonly MessengerSender messengerSender;
|
||||||
|
private readonly SignCaching signCaching;
|
||||||
|
public TunnelServerMessenger(MessengerSender messengerSender, SignCaching signCaching)
|
||||||
|
{
|
||||||
|
this.messengerSender = messengerSender;
|
||||||
|
this.signCaching = signCaching;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MessengerId((ushort)TunnelMessengerIds.BeginForward)]
|
||||||
|
public async Task BeginForward(IConnection connection)
|
||||||
|
{
|
||||||
|
TunnelTransportInfo tunnelTransportInfo = MemoryPackSerializer.Deserialize<TunnelTransportInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
|
||||||
|
if (signCaching.Get(tunnelTransportInfo.ToMachineName, out SignCacheInfo cache))
|
||||||
|
{
|
||||||
|
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = cache.Connection,
|
||||||
|
MessengerId = (ushort)TunnelMessengerIds.Begin,
|
||||||
|
Payload = connection.ReceiveRequestWrap.Payload
|
||||||
|
});
|
||||||
|
if (resp.Code == MessageResponeCodes.OK)
|
||||||
|
{
|
||||||
|
byte[] bytes = ArrayPool<byte>.Shared.Rent(resp.Data.Length);
|
||||||
|
resp.Data.CopyTo(bytes);
|
||||||
|
|
||||||
|
connection.Write(bytes.AsMemory(0, resp.Data.Length));
|
||||||
|
|
||||||
|
ArrayPool<byte>.Shared.Return(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,10 @@
|
|||||||
public enum TunnelMessengerIds : ushort
|
public enum TunnelMessengerIds : ushort
|
||||||
{
|
{
|
||||||
Update = 2000,
|
Update = 2000,
|
||||||
|
Begin = 2001,
|
||||||
|
BeginForward = 2002,
|
||||||
|
Reverse = 2003,
|
||||||
|
ReverseForward = 2004,
|
||||||
None = 2001
|
None = 2001
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
117
cmonitor/plugins/tunnel/server/TunnelBindServer.cs
Normal file
117
cmonitor/plugins/tunnel/server/TunnelBindServer.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using common.libs;
|
||||||
|
using common.libs.extends;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace cmonitor.plugins.tunnel.server
|
||||||
|
{
|
||||||
|
public sealed class TunnelBindServer
|
||||||
|
{
|
||||||
|
private SocketAsyncEventArgs acceptEventArg;
|
||||||
|
private Socket socket;
|
||||||
|
private UdpClient socketUdp;
|
||||||
|
|
||||||
|
public Action<object, Socket> OnTcpConnected { get; set; } = (state, socket) => { };
|
||||||
|
public Action<object, UdpClient> OnUdpConnected { get; set; } = (state, udpClient) => { };
|
||||||
|
|
||||||
|
public void Bind(IPEndPoint local, object state)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket = new Socket(local.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
socket.IPv6Only(local.AddressFamily, false);
|
||||||
|
socket.ReuseBind(local);
|
||||||
|
socket.Listen(int.MaxValue);
|
||||||
|
|
||||||
|
acceptEventArg = new SocketAsyncEventArgs
|
||||||
|
{
|
||||||
|
UserToken = new AsyncUserToken
|
||||||
|
{
|
||||||
|
SourceSocket = socket,
|
||||||
|
State = state
|
||||||
|
},
|
||||||
|
SocketFlags = SocketFlags.None,
|
||||||
|
};
|
||||||
|
|
||||||
|
acceptEventArg.Completed += IO_Completed;
|
||||||
|
StartAccept(acceptEventArg);
|
||||||
|
|
||||||
|
|
||||||
|
socketUdp = new UdpClient();
|
||||||
|
socketUdp.Client.ReuseBind(local);
|
||||||
|
socketUdp.Client.EnableBroadcast = true;
|
||||||
|
socketUdp.Client.WindowsUdpBug();
|
||||||
|
IAsyncResult result = socketUdp.BeginReceive(ReceiveCallbackUdp, state);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Instance.Error(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void StartAccept(SocketAsyncEventArgs acceptEventArg)
|
||||||
|
{
|
||||||
|
acceptEventArg.AcceptSocket = null;
|
||||||
|
AsyncUserToken token = (AsyncUserToken)acceptEventArg.UserToken;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (token.SourceSocket.AcceptAsync(acceptEventArg) == false)
|
||||||
|
{
|
||||||
|
ProcessAccept(acceptEventArg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
token.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void IO_Completed(object sender, SocketAsyncEventArgs e)
|
||||||
|
{
|
||||||
|
switch (e.LastOperation)
|
||||||
|
{
|
||||||
|
case SocketAsyncOperation.Accept:
|
||||||
|
ProcessAccept(e);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void ProcessAccept(SocketAsyncEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.AcceptSocket != null)
|
||||||
|
{
|
||||||
|
AsyncUserToken token = e.UserToken as AsyncUserToken;
|
||||||
|
OnTcpConnected(token.State, e.AcceptSocket);
|
||||||
|
StartAccept(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void ReceiveCallbackUdp(IAsyncResult result)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IPEndPoint ep = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
|
||||||
|
byte[] _ = socketUdp.EndReceive(result, ref ep);
|
||||||
|
|
||||||
|
OnUdpConnected(result.AsyncState, socketUdp);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class AsyncUserToken
|
||||||
|
{
|
||||||
|
public Socket SourceSocket { get; set; }
|
||||||
|
public object State { get; set; }
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
SourceSocket?.SafeClose();
|
||||||
|
SourceSocket = null;
|
||||||
|
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using common.libs;
|
using common.libs;
|
||||||
using common.libs.extends;
|
using common.libs.extends;
|
||||||
using System.Buffers;
|
using MemoryPack;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|
||||||
@@ -88,20 +88,10 @@ namespace cmonitor.plugins.tunnel.server
|
|||||||
if (token.SourceSocket != null)
|
if (token.SourceSocket != null)
|
||||||
{
|
{
|
||||||
IPEndPoint ep = token.SourceSocket.RemoteEndPoint as IPEndPoint;
|
IPEndPoint ep = token.SourceSocket.RemoteEndPoint as IPEndPoint;
|
||||||
|
Memory<byte> memory = MemoryPackSerializer.Serialize(new TunnelExternalIPInfo { ExternalIP = ep });
|
||||||
|
|
||||||
byte[] bytes = ArrayPool<byte>.Shared.Rent(20);
|
await token.SourceSocket.SendAsync(memory);
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
bytes[index] = (byte)ep.Address.AddressFamily;
|
|
||||||
index++;
|
|
||||||
ep.Address.TryWriteBytes(bytes.AsSpan(index), out int bytesWritten);
|
|
||||||
index += bytesWritten;
|
|
||||||
((ushort)ep.Port).ToBytes(bytes.AsMemory(index));
|
|
||||||
index += 2;
|
|
||||||
|
|
||||||
await token.SourceSocket.SendAsync(bytes.AsMemory(0, index));
|
|
||||||
|
|
||||||
ArrayPool<byte>.Shared.Return(bytes);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,20 +102,9 @@ namespace cmonitor.plugins.tunnel.server
|
|||||||
IPEndPoint ep = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
|
IPEndPoint ep = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
|
||||||
byte[] _ = socketUdp.EndReceive(result, ref ep);
|
byte[] _ = socketUdp.EndReceive(result, ref ep);
|
||||||
|
|
||||||
|
Memory<byte> memory = MemoryPackSerializer.Serialize(new TunnelExternalIPInfo { ExternalIP = ep });
|
||||||
|
|
||||||
byte[] bytes = ArrayPool<byte>.Shared.Rent(20);
|
await socketUdp.SendAsync(memory, ep);
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
bytes[index] = (byte)ep.Address.AddressFamily;
|
|
||||||
index++;
|
|
||||||
ep.Address.TryWriteBytes(bytes.AsSpan(index), out int bytesWritten);
|
|
||||||
index += bytesWritten;
|
|
||||||
((ushort)ep.Port).ToBytes(bytes.AsMemory(index));
|
|
||||||
index += 2;
|
|
||||||
|
|
||||||
await socketUdp.SendAsync(bytes.AsMemory(0, index), ep);
|
|
||||||
|
|
||||||
ArrayPool<byte>.Shared.Return(bytes);
|
|
||||||
|
|
||||||
result = socketUdp.BeginReceive(ReceiveCallbackUdp, null);
|
result = socketUdp.BeginReceive(ReceiveCallbackUdp, null);
|
||||||
}
|
}
|
||||||
@@ -147,6 +126,7 @@ namespace cmonitor.plugins.tunnel.server
|
|||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
CloseClientSocket(acceptEventArg);
|
CloseClientSocket(acceptEventArg);
|
||||||
|
socketUdp?.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,4 +142,11 @@ namespace cmonitor.plugins.tunnel.server
|
|||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public sealed partial class TunnelExternalIPInfo
|
||||||
|
{
|
||||||
|
[MemoryPackAllowSerialize]
|
||||||
|
public IPEndPoint ExternalIP { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,43 @@
|
|||||||
using System.Net;
|
using MemoryPack;
|
||||||
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
|
||||||
namespace cmonitor.plugins.tunnel.transport
|
namespace cmonitor.plugins.tunnel.transport
|
||||||
{
|
{
|
||||||
public interface ITransport
|
public interface ITransport
|
||||||
{
|
{
|
||||||
public Task<Socket> ConnectAsync(IPEndPoint local, IPEndPoint remote);
|
public string Name { get; }
|
||||||
|
public ProtocolType TypeFlag { get; }
|
||||||
|
public Func<TunnelTransportInfo, Task<TunnelTransportInfo>> SendBegin { get; set; }
|
||||||
|
public Action<TransportState> OnConnected { get; set; }
|
||||||
|
|
||||||
|
public Task<Socket> ConnectAsync(string fromMachineName, string toMachineName);
|
||||||
|
public Task<TunnelTransportInfo> OnBegin(TunnelTransportInfo tunnelTransportNoticeInfo);
|
||||||
|
public Task OnReverse(TunnelTransportInfo tunnelTransportNoticeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public sealed partial class TunnelTransportInfo
|
||||||
|
{
|
||||||
|
[MemoryPackAllowSerialize]
|
||||||
|
public IPEndPoint FromLocal { get; set; }
|
||||||
|
|
||||||
|
[MemoryPackAllowSerialize]
|
||||||
|
public IPEndPoint FromRemote { get; set; }
|
||||||
|
public string FromMachineName { get; set; }
|
||||||
|
public string ToMachineName { get; set; }
|
||||||
|
|
||||||
|
public ProtocolType TypeFlag { get; set; }
|
||||||
|
|
||||||
|
public int RouteLevel { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class TransportState
|
||||||
|
{
|
||||||
|
public string FromMachineName { get; set; }
|
||||||
|
public ProtocolType TypeFlag { get; set; }
|
||||||
|
|
||||||
|
public object ConnectedObject { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
160
cmonitor/plugins/tunnel/transport/TransportTcpNutssb.cs
Normal file
160
cmonitor/plugins/tunnel/transport/TransportTcpNutssb.cs
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
using cmonitor.plugins.tunnel.compact;
|
||||||
|
using cmonitor.plugins.tunnel.server;
|
||||||
|
using common.libs;
|
||||||
|
using common.libs.extends;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace cmonitor.plugins.tunnel.transport
|
||||||
|
{
|
||||||
|
public sealed class TransportTcpNutssb : ITransport
|
||||||
|
{
|
||||||
|
|
||||||
|
private readonly TunnelBindServer tunnelBindServer;
|
||||||
|
private readonly CompactTransfer compactTransfer;
|
||||||
|
|
||||||
|
public Action<TransportState> OnConnected { get; set; } = (state) => { };
|
||||||
|
public Func<TunnelTransportInfo, Task<TunnelTransportInfo>> SendBegin { get; set; }
|
||||||
|
public string Name => "TcpNutssb";
|
||||||
|
public ProtocolType TypeFlag => ProtocolType.Tcp;
|
||||||
|
|
||||||
|
public TransportTcpNutssb(TunnelBindServer tunnelBindServer, CompactTransfer compactTransfer)
|
||||||
|
{
|
||||||
|
this.tunnelBindServer = tunnelBindServer;
|
||||||
|
tunnelBindServer.OnTcpConnected += OnTcpConnected;
|
||||||
|
|
||||||
|
this.compactTransfer = compactTransfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Socket> ConnectAsync(string fromMachineName, string toMachineName)
|
||||||
|
{
|
||||||
|
//获取自己的外网IP
|
||||||
|
TunnelCompactIPEndPoint[] ips = await compactTransfer.GetExternalIPAsync(TypeFlag);
|
||||||
|
if (ips.Length == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//告诉对方,我要连你,你需要给我发送一下 低TTL,并且对方要返回它的外网地址过来,给我去连接
|
||||||
|
TunnelTransportInfo tunnelTransportInfo = new TunnelTransportInfo
|
||||||
|
{
|
||||||
|
FromMachineName = fromMachineName,
|
||||||
|
ToMachineName = toMachineName,
|
||||||
|
FromLocal = ips[0].Local,
|
||||||
|
FromRemote = ips[0].Remote,
|
||||||
|
};
|
||||||
|
TunnelTransportInfo remoteInfo = await SendBegin(tunnelTransportInfo);
|
||||||
|
|
||||||
|
//要连接哪些IP
|
||||||
|
IPEndPoint[] eps = new IPEndPoint[] {
|
||||||
|
new IPEndPoint(remoteInfo.FromLocal.Address,remoteInfo.FromLocal.Port),
|
||||||
|
new IPEndPoint(remoteInfo.FromLocal.Address,remoteInfo.FromRemote.Port),
|
||||||
|
new IPEndPoint(remoteInfo.FromLocal.Address,remoteInfo.FromRemote.Port+1),
|
||||||
|
new IPEndPoint(remoteInfo.FromRemote.Address,remoteInfo.FromRemote.Port),
|
||||||
|
new IPEndPoint(remoteInfo.FromRemote.Address,remoteInfo.FromRemote.Port+1),
|
||||||
|
};
|
||||||
|
//过滤掉不支持IPV6的情况,去尝试连接
|
||||||
|
IEnumerable<IAsyncResult> results = eps.Where(c => NotIPv6Support(c.Address) == false).Select(ip =>
|
||||||
|
{
|
||||||
|
using Socket targetSocket = new(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
targetSocket.IPv6Only(ip.Address.AddressFamily, false);
|
||||||
|
targetSocket.ReuseBind(new IPEndPoint(ip.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, tunnelTransportInfo.FromLocal.Port));
|
||||||
|
IAsyncResult result = targetSocket.BeginConnect(ip, null, targetSocket);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
//检查一下是否连接成功
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
IAsyncResult result = results.FirstOrDefault(c => c.IsCompleted);
|
||||||
|
if (result != null)
|
||||||
|
{
|
||||||
|
return result.AsyncState as Socket;
|
||||||
|
}
|
||||||
|
await Task.Delay(10);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public async Task<TunnelTransportInfo> OnBegin(TunnelTransportInfo tunnelTransportInfo)
|
||||||
|
{
|
||||||
|
//获取自己的外网IP
|
||||||
|
TunnelCompactIPEndPoint[] ips = await compactTransfer.GetExternalIPAsync(ProtocolType.Tcp);
|
||||||
|
if (ips.Length == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
//监听,等对方来连
|
||||||
|
TunnelTransportInfo info = new TunnelTransportInfo
|
||||||
|
{
|
||||||
|
ToMachineName = tunnelTransportInfo.FromMachineName,
|
||||||
|
FromMachineName = tunnelTransportInfo.ToMachineName,
|
||||||
|
FromLocal = ips[0].Local,
|
||||||
|
FromRemote = ips[0].Remote,
|
||||||
|
RouteLevel = tunnelTransportInfo.RouteLevel
|
||||||
|
};
|
||||||
|
TransportTcpNutssbState state = new TransportTcpNutssbState { FromMachineName = tunnelTransportInfo.FromMachineName };
|
||||||
|
tunnelBindServer.Bind(info.FromLocal, state);
|
||||||
|
|
||||||
|
//给对方发送TTL消息
|
||||||
|
IPEndPoint[] eps = new IPEndPoint[] {
|
||||||
|
new IPEndPoint(tunnelTransportInfo.FromLocal.Address,tunnelTransportInfo.FromLocal.Port),
|
||||||
|
new IPEndPoint(tunnelTransportInfo.FromLocal.Address,tunnelTransportInfo.FromRemote.Port),
|
||||||
|
new IPEndPoint(tunnelTransportInfo.FromLocal.Address,tunnelTransportInfo.FromRemote.Port+1),
|
||||||
|
new IPEndPoint(tunnelTransportInfo.FromRemote.Address,tunnelTransportInfo.FromRemote.Port),
|
||||||
|
new IPEndPoint(tunnelTransportInfo.FromRemote.Address,tunnelTransportInfo.FromRemote.Port+1),
|
||||||
|
};
|
||||||
|
//过滤掉不支持IPV6的情况
|
||||||
|
IEnumerable<Socket> sockets = eps.Where(c => NotIPv6Support(c.Address) == false).Select(ip =>
|
||||||
|
{
|
||||||
|
using Socket targetSocket = new(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
targetSocket.IPv6Only(ip.Address.AddressFamily, false);
|
||||||
|
targetSocket.Ttl = (short)(info.RouteLevel);
|
||||||
|
targetSocket.ReuseBind(new IPEndPoint(ip.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, info.FromLocal.Port));
|
||||||
|
_ = targetSocket.ConnectAsync(ip);
|
||||||
|
return targetSocket;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
foreach (Socket item in sockets.Where(c => c != null && c.Connected == false))
|
||||||
|
{
|
||||||
|
item.SafeClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnReverse(TunnelTransportInfo tunnelTransportInfo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void OnTcpConnected(object state, Socket socket)
|
||||||
|
{
|
||||||
|
if (state is TransportTcpNutssbState _state)
|
||||||
|
{
|
||||||
|
OnConnected(new TransportState { FromMachineName = _state.FromMachineName, TypeFlag = ProtocolType.Tcp, ConnectedObject = socket });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool NotIPv6Support(IPAddress ip)
|
||||||
|
{
|
||||||
|
return ip.AddressFamily == AddressFamily.InterNetworkV6 && (NetworkHelper.IPv6Support == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class TransportTcpNutssbState
|
||||||
|
{
|
||||||
|
public string FromMachineName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@ namespace cmonitor.plugins.viewer.messenger
|
|||||||
public async Task ProxyFromServer(IConnection connection)
|
public async Task ProxyFromServer(IConnection connection)
|
||||||
{
|
{
|
||||||
ViewerProxyInfo proxy = MemoryPackSerializer.Deserialize<ViewerProxyInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
ViewerProxyInfo proxy = MemoryPackSerializer.Deserialize<ViewerProxyInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
proxy.ProxyEP = $"{clientSignInState.Connection.Address.Address}:{config.Data.Client.Viewer.ProxyPort}";
|
proxy.ProxyEP = new System.Net.IPEndPoint(clientSignInState.Connection.Address.Address,config.Data.Client.Viewer.ProxyPort);
|
||||||
proxy.TargetEP = runningConfig.Data.Viewer.ConnectEP;
|
proxy.TargetEP = runningConfig.Data.Viewer.ConnectEP;
|
||||||
await viewerProxyClient.Connect(proxy);
|
await viewerProxyClient.Connect(proxy);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -248,22 +248,13 @@ namespace cmonitor.plugins.viewer.proxy
|
|||||||
Socket targetSocket = null;
|
Socket targetSocket = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (IPEndPoint.TryParse(viewerProxyInfo.ProxyEP, out IPEndPoint proxyEP) == false)
|
proxySocket = new Socket(viewerProxyInfo.ProxyEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (IPEndPoint.TryParse(viewerProxyInfo.TargetEP, out IPEndPoint targetEP) == false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
proxySocket = new Socket(proxyEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
|
||||||
proxySocket.KeepAlive();
|
proxySocket.KeepAlive();
|
||||||
await proxySocket.ConnectAsync(proxyEP);
|
await proxySocket.ConnectAsync(viewerProxyInfo.ProxyEP);
|
||||||
|
|
||||||
targetSocket = new Socket(targetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
targetSocket = new Socket(viewerProxyInfo.TargetEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
targetSocket.KeepAlive();
|
targetSocket.KeepAlive();
|
||||||
await targetSocket.ConnectAsync(targetEP);
|
await targetSocket.ConnectAsync(viewerProxyInfo.TargetEP);
|
||||||
|
|
||||||
int length = responseBytes.Length + 4;
|
int length = responseBytes.Length + 4;
|
||||||
byte[] data = ArrayPool<byte>.Shared.Rent(length);
|
byte[] data = ArrayPool<byte>.Shared.Rent(length);
|
||||||
@@ -428,9 +419,11 @@ namespace cmonitor.plugins.viewer.proxy
|
|||||||
|
|
||||||
public string ViewerMachine { get; set; }
|
public string ViewerMachine { get; set; }
|
||||||
|
|
||||||
public string ProxyEP { get; set; }
|
[MemoryPackAllowSerialize]
|
||||||
|
public IPEndPoint ProxyEP { get; set; }
|
||||||
|
|
||||||
public string TargetEP { get; set; }
|
[MemoryPackAllowSerialize]
|
||||||
|
public IPEndPoint TargetEP { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ConnectServerCache
|
public sealed class ConnectServerCache
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace cmonitor.plugins.viewer.proxy
|
|||||||
Payload = MemoryPackSerializer.Serialize(new ViewerProxyInfo
|
Payload = MemoryPackSerializer.Serialize(new ViewerProxyInfo
|
||||||
{
|
{
|
||||||
ConnectId = connectId,
|
ConnectId = connectId,
|
||||||
ProxyEP = $"{clientSignInState.Connection.LocalAddress.Address}:{LocalEndpoint.Port}",
|
ProxyEP = new System.Net.IPEndPoint(clientSignInState.Connection.LocalAddress.Address, LocalEndpoint.Port),
|
||||||
ViewerMachine = runningConfig.Data.Viewer.ServerMachine
|
ViewerMachine = runningConfig.Data.Viewer.ServerMachine
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace cmonitor.plugins.viewer.proxy
|
|||||||
Payload = MemoryPackSerializer.Serialize(new ViewerProxyInfo
|
Payload = MemoryPackSerializer.Serialize(new ViewerProxyInfo
|
||||||
{
|
{
|
||||||
ConnectId = connectId,
|
ConnectId = connectId,
|
||||||
ProxyEP = string.Empty,
|
ProxyEP = null,
|
||||||
ViewerMachine = string.Empty
|
ViewerMachine = string.Empty
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ namespace cmonitor.plugins.viewer.report
|
|||||||
public void Open(bool value, ParamInfo info);
|
public void Open(bool value, ParamInfo info);
|
||||||
public string GetConnectString();
|
public string GetConnectString();
|
||||||
public void SetConnectString(string connectStr);
|
public void SetConnectString(string connectStr);
|
||||||
public string GetConnectEP(string connectStr)
|
public IPEndPoint GetConnectEP(string connectStr)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,8 @@ namespace cmonitor.plugins.viewer.report
|
|||||||
/// 比如 B 是共享服务端,A是共享客户端
|
/// 比如 B 是共享服务端,A是共享客户端
|
||||||
/// 当连不上时,会需要代理,由B去连接A或者B去连接服务器,形成通道,那B这边还需要手动连接共享服务,就用这个去连
|
/// 当连不上时,会需要代理,由B去连接A或者B去连接服务器,形成通道,那B这边还需要手动连接共享服务,就用这个去连
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ConnectEP { get; set; } = string.Empty;
|
[MemoryPackAllowSerialize]
|
||||||
|
public IPEndPoint ConnectEP { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ViewerMode : byte
|
public enum ViewerMode : byte
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ namespace cmonitor.plugins.viewer.report
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetConnectEP(string connectStr)
|
public IPEndPoint GetConnectEP(string connectStr)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ namespace cmonitor.plugins.viewer.report
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetConnectEP(string connectStr)
|
public IPEndPoint GetConnectEP(string connectStr)
|
||||||
{
|
{
|
||||||
return string.Empty;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ namespace cmonitor.plugins.viewer.report
|
|||||||
}
|
}
|
||||||
private void UpdateConnectEP()
|
private void UpdateConnectEP()
|
||||||
{
|
{
|
||||||
string connectEP = viewer.GetConnectEP(runningConfig.Data.Viewer.ConnectStr);
|
IPEndPoint connectEP = viewer.GetConnectEP(runningConfig.Data.Viewer.ConnectStr);
|
||||||
runningConfig.Data.Viewer.ConnectEP = connectEP;
|
runningConfig.Data.Viewer.ConnectEP = connectEP;
|
||||||
runningConfig.Data.Update();
|
runningConfig.Data.Update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ namespace cmonitor.plugins.viewer.report
|
|||||||
Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Cmonitor", "viewerConnectStr", connectStr);
|
Registry.SetValue("HKEY_CURRENT_USER\\SOFTWARE\\Cmonitor", "viewerConnectStr", connectStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetConnectEP(string connectStr)
|
public IPEndPoint GetConnectEP(string connectStr)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -48,13 +48,13 @@ namespace cmonitor.plugins.viewer.report
|
|||||||
var p = node.Attributes["P"].Value;
|
var p = node.Attributes["P"].Value;
|
||||||
var n = node.Attributes["N"].Value;
|
var n = node.Attributes["N"].Value;
|
||||||
|
|
||||||
return $"{n}:{p}";
|
return new IPEndPoint(IPAddress.Parse(n),int.Parse(p));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Instance.Error(ex);
|
Logger.Instance.Error(ex);
|
||||||
}
|
}
|
||||||
return string.Empty;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
cmonitor/serializes/IPEndPointFormatter.cs
Normal file
50
cmonitor/serializes/IPEndPointFormatter.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using common.libs.extends;
|
||||||
|
using MemoryPack;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
|
namespace cmonitor.serializes
|
||||||
|
{
|
||||||
|
public sealed class IPEndPointFormatter : MemoryPackFormatter<IPEndPoint>
|
||||||
|
{
|
||||||
|
public override void Serialize<TBufferWriter>(ref MemoryPackWriter<TBufferWriter> writer, scoped ref IPEndPoint value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
writer.WriteNullCollectionHeader();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Memory<byte> memory = new byte[20];
|
||||||
|
Span<byte> span = memory.Span;
|
||||||
|
int index = 1;
|
||||||
|
|
||||||
|
value.Address.TryWriteBytes(span.Slice(index), out int bytesWritten);
|
||||||
|
index += bytesWritten;
|
||||||
|
span[0] = (byte)bytesWritten;
|
||||||
|
|
||||||
|
ushort port = (ushort)value.Port;
|
||||||
|
port.ToBytes(memory.Slice(index));
|
||||||
|
index += 2;
|
||||||
|
|
||||||
|
writer.WriteCollectionHeader(index + 4);
|
||||||
|
writer.WriteSpan(span.Slice(0, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Deserialize(ref MemoryPackReader reader, scoped ref IPEndPoint value)
|
||||||
|
{
|
||||||
|
if (!reader.TryReadCollectionHeader(out int len))
|
||||||
|
{
|
||||||
|
value = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Span<byte> span = Array.Empty<byte>();
|
||||||
|
reader.ReadSpan(ref span);
|
||||||
|
|
||||||
|
int length = span[4];
|
||||||
|
value = new IPEndPoint(new IPAddress(span.Slice(4 + 1, length)), span.Slice(4 + 1 + length).ToUInt16());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
cmonitor/serializes/SerializeStartup.cs
Normal file
30
cmonitor/serializes/SerializeStartup.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using cmonitor.config;
|
||||||
|
using cmonitor.startup;
|
||||||
|
using MemoryPack;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace cmonitor.serializes
|
||||||
|
{
|
||||||
|
public sealed class SerializeStartup : IStartup
|
||||||
|
{
|
||||||
|
public void AddClient(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
|
{
|
||||||
|
MemoryPackFormatterProvider.Register(new IPEndPointFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
|
{
|
||||||
|
MemoryPackFormatterProvider.Register(new IPEndPointFormatter());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UseServer(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,8 @@ namespace cmonitor.startup
|
|||||||
types = types.Where(c => config.Data.Common.PluginNames.Any(d => c.FullName.Contains(d)));
|
types = types.Where(c => config.Data.Common.PluginNames.Any(d => c.FullName.Contains(d)));
|
||||||
}
|
}
|
||||||
startups = types.Select(c => Activator.CreateInstance(c) as IStartup).ToList();
|
startups = types.Select(c => Activator.CreateInstance(c) as IStartup).ToList();
|
||||||
|
|
||||||
|
Logger.Instance.Warning($"load startup : {string.Join(",", types.Select(c=>c.Name))}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Add(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
public static void Add(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.NetworkInformation;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace common.libs
|
namespace common.libs
|
||||||
{
|
{
|
||||||
@@ -46,6 +49,75 @@ namespace common.libs
|
|||||||
return new IPEndPoint(ip, port);
|
return new IPEndPoint(ip, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ushort GetRouteLevel(out List<IPAddress> ips)
|
||||||
|
{
|
||||||
|
ips = new List<IPAddress>();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<string> starts = new() { "10.", "100.", "192.168.", "172." };
|
||||||
|
var list = GetTraceRoute("www.baidu.com").ToList();
|
||||||
|
for (ushort i = 0; i < list.Count(); i++)
|
||||||
|
{
|
||||||
|
string ip = list.ElementAt(i).ToString();
|
||||||
|
if (ip.StartsWith(starts[0], StringComparison.Ordinal) || ip.StartsWith(starts[1], StringComparison.Ordinal) || ip.StartsWith(starts[2], StringComparison.Ordinal) || ip.StartsWith(starts[3], StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
if (ip.StartsWith(starts[2], StringComparison.Ordinal) == false)
|
||||||
|
ips.Add(list.ElementAt(i));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
public static IEnumerable<IPAddress> GetTraceRoute(string hostNameOrAddress)
|
||||||
|
{
|
||||||
|
return GetTraceRoute(hostNameOrAddress, 1);
|
||||||
|
}
|
||||||
|
private static IEnumerable<IPAddress> GetTraceRoute(string hostNameOrAddress, int ttl)
|
||||||
|
{
|
||||||
|
Ping pinger = new();
|
||||||
|
// 创建PingOptions对象
|
||||||
|
PingOptions pingerOptions = new(ttl, true);
|
||||||
|
int timeout = 100;
|
||||||
|
byte[] buffer = Encoding.ASCII.GetBytes("11");
|
||||||
|
// 创建PingReply对象
|
||||||
|
// 发送ping命令
|
||||||
|
PingReply reply = pinger.Send(hostNameOrAddress, timeout, buffer, pingerOptions);
|
||||||
|
|
||||||
|
// 处理返回结果
|
||||||
|
List<IPAddress> result = new();
|
||||||
|
if (reply.Status == IPStatus.Success)
|
||||||
|
{
|
||||||
|
result.Add(reply.Address);
|
||||||
|
}
|
||||||
|
else if (reply.Status == IPStatus.TtlExpired || reply.Status == IPStatus.TimedOut)
|
||||||
|
{
|
||||||
|
//增加当前这个访问地址
|
||||||
|
if (reply.Status == IPStatus.TtlExpired)
|
||||||
|
{
|
||||||
|
result.Add(reply.Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ttl <= 10)
|
||||||
|
{
|
||||||
|
//递归访问下一个地址
|
||||||
|
IEnumerable<IPAddress> tempResult = GetTraceRoute(hostNameOrAddress, ttl + 1);
|
||||||
|
result.AddRange(tempResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//失败
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if DISABLE_IPV6 || (!UNITY_EDITOR && ENABLE_IL2CPP && !UNITY_2018_3_OR_NEWER)
|
#if DISABLE_IPV6 || (!UNITY_EDITOR && ENABLE_IL2CPP && !UNITY_2018_3_OR_NEWER)
|
||||||
public static bool IPv6Support = false;
|
public static bool IPv6Support = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user