mirror of
https://github.com/snltty/linker.git
synced 2025-11-03 01:53:32 +08:00
增加打洞和中继插件,后续桌面共享的代理将有这两个插件去实现通信
This commit is contained in:
5
cmonitor.web.client/src/apis/relay.js
Normal file
5
cmonitor.web.client/src/apis/relay.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { sendWebsocketMsg } from './request'
|
||||||
|
|
||||||
|
export const updateRelayConnect = (machineName) => {
|
||||||
|
return sendWebsocketMsg('relay/Connect', machineName);
|
||||||
|
}
|
||||||
21
cmonitor.web.client/src/apis/signin.js
Normal file
21
cmonitor.web.client/src/apis/signin.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { sendWebsocketMsg } from './request'
|
||||||
|
|
||||||
|
export const getConfig = () => {
|
||||||
|
return sendWebsocketMsg('signInclient/config');
|
||||||
|
}
|
||||||
|
export const updateConfigSet = (data) => {
|
||||||
|
return sendWebsocketMsg('signInclient/set', data);
|
||||||
|
}
|
||||||
|
export const updateConfigSetServers = (servers) => {
|
||||||
|
return sendWebsocketMsg('signInclient/setservers', servers);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getSignInfo = () => {
|
||||||
|
return sendWebsocketMsg('signInclient/info');
|
||||||
|
}
|
||||||
|
export const getSignList = (data) => {
|
||||||
|
return sendWebsocketMsg('signInclient/List', data);
|
||||||
|
}
|
||||||
|
export const updateSignInDel = (machineName) => {
|
||||||
|
return sendWebsocketMsg('signInclient/del', machineName);
|
||||||
|
}
|
||||||
@@ -1,25 +1,5 @@
|
|||||||
import { sendWebsocketMsg } from './request'
|
import { sendWebsocketMsg } from './request'
|
||||||
|
|
||||||
export const getConfig = () => {
|
|
||||||
return sendWebsocketMsg('tunnel/config');
|
|
||||||
}
|
|
||||||
export const updateConfigSet = (data) => {
|
|
||||||
return sendWebsocketMsg('tunnel/configset', data);
|
|
||||||
}
|
|
||||||
export const updateConfigSetServers = (servers) => {
|
|
||||||
return sendWebsocketMsg('tunnel/configsetservers', servers);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getSignInfo = () => {
|
|
||||||
return sendWebsocketMsg('tunnel/signininfo');
|
|
||||||
}
|
|
||||||
export const getSignList = (data) => {
|
|
||||||
return sendWebsocketMsg('tunnel/SignInList', data);
|
|
||||||
}
|
|
||||||
export const updateSignInDel = (machineName) => {
|
|
||||||
return sendWebsocketMsg('tunnel/signindel', machineName);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const updateTunnelConnect = (machineName) => {
|
export const updateTunnelConnect = (machineName) => {
|
||||||
return sendWebsocketMsg('tunnel/TunnelConnect', machineName);
|
return sendWebsocketMsg('tunnel/Connect', machineName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { computed, onMounted, reactive, watch } from 'vue';
|
import { computed, onMounted, reactive, watch } from 'vue';
|
||||||
import { initWebsocket, subWebsocketState } from '../apis/request'
|
import { initWebsocket, subWebsocketState } from '../apis/request'
|
||||||
import { getConfig,getSignInfo } from '../apis/tunnel'
|
import { getConfig,getSignInfo } from '../apis/signin'
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { injectGlobalData } from '../provide';
|
import { injectGlobalData } from '../provide';
|
||||||
export default {
|
export default {
|
||||||
@@ -65,12 +65,14 @@ export default {
|
|||||||
|
|
||||||
const _getConfig = ()=>{
|
const _getConfig = ()=>{
|
||||||
getConfig().then((res)=>{
|
getConfig().then((res)=>{
|
||||||
|
console.log(res);
|
||||||
globalData.value.config.Common = res.Data.Common;
|
globalData.value.config.Common = res.Data.Common;
|
||||||
globalData.value.config.Client = res.Data.Client;
|
globalData.value.config.Client = res.Data.Client;
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
_getConfig();
|
_getConfig();
|
||||||
},1000);
|
},1000);
|
||||||
}).catch((err)=>{
|
}).catch((err)=>{
|
||||||
|
console.log(err);
|
||||||
setTimeout(()=>{
|
setTimeout(()=>{
|
||||||
_getConfig();
|
_getConfig();
|
||||||
},1000);
|
},1000);
|
||||||
|
|||||||
@@ -75,7 +75,7 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { updateConfigSet, updateConfigSetServers } from '@/apis/tunnel';
|
import { updateConfigSet, updateConfigSetServers } from '@/apis/signin';
|
||||||
import { injectGlobalData } from '@/provide';
|
import { injectGlobalData } from '@/provide';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import { computed, reactive } from 'vue';
|
import { computed, reactive } from 'vue';
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ import 'element-plus/theme-chalk/display.css'
|
|||||||
import 'element-plus/theme-chalk/dark/css-vars.css'
|
import 'element-plus/theme-chalk/dark/css-vars.css'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ChromeFilled,
|
ArrowDown,
|
||||||
} from '@element-plus/icons-vue'
|
} from '@element-plus/icons-vue'
|
||||||
app.component(ChromeFilled.name, ChromeFilled);
|
app.component(ArrowDown.name, ArrowDown);
|
||||||
|
|
||||||
|
|
||||||
app.use(ElementPlus, { size: 'default' }).use(router).mount('#app');
|
app.use(ElementPlus, { size: 'default' }).use(router).mount('#app');
|
||||||
|
|||||||
@@ -18,8 +18,18 @@
|
|||||||
<el-table-column prop="LastSignIn" label="最后登入" width="140" />
|
<el-table-column prop="LastSignIn" label="最后登入" width="140" />
|
||||||
<el-table-column label="操作">
|
<el-table-column label="操作">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button size="small" @click="handleTestTunnel(scope.row.MachineName)">测试</el-button>
|
<el-dropdown>
|
||||||
<el-popconfirm confirm-button-text="确认" cancel-button-text="取消" title="删除不可逆,是否确认?" @confirm="handleDelTunnel(scope.row.MachineName)">
|
<el-button size="small">
|
||||||
|
测试<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="handleTestTunnel(scope.row.MachineName)">打洞</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click="handleTestRelay(scope.row.MachineName)">中继</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
<el-popconfirm confirm-button-text="确认" cancel-button-text="取消" title="删除不可逆,是否确认?" @confirm="handleDel(scope.row.MachineName)">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-button type="danger" size="small">删除</el-button>
|
<el-button type="danger" size="small">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -37,7 +47,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import {getSignList,updateTunnelConnect,updateSignInDel} from '@/apis/tunnel.js'
|
import {getSignList,updateSignInDel} from '@/apis/signin.js'
|
||||||
|
import {updateTunnelConnect} from '@/apis/tunnel.js'
|
||||||
|
import {updateRelayConnect} from '@/apis/relay.js'
|
||||||
import {subWebsocketState} from '@/apis/request.js'
|
import {subWebsocketState} from '@/apis/request.js'
|
||||||
import {injectGlobalData} from '../provide.js'
|
import {injectGlobalData} from '../provide.js'
|
||||||
import {reactive,onMounted, ref, nextTick, onUnmounted} from 'vue'
|
import {reactive,onMounted, ref, nextTick, onUnmounted} from 'vue'
|
||||||
@@ -73,7 +85,10 @@ export default {
|
|||||||
const handleTestTunnel = (name)=>{
|
const handleTestTunnel = (name)=>{
|
||||||
updateTunnelConnect(name);
|
updateTunnelConnect(name);
|
||||||
}
|
}
|
||||||
const handleDelTunnel = (name)=>{
|
const handleTestRelay = (name)=>{
|
||||||
|
updateRelayConnect(name);
|
||||||
|
}
|
||||||
|
const handleDel = (name)=>{
|
||||||
updateSignInDel(name).then(()=>{
|
updateSignInDel(name).then(()=>{
|
||||||
_getSignList();
|
_getSignList();
|
||||||
});
|
});
|
||||||
@@ -89,7 +104,7 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
state,wrap,handlePageChange,handleTestTunnel,handleDelTunnel
|
state,wrap,handlePageChange,handleTestTunnel,handleTestRelay,handleDel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { sendWebsocketMsg } from './request'
|
import { sendWebsocketMsg } from './request'
|
||||||
|
|
||||||
export const getList = (groupid) => {
|
export const getList = (groupid) => {
|
||||||
return sendWebsocketMsg('signin/list', groupid);
|
return sendWebsocketMsg('signinserver/list', groupid);
|
||||||
}
|
}
|
||||||
export const getConfig = () => {
|
export const getConfig = () => {
|
||||||
return sendWebsocketMsg('signin/config');
|
return sendWebsocketMsg('signinserver/config');
|
||||||
}
|
}
|
||||||
export const delDevice = (name) => {
|
export const delDevice = (name) => {
|
||||||
return sendWebsocketMsg('signin/del', name);
|
return sendWebsocketMsg('signinserver/del', name);
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ namespace cmonitor.config
|
|||||||
{
|
{
|
||||||
"cmonitor.client.","cmonitor.server.","cmonitor.serializes.",
|
"cmonitor.client.","cmonitor.server.","cmonitor.serializes.",
|
||||||
"cmonitor.plugins.signin.", "cmonitor.plugins.watch.","cmonitor.plugins.devices.","cmonitor.plugins.report.",
|
"cmonitor.plugins.signin.", "cmonitor.plugins.watch.","cmonitor.plugins.devices.","cmonitor.plugins.report.",
|
||||||
"cmonitor.plugins.share.","cmonitor.plugins.rule.","cmonitor.plugins.modes.",
|
"cmonitor.plugins.share.","cmonitor.plugins.rule.","cmonitor.plugins.modes.","cmonitor.plugins.tunnel.","cmonitor.plugins.relay",
|
||||||
}).Distinct().ToArray();
|
}).Distinct().ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
77
cmonitor/plugins/relay/RelayApiController.cs
Normal file
77
cmonitor/plugins/relay/RelayApiController.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using cmonitor.client.api;
|
||||||
|
using cmonitor.config;
|
||||||
|
using cmonitor.plugins.relay.transport;
|
||||||
|
using common.libs;
|
||||||
|
using common.libs.api;
|
||||||
|
using common.libs.extends;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace cmonitor.plugins.relay
|
||||||
|
{
|
||||||
|
public sealed class RelayApiController : IApiClientController
|
||||||
|
{
|
||||||
|
private readonly Config config;
|
||||||
|
private readonly RelayTransfer relayTransfer;
|
||||||
|
|
||||||
|
public RelayApiController(Config config, RelayTransfer relayTransfer)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.relayTransfer = relayTransfer;
|
||||||
|
|
||||||
|
RelayTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Connect(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
Task.Run(async () =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RelayTransportState state = await relayTransfer.ConnectAsync(param.Content, "test", config.Data.Client.Relay.SecretKey);
|
||||||
|
if (state != null)
|
||||||
|
{
|
||||||
|
var socket = state.Socket;
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
Logger.Instance.Debug($"relay [test] send {i}");
|
||||||
|
socket.Send(Encoding.UTF8.GetBytes($"snltty.relay.{i}"));
|
||||||
|
await Task.Delay(10);
|
||||||
|
}
|
||||||
|
socket.SafeClose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex + "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void RelayTest()
|
||||||
|
{
|
||||||
|
relayTransfer.OnConnected += (RelayTransportState state) =>
|
||||||
|
{
|
||||||
|
if (state.Info.TransactionId == "test")
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
byte[] bytes = new byte[1024];
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int length = state.Socket.Receive(bytes);
|
||||||
|
if (length == 0) break;
|
||||||
|
|
||||||
|
Logger.Instance.Debug($"relay [{state.Info.TransactionId}] receive {Encoding.UTF8.GetString(bytes.AsSpan(0,length))}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ConfigSetInfo
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string GroupId { get; set; }
|
||||||
|
public string Server { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
45
cmonitor/plugins/relay/RelayStartup.cs
Normal file
45
cmonitor/plugins/relay/RelayStartup.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using cmonitor.config;
|
||||||
|
using cmonitor.plugins.relay.messenger;
|
||||||
|
using cmonitor.plugins.relay.transport;
|
||||||
|
using cmonitor.startup;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace cmonitor.plugins.relay
|
||||||
|
{
|
||||||
|
public sealed class RelayStartup : IStartup
|
||||||
|
{
|
||||||
|
public StartupLevel Level => StartupLevel.Normal;
|
||||||
|
public void AddClient(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
|
{
|
||||||
|
serviceCollection.AddSingleton<RelayApiController>();
|
||||||
|
serviceCollection.AddSingleton<RelayClientMessenger>();
|
||||||
|
serviceCollection.AddSingleton<TransportSelfHost>();
|
||||||
|
serviceCollection.AddSingleton<RelayTransfer>();
|
||||||
|
|
||||||
|
|
||||||
|
if (config.Data.Client.Relay.Servers.Length == 0)
|
||||||
|
{
|
||||||
|
config.Data.Client.Relay.Servers = new RelayCompactInfo[]
|
||||||
|
{
|
||||||
|
new RelayCompactInfo{ Name="self", Disabled = false, Host = config.Data.Client.Server }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
|
{
|
||||||
|
serviceCollection.AddSingleton<RelayServerMessenger>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||||
|
{
|
||||||
|
RelayTransfer relayTransfer = serviceProvider.GetService<RelayTransfer>();
|
||||||
|
relayTransfer.Load(assemblies);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UseServer(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
90
cmonitor/plugins/relay/RelayTransfer.cs
Normal file
90
cmonitor/plugins/relay/RelayTransfer.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
using cmonitor.client;
|
||||||
|
using cmonitor.config;
|
||||||
|
using cmonitor.plugins.relay.transport;
|
||||||
|
using cmonitor.server;
|
||||||
|
using common.libs;
|
||||||
|
using common.libs.extends;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace cmonitor.plugins.relay
|
||||||
|
{
|
||||||
|
public sealed class RelayTransfer
|
||||||
|
{
|
||||||
|
private List<ITransport> transports;
|
||||||
|
|
||||||
|
private readonly Config config;
|
||||||
|
private readonly ServiceProvider serviceProvider;
|
||||||
|
|
||||||
|
public Action<RelayTransportState> OnConnected { get; set; } = (state) => { };
|
||||||
|
|
||||||
|
public RelayTransfer(Config config, ServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load(Assembly[] assembs)
|
||||||
|
{
|
||||||
|
IEnumerable<Type> types = ReflectionHelper.GetInterfaceSchieves(assembs, typeof(ITransport));
|
||||||
|
types = config.Data.Common.PluginContains(types);
|
||||||
|
transports = types.Select(c => (ITransport)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Name) == false).ToList();
|
||||||
|
|
||||||
|
Logger.Instance.Warning($"load relay transport:{string.Join(",", transports.Select(c => c.Name))}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<RelayTransportState> ConnectAsync(string remoteMachineName, string transactionId, string secretKey)
|
||||||
|
{
|
||||||
|
IEnumerable<ITransport> _transports = transports.OrderBy(c => c.Name);
|
||||||
|
foreach (RelayCompactInfo item in config.Data.Client.Relay.Servers.Where(c=>c.Disabled == false))
|
||||||
|
{
|
||||||
|
ITransport transport = _transports.FirstOrDefault(c => c.Name == item.Name);
|
||||||
|
if (transport == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IPEndPoint server = NetworkHelper.GetEndPoint(item.Host, 3478);
|
||||||
|
RelayInfo relayInfo = new RelayInfo
|
||||||
|
{
|
||||||
|
FlowingId = 0,
|
||||||
|
RemoteMachineName = remoteMachineName,
|
||||||
|
SecretKey = secretKey,
|
||||||
|
Server = server,
|
||||||
|
TransactionId = transactionId,
|
||||||
|
TransportName = transport.Name
|
||||||
|
};
|
||||||
|
Socket socket = await transport.RelayAsync(relayInfo);
|
||||||
|
if (socket != null)
|
||||||
|
{
|
||||||
|
return new RelayTransportState { Info = relayInfo, Socket = socket };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.Instance.Error(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public async Task<bool> OnBeginAsync(RelayInfo relayInfo)
|
||||||
|
{
|
||||||
|
ITransport _transports = transports.FirstOrDefault(c => c.Name == relayInfo.TransportName);
|
||||||
|
if (_transports != null)
|
||||||
|
{
|
||||||
|
Socket socket = await _transports.OnBeginAsync(relayInfo);
|
||||||
|
if (socket != null)
|
||||||
|
{
|
||||||
|
OnConnected(new RelayTransportState { Info = relayInfo, Socket = socket });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
29
cmonitor/plugins/relay/config/Config.cs
Normal file
29
cmonitor/plugins/relay/config/Config.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
namespace cmonitor.config
|
||||||
|
{
|
||||||
|
public partial class ConfigClientInfo
|
||||||
|
{
|
||||||
|
public RelayConfigClientInfo Relay { get; set; } = new RelayConfigClientInfo();
|
||||||
|
}
|
||||||
|
public partial class ConfigServerInfo
|
||||||
|
{
|
||||||
|
public RelayConfigServerInfo Relay { get; set; } = new RelayConfigServerInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class RelayConfigClientInfo
|
||||||
|
{
|
||||||
|
public RelayCompactInfo[] Servers { get; set; } = Array.Empty<RelayCompactInfo>();
|
||||||
|
public string SecretKey { get; set; } = "snltty";
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class RelayConfigServerInfo
|
||||||
|
{
|
||||||
|
public string SecretKey { get; set; } = "snltty";
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class RelayCompactInfo
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Host { get; set; }
|
||||||
|
public bool Disabled { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
112
cmonitor/plugins/relay/messenger/RelayMessenger.cs
Normal file
112
cmonitor/plugins/relay/messenger/RelayMessenger.cs
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
using cmonitor.config;
|
||||||
|
using cmonitor.plugins.relay.transport;
|
||||||
|
using cmonitor.plugins.signin.messenger;
|
||||||
|
using cmonitor.server;
|
||||||
|
using common.libs;
|
||||||
|
using MemoryPack;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace cmonitor.plugins.relay.messenger
|
||||||
|
{
|
||||||
|
public sealed class RelayClientMessenger : IMessenger
|
||||||
|
{
|
||||||
|
private readonly RelayTransfer relayTransfer;
|
||||||
|
public RelayClientMessenger(RelayTransfer relayTransfer)
|
||||||
|
{
|
||||||
|
this.relayTransfer = relayTransfer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MessengerId((ushort)RelayMessengerIds.Relay)]
|
||||||
|
public async Task Relay(IConnection connection)
|
||||||
|
{
|
||||||
|
RelayInfo info = MemoryPackSerializer.Deserialize<RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
bool res = await relayTransfer.OnBeginAsync(info);
|
||||||
|
connection.Write(res ? Helper.TrueArray : Helper.FalseArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class RelayServerMessenger : IMessenger
|
||||||
|
{
|
||||||
|
private readonly Config config;
|
||||||
|
private readonly MessengerSender messengerSender;
|
||||||
|
private readonly SignCaching signCaching;
|
||||||
|
private readonly ConcurrentDictionary<ulong, TaskCompletionSource<IConnection>> dic = new ConcurrentDictionary<ulong, TaskCompletionSource<IConnection>>();
|
||||||
|
private ulong flowingId = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public RelayServerMessenger(Config config, MessengerSender messengerSender, SignCaching signCaching)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.messengerSender = messengerSender;
|
||||||
|
this.signCaching = signCaching;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MessengerId((ushort)RelayMessengerIds.RelayForward)]
|
||||||
|
public async Task RelayForward(IConnection connection)
|
||||||
|
{
|
||||||
|
RelayInfo info = MemoryPackSerializer.Deserialize<RelayInfo>(connection.ReceiveRequestWrap.Payload.Span);
|
||||||
|
if (info.FlowingId == 0)
|
||||||
|
{
|
||||||
|
if (info.SecretKey != config.Data.Client.Relay.SecretKey)
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (signCaching.Get(info.RemoteMachineName, out SignCacheInfo cache) == false)
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.FlowingId = Interlocked.Increment(ref flowingId);
|
||||||
|
TaskCompletionSource<IConnection> tcs = new TaskCompletionSource<IConnection>();
|
||||||
|
dic.TryAdd(info.FlowingId, tcs);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = cache.Connection,
|
||||||
|
MessengerId = (ushort)RelayMessengerIds.Relay,
|
||||||
|
Payload = MemoryPackSerializer.Serialize(info)
|
||||||
|
});
|
||||||
|
if (resp.Code != MessageResponeCodes.OK || resp.Data.Span.SequenceEqual(Helper.TrueArray) == false)
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IConnection targetConnection = await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(3000));
|
||||||
|
connection.TcpTargetSocket = targetConnection.TcpSourceSocket;
|
||||||
|
targetConnection.TcpTargetSocket = connection.TcpSourceSocket;
|
||||||
|
connection.Write(Helper.TrueArray);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
dic.TryRemove(info.FlowingId, out _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dic.TryRemove(info.FlowingId, out TaskCompletionSource<IConnection> tcs))
|
||||||
|
{
|
||||||
|
tcs.SetResult(connection);
|
||||||
|
connection.Write(Helper.TrueArray);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
connection.Write(Helper.FalseArray);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
12
cmonitor/plugins/relay/messenger/RelayMessengerIds.cs
Normal file
12
cmonitor/plugins/relay/messenger/RelayMessengerIds.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace cmonitor.plugins.relay.messenger
|
||||||
|
{
|
||||||
|
public enum RelayMessengerIds : ushort
|
||||||
|
{
|
||||||
|
Update = 2100,
|
||||||
|
|
||||||
|
Relay = 2101,
|
||||||
|
RelayForward = 2102,
|
||||||
|
|
||||||
|
None = 2199
|
||||||
|
}
|
||||||
|
}
|
||||||
38
cmonitor/plugins/relay/transport/ITransport.cs
Normal file
38
cmonitor/plugins/relay/transport/ITransport.cs
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
using cmonitor.plugins.relay.messenger;
|
||||||
|
using MemoryPack;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace cmonitor.plugins.relay.transport
|
||||||
|
{
|
||||||
|
public interface ITransport
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
public Task<Socket> RelayAsync(RelayInfo relayInfo);
|
||||||
|
public Task<Socket> OnBeginAsync(RelayInfo relayInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public sealed partial class RelayInfo
|
||||||
|
{
|
||||||
|
public string RemoteMachineName { get; set; }
|
||||||
|
public string TransactionId { get; set; }
|
||||||
|
public string SecretKey { get; set; }
|
||||||
|
public string TransportName { get; set; }
|
||||||
|
|
||||||
|
public ulong FlowingId { get; set; }
|
||||||
|
|
||||||
|
[MemoryPackAllowSerialize]
|
||||||
|
public IPEndPoint Server { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class RelayTransportState
|
||||||
|
{
|
||||||
|
public RelayInfo Info { get; set; }
|
||||||
|
|
||||||
|
public Socket Socket { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
73
cmonitor/plugins/relay/transport/TransportSelfHost.cs
Normal file
73
cmonitor/plugins/relay/transport/TransportSelfHost.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using cmonitor.plugins.relay.messenger;
|
||||||
|
using cmonitor.server;
|
||||||
|
using common.libs;
|
||||||
|
using common.libs.extends;
|
||||||
|
using MemoryPack;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace cmonitor.plugins.relay.transport
|
||||||
|
{
|
||||||
|
public sealed class TransportSelfHost : ITransport
|
||||||
|
{
|
||||||
|
public string Name => "self";
|
||||||
|
|
||||||
|
private readonly TcpServer tcpServer;
|
||||||
|
private readonly MessengerSender messengerSender;
|
||||||
|
private readonly Memory<byte> relayFlagData = Encoding.UTF8.GetBytes("snltty.relay").AsMemory();
|
||||||
|
|
||||||
|
public TransportSelfHost(TcpServer tcpServer, MessengerSender messengerSender)
|
||||||
|
{
|
||||||
|
this.tcpServer = tcpServer;
|
||||||
|
this.messengerSender = messengerSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Socket> RelayAsync(RelayInfo relayInfo)
|
||||||
|
{
|
||||||
|
Socket socket = new Socket(relayInfo.Server.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
socket.Reuse(true);
|
||||||
|
socket.IPv6Only(relayInfo.Server.AddressFamily, false);
|
||||||
|
await socket.ConnectAsync(relayInfo.Server).WaitAsync(TimeSpan.FromSeconds(5));
|
||||||
|
|
||||||
|
IConnection connection = tcpServer.BindReceive(socket);
|
||||||
|
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = connection,
|
||||||
|
MessengerId = (ushort)RelayMessengerIds.RelayForward,
|
||||||
|
Payload = MemoryPackSerializer.Serialize(relayInfo)
|
||||||
|
});
|
||||||
|
if (resp.Code != MessageResponeCodes.OK || resp.Data.Span.SequenceEqual(Helper.TrueArray) == false)
|
||||||
|
{
|
||||||
|
connection.Disponse();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
await socket.SendAsync(relayFlagData);
|
||||||
|
await Task.Delay(10);
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Socket> OnBeginAsync(RelayInfo relayInfo)
|
||||||
|
{
|
||||||
|
Socket socket = new Socket(relayInfo.Server.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
socket.Reuse(true);
|
||||||
|
socket.IPv6Only(relayInfo.Server.AddressFamily, false);
|
||||||
|
await socket.ConnectAsync(relayInfo.Server).WaitAsync(TimeSpan.FromSeconds(5));
|
||||||
|
|
||||||
|
IConnection connection = tcpServer.BindReceive(socket);
|
||||||
|
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = connection,
|
||||||
|
MessengerId = (ushort)RelayMessengerIds.RelayForward,
|
||||||
|
Payload = MemoryPackSerializer.Serialize(relayInfo)
|
||||||
|
});
|
||||||
|
if (resp.Code != MessageResponeCodes.OK || resp.Data.Span.SequenceEqual(Helper.TrueArray) == false)
|
||||||
|
{
|
||||||
|
connection.Disponse();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
await socket.SendAsync(relayFlagData);
|
||||||
|
await Task.Delay(10);
|
||||||
|
return socket;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,14 +2,19 @@
|
|||||||
using cmonitor.config;
|
using cmonitor.config;
|
||||||
using cmonitor.plugins.signin.messenger;
|
using cmonitor.plugins.signin.messenger;
|
||||||
using common.libs.api;
|
using common.libs.api;
|
||||||
|
using cmonitor.client.api;
|
||||||
|
using common.libs.extends;
|
||||||
|
using cmonitor.client;
|
||||||
|
using cmonitor.server;
|
||||||
|
using MemoryPack;
|
||||||
|
|
||||||
namespace cmonitor.plugins.signin
|
namespace cmonitor.plugins.signin
|
||||||
{
|
{
|
||||||
public sealed class SignInApiController : IApiServerController
|
public sealed class SignInServerApiController : IApiServerController
|
||||||
{
|
{
|
||||||
private readonly SignCaching signCaching;
|
private readonly SignCaching signCaching;
|
||||||
private readonly Config config;
|
private readonly Config config;
|
||||||
public SignInApiController(SignCaching signCaching, Config config)
|
public SignInServerApiController(SignCaching signCaching, Config config)
|
||||||
{
|
{
|
||||||
this.signCaching = signCaching;
|
this.signCaching = signCaching;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
@@ -31,4 +36,77 @@ namespace cmonitor.plugins.signin
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class SignInClientApiController : IApiClientController
|
||||||
|
{
|
||||||
|
private readonly Config config;
|
||||||
|
private readonly ClientSignInState clientSignInState;
|
||||||
|
private readonly ClientSignInTransfer clientSignInTransfer;
|
||||||
|
private readonly MessengerSender messengerSender;
|
||||||
|
|
||||||
|
public SignInClientApiController(Config config, ClientSignInState clientSignInState, ClientSignInTransfer clientSignInTransfer, MessengerSender messengerSender)
|
||||||
|
{
|
||||||
|
this.config = config;
|
||||||
|
this.clientSignInState = clientSignInState;
|
||||||
|
this.clientSignInTransfer = clientSignInTransfer;
|
||||||
|
this.messengerSender = messengerSender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Config Config(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
public void Set(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
ConfigSetInfo info = param.Content.DeJson<ConfigSetInfo>();
|
||||||
|
config.Data.Client.Name = info.Name;
|
||||||
|
config.Data.Client.GroupId = info.GroupId;
|
||||||
|
config.Data.Client.Server = info.Server;
|
||||||
|
config.Save();
|
||||||
|
clientSignInTransfer.SignOut();
|
||||||
|
_ = clientSignInTransfer.SignIn();
|
||||||
|
}
|
||||||
|
public void SetServers(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
config.Data.Client.Servers = param.Content.DeJson<ClientServerInfo[]>();
|
||||||
|
config.Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientSignInState Info(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
return clientSignInState;
|
||||||
|
}
|
||||||
|
public async Task Del(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
await messengerSender.SendOnly(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = clientSignInState.Connection,
|
||||||
|
MessengerId = (ushort)SignInMessengerIds.Delete,
|
||||||
|
Payload = MemoryPackSerializer.Serialize(param.Content)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public async Task<SignInListResponseInfo> List(ApiControllerParamsInfo param)
|
||||||
|
{
|
||||||
|
SignInListRequestInfo request = param.Content.DeJson<SignInListRequestInfo>();
|
||||||
|
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
|
{
|
||||||
|
Connection = clientSignInState.Connection,
|
||||||
|
MessengerId = (ushort)SignInMessengerIds.List,
|
||||||
|
Payload = MemoryPackSerializer.Serialize(request)
|
||||||
|
});
|
||||||
|
if (resp.Code == MessageResponeCodes.OK)
|
||||||
|
{
|
||||||
|
return MemoryPackSerializer.Deserialize<SignInListResponseInfo>(resp.Data.Span);
|
||||||
|
}
|
||||||
|
return new SignInListResponseInfo { };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class ConfigSetInfo
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string GroupId { get; set; }
|
||||||
|
public string Server { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,13 +12,15 @@ namespace cmonitor.plugins.signin
|
|||||||
|
|
||||||
public void AddClient(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
public void AddClient(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
{
|
{
|
||||||
|
serviceCollection.AddSingleton<SignInClientApiController>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
{
|
{
|
||||||
serviceCollection.AddSingleton<SignCaching>();
|
serviceCollection.AddSingleton<SignCaching>();
|
||||||
serviceCollection.AddSingleton<SignInMessenger>();
|
serviceCollection.AddSingleton<SignInMessenger>();
|
||||||
serviceCollection.AddSingleton<SignInApiController>();
|
serviceCollection.AddSingleton<SignInServerApiController>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
public void UseClient(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||||
|
|||||||
@@ -16,80 +16,23 @@ namespace cmonitor.plugins.tunnel
|
|||||||
{
|
{
|
||||||
public sealed class TunnelApiController : IApiClientController
|
public sealed class TunnelApiController : IApiClientController
|
||||||
{
|
{
|
||||||
private readonly Config config;
|
|
||||||
private readonly ClientSignInState clientSignInState;
|
|
||||||
private readonly ClientSignInTransfer clientSignInTransfer;
|
|
||||||
private readonly MessengerSender messengerSender;
|
|
||||||
private readonly TunnelTransfer tunnelTransfer;
|
private readonly TunnelTransfer tunnelTransfer;
|
||||||
private readonly TunnelBindServer tunnelBindServer;
|
private readonly TunnelBindServer tunnelBindServer;
|
||||||
|
|
||||||
public TunnelApiController(Config config, ClientSignInState clientSignInState, ClientSignInTransfer clientSignInTransfer, MessengerSender messengerSender, TunnelTransfer tunnelTransfer,
|
public TunnelApiController(TunnelTransfer tunnelTransfer,
|
||||||
TunnelBindServer tunnelBindServer)
|
TunnelBindServer tunnelBindServer)
|
||||||
{
|
{
|
||||||
this.config = config;
|
|
||||||
this.clientSignInState = clientSignInState;
|
|
||||||
this.clientSignInTransfer = clientSignInTransfer;
|
|
||||||
this.messengerSender = messengerSender;
|
|
||||||
this.tunnelTransfer = tunnelTransfer;
|
this.tunnelTransfer = tunnelTransfer;
|
||||||
this.tunnelBindServer = tunnelBindServer;
|
this.tunnelBindServer = tunnelBindServer;
|
||||||
|
|
||||||
TunnelTest();
|
TunnelTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Config Config(ApiControllerParamsInfo param)
|
public Dictionary<string, TunnelConnectInfo> Connections(ApiControllerParamsInfo param)
|
||||||
{
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
public void ConfigSet(ApiControllerParamsInfo param)
|
|
||||||
{
|
|
||||||
ConfigSetInfo info = param.Content.DeJson<ConfigSetInfo>();
|
|
||||||
config.Data.Client.Name = info.Name;
|
|
||||||
config.Data.Client.GroupId = info.GroupId;
|
|
||||||
config.Data.Client.Server = info.Server;
|
|
||||||
config.Save();
|
|
||||||
clientSignInTransfer.SignOut();
|
|
||||||
_ = clientSignInTransfer.SignIn();
|
|
||||||
}
|
|
||||||
public void ConfigSetServers(ApiControllerParamsInfo param)
|
|
||||||
{
|
|
||||||
config.Data.Client.Servers = param.Content.DeJson<ClientServerInfo[]>();
|
|
||||||
config.Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClientSignInState SignInInfo(ApiControllerParamsInfo param)
|
|
||||||
{
|
|
||||||
return clientSignInState;
|
|
||||||
}
|
|
||||||
public async Task SignInDel(ApiControllerParamsInfo param)
|
|
||||||
{
|
|
||||||
await messengerSender.SendOnly(new MessageRequestWrap
|
|
||||||
{
|
|
||||||
Connection = clientSignInState.Connection,
|
|
||||||
MessengerId = (ushort)SignInMessengerIds.Delete,
|
|
||||||
Payload = MemoryPackSerializer.Serialize(param.Content)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
public async Task<SignInListResponseInfo> SignInList(ApiControllerParamsInfo param)
|
|
||||||
{
|
|
||||||
SignInListRequestInfo request = param.Content.DeJson<SignInListRequestInfo>();
|
|
||||||
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
|
||||||
{
|
|
||||||
Connection = clientSignInState.Connection,
|
|
||||||
MessengerId = (ushort)SignInMessengerIds.List,
|
|
||||||
Payload = MemoryPackSerializer.Serialize(request)
|
|
||||||
});
|
|
||||||
if (resp.Code == MessageResponeCodes.OK)
|
|
||||||
{
|
|
||||||
return MemoryPackSerializer.Deserialize<SignInListResponseInfo>(resp.Data.Span);
|
|
||||||
}
|
|
||||||
return new SignInListResponseInfo { };
|
|
||||||
}
|
|
||||||
|
|
||||||
public Dictionary<string, TunnelConnectInfo> TunnelConnections(ApiControllerParamsInfo param)
|
|
||||||
{
|
{
|
||||||
return tunnelTransfer.Connections;
|
return tunnelTransfer.Connections;
|
||||||
}
|
}
|
||||||
public void TunnelConnect(ApiControllerParamsInfo param)
|
public void Connect(ApiControllerParamsInfo param)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
@@ -129,10 +72,4 @@ namespace cmonitor.plugins.tunnel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ConfigSetInfo
|
|
||||||
{
|
|
||||||
public string Name { get; set; }
|
|
||||||
public string GroupId { get; set; }
|
|
||||||
public string Server { get; set; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,11 +34,18 @@ namespace cmonitor.plugins.tunnel
|
|||||||
Logger.Instance.Info($"tunnel route level getting.");
|
Logger.Instance.Info($"tunnel route level getting.");
|
||||||
config.Data.Client.Tunnel.RouteLevel = NetworkHelper.GetRouteLevel(out List<IPAddress> ips);
|
config.Data.Client.Tunnel.RouteLevel = NetworkHelper.GetRouteLevel(out List<IPAddress> ips);
|
||||||
Logger.Instance.Info($"tunnel route level:{config.Data.Client.Tunnel.RouteLevel}");
|
Logger.Instance.Info($"tunnel route level:{config.Data.Client.Tunnel.RouteLevel}");
|
||||||
|
|
||||||
|
if (config.Data.Client.Tunnel.Servers.Length == 0)
|
||||||
|
{
|
||||||
|
config.Data.Client.Tunnel.Servers = new TunnelCompactInfo[]
|
||||||
|
{
|
||||||
|
new TunnelCompactInfo{ Name="self", Disabled = false, Host = config.Data.Client.Server }
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
public void AddServer(ServiceCollection serviceCollection, Config config, Assembly[] assemblies)
|
||||||
{
|
{
|
||||||
serviceCollection.AddSingleton<TunnelExternalIPServer>();
|
|
||||||
serviceCollection.AddSingleton<TunnelServerMessenger>();
|
serviceCollection.AddSingleton<TunnelServerMessenger>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,10 +60,7 @@ namespace cmonitor.plugins.tunnel
|
|||||||
|
|
||||||
public void UseServer(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
public void UseServer(ServiceProvider serviceProvider, Config config, Assembly[] assemblies)
|
||||||
{
|
{
|
||||||
Logger.Instance.Info($"use tunnel external ip server in server mode.");
|
|
||||||
TunnelExternalIPServer tunnelServer = serviceProvider.GetService<TunnelExternalIPServer>();
|
|
||||||
tunnelServer.Start(config.Data.Server.Tunnel.ListenPort);
|
|
||||||
Logger.Instance.Info($"start tunnel external ip server, port : {config.Data.Server.Tunnel.ListenPort}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ namespace cmonitor.plugins.tunnel
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TunnelTransportInfo tunnelTransportInfo = new TunnelTransportInfo
|
TunnelTransportInfo tunnelTransportInfo = new TunnelTransportInfo
|
||||||
{
|
{
|
||||||
Direction = TunnelTransportDirection.Forward,
|
Direction = TunnelTransportDirection.Forward,
|
||||||
@@ -80,7 +79,6 @@ namespace cmonitor.plugins.tunnel
|
|||||||
Local = localInfo,
|
Local = localInfo,
|
||||||
Remote = remoteInfo,
|
Remote = remoteInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
TunnelTransportState state = await transport.ConnectAsync(tunnelTransportInfo);
|
TunnelTransportState state = await transport.ConnectAsync(tunnelTransportInfo);
|
||||||
if (state != null)
|
if (state != null)
|
||||||
{
|
{
|
||||||
@@ -148,18 +146,19 @@ namespace cmonitor.plugins.tunnel
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnSendConnectBegin(TunnelTransportInfo tunnelTransportInfo)
|
private async Task<bool> OnSendConnectBegin(TunnelTransportInfo tunnelTransportInfo)
|
||||||
{
|
{
|
||||||
await messengerSender.SendReply(new MessageRequestWrap
|
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap
|
||||||
{
|
{
|
||||||
Connection = clientSignInState.Connection,
|
Connection = clientSignInState.Connection,
|
||||||
MessengerId = (ushort)TunnelMessengerIds.BeginForward,
|
MessengerId = (ushort)TunnelMessengerIds.BeginForward,
|
||||||
Payload = MemoryPackSerializer.Serialize(tunnelTransportInfo)
|
Payload = MemoryPackSerializer.Serialize(tunnelTransportInfo)
|
||||||
});
|
});
|
||||||
|
return resp.Code == MessageResponeCodes.OK && resp.Data.Span.SequenceEqual(Helper.TrueArray);
|
||||||
}
|
}
|
||||||
private async Task OnSendConnectFail(TunnelTransportInfo tunnelTransportInfo)
|
private async Task OnSendConnectFail(TunnelTransportInfo tunnelTransportInfo)
|
||||||
{
|
{
|
||||||
await messengerSender.SendReply(new MessageRequestWrap
|
await messengerSender.SendOnly(new MessageRequestWrap
|
||||||
{
|
{
|
||||||
Connection = clientSignInState.Connection,
|
Connection = clientSignInState.Connection,
|
||||||
MessengerId = (ushort)TunnelMessengerIds.FailForward,
|
MessengerId = (ushort)TunnelMessengerIds.FailForward,
|
||||||
@@ -185,9 +184,9 @@ namespace cmonitor.plugins.tunnel
|
|||||||
{
|
{
|
||||||
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
if (Logger.Instance.LoggerLevel <= LoggerTypes.DEBUG)
|
||||||
{
|
{
|
||||||
Logger.Instance.Debug($"tunnel connect from {tunnelTransportInfo.Local.MachineName}->{tunnelTransportInfo.ToJson()}");
|
Logger.Instance.Debug($"tunnel connect from {tunnelTransportInfo.Remote.MachineName}->{tunnelTransportInfo.ToJson()}");
|
||||||
}
|
}
|
||||||
CheckDic(tunnelTransportInfo.Local.MachineName, out TunnelConnectInfo info);
|
CheckDic(tunnelTransportInfo.Remote.MachineName, out TunnelConnectInfo info);
|
||||||
info.Status = TunnelConnectStatus.Connecting;
|
info.Status = TunnelConnectStatus.Connecting;
|
||||||
Interlocked.Exchange(ref connectionsChangeFlag, 1);
|
Interlocked.Exchange(ref connectionsChangeFlag, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using cmonitor.plugins.tunnel.server;
|
using cmonitor.plugins.tunnel.messenger;
|
||||||
|
using cmonitor.plugins.tunnel.server;
|
||||||
|
using cmonitor.server;
|
||||||
using common.libs.extends;
|
using common.libs.extends;
|
||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
@@ -8,7 +10,16 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
{
|
{
|
||||||
public sealed class CompactSelfHost : ICompact
|
public sealed class CompactSelfHost : ICompact
|
||||||
{
|
{
|
||||||
public string Type => "self";
|
public string Name => "self";
|
||||||
|
|
||||||
|
private readonly TcpServer tcpServer;
|
||||||
|
private readonly MessengerSender messengerSender;
|
||||||
|
|
||||||
|
public CompactSelfHost(TcpServer tcpServer, MessengerSender messengerSender)
|
||||||
|
{
|
||||||
|
this.tcpServer = tcpServer;
|
||||||
|
this.messengerSender = messengerSender;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<TunnelCompactIPEndPoint> GetTcpExternalIPAsync(IPEndPoint server)
|
public async Task<TunnelCompactIPEndPoint> GetTcpExternalIPAsync(IPEndPoint server)
|
||||||
{
|
{
|
||||||
@@ -17,23 +28,22 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
socket.IPv6Only(server.AddressFamily, false);
|
socket.IPv6Only(server.AddressFamily, false);
|
||||||
await socket.ConnectAsync(server).WaitAsync(TimeSpan.FromSeconds(5));
|
await socket.ConnectAsync(server).WaitAsync(TimeSpan.FromSeconds(5));
|
||||||
|
|
||||||
byte[] bytes = new byte[128];
|
IConnection connection = tcpServer.BindReceive(socket);
|
||||||
int length = await socket.ReceiveAsync(bytes.AsMemory(), SocketFlags.None);
|
MessageResponeInfo resp = await messengerSender.SendReply(new MessageRequestWrap { Connection = connection, MessengerId = (ushort)TunnelMessengerIds.ExternalIP });
|
||||||
if (length == 0)
|
|
||||||
{
|
if (resp.Code != MessageResponeCodes.OK) return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPEndPoint local = socket.LocalEndPoint as IPEndPoint;
|
IPEndPoint local = socket.LocalEndPoint as IPEndPoint;
|
||||||
socket.SafeClose();
|
connection.Disponse();
|
||||||
TunnelExternalIPInfo tunnelExternalIPInfo = MemoryPackSerializer.Deserialize<TunnelExternalIPInfo>(bytes.AsSpan(0,length));
|
TunnelExternalIPInfo tunnelExternalIPInfo = MemoryPackSerializer.Deserialize<TunnelExternalIPInfo>(resp.Data.Span);
|
||||||
|
|
||||||
return new TunnelCompactIPEndPoint { Local = local, Remote = tunnelExternalIPInfo.ExternalIP };
|
return new TunnelCompactIPEndPoint { Local = local, Remote = tunnelExternalIPInfo.ExternalIP };
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TunnelCompactIPEndPoint> GetUdpExternalIPAsync(IPEndPoint server)
|
public async Task<TunnelCompactIPEndPoint> GetUdpExternalIPAsync(IPEndPoint server)
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
|
/*
|
||||||
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);
|
||||||
@@ -46,6 +56,7 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
TunnelExternalIPInfo tunnelExternalIPInfo = MemoryPackSerializer.Deserialize<TunnelExternalIPInfo>(result.Buffer);
|
TunnelExternalIPInfo tunnelExternalIPInfo = MemoryPackSerializer.Deserialize<TunnelExternalIPInfo>(result.Buffer);
|
||||||
|
|
||||||
return new TunnelCompactIPEndPoint { Local = udpClient.Client.LocalEndPoint as IPEndPoint, Remote = tunnelExternalIPInfo.ExternalIP };
|
return new TunnelCompactIPEndPoint { Local = udpClient.Client.LocalEndPoint as IPEndPoint, Remote = tunnelExternalIPInfo.ExternalIP };
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
{
|
{
|
||||||
IEnumerable<Type> types = ReflectionHelper.GetInterfaceSchieves(assembs, typeof(ICompact));
|
IEnumerable<Type> types = ReflectionHelper.GetInterfaceSchieves(assembs, typeof(ICompact));
|
||||||
types = config.Data.Common.PluginContains(types);
|
types = config.Data.Common.PluginContains(types);
|
||||||
compacts = types.Select(c => (ICompact)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Type) == false).ToList();
|
compacts = types.Select(c => (ICompact)serviceProvider.GetService(c)).Where(c => c != null).Where(c => string.IsNullOrWhiteSpace(c.Name) == false).ToList();
|
||||||
|
|
||||||
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.Name))}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<TunnelCompactIPEndPoint[]> GetExternalIPAsync(ProtocolType protocolType)
|
public async Task<TunnelCompactIPEndPoint[]> GetExternalIPAsync(ProtocolType protocolType)
|
||||||
@@ -36,7 +36,7 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
{
|
{
|
||||||
TunnelCompactInfo item = config.Data.Client.Tunnel.Servers[i];
|
TunnelCompactInfo item = config.Data.Client.Tunnel.Servers[i];
|
||||||
if (item.Disabled) continue;
|
if (item.Disabled) continue;
|
||||||
ICompact compact = compacts.FirstOrDefault(c => c.Type == item.Type);
|
ICompact compact = compacts.FirstOrDefault(c => c.Name == item.Name);
|
||||||
if (compact == null) continue;
|
if (compact == null) continue;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ namespace cmonitor.plugins.tunnel.compact
|
|||||||
{
|
{
|
||||||
public interface ICompact
|
public interface ICompact
|
||||||
{
|
{
|
||||||
public string Type { get; }
|
public string Name { get; }
|
||||||
public Task<TunnelCompactIPEndPoint> GetTcpExternalIPAsync(IPEndPoint server);
|
public Task<TunnelCompactIPEndPoint> GetTcpExternalIPAsync(IPEndPoint server);
|
||||||
public Task<TunnelCompactIPEndPoint> GetUdpExternalIPAsync(IPEndPoint server);
|
public Task<TunnelCompactIPEndPoint> GetUdpExternalIPAsync(IPEndPoint server);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,7 @@ namespace cmonitor.config
|
|||||||
|
|
||||||
public sealed class TunnelConfigClientInfo
|
public sealed class TunnelConfigClientInfo
|
||||||
{
|
{
|
||||||
public TunnelCompactInfo[] Servers { get; set; } = new TunnelCompactInfo[]
|
public TunnelCompactInfo[] Servers { get; set; } = Array.Empty<TunnelCompactInfo>();
|
||||||
{
|
|
||||||
new TunnelCompactInfo { Type="self", Host="127.0.0.1:1804" }
|
|
||||||
};
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int RouteLevel { get; set; }
|
public int RouteLevel { get; set; }
|
||||||
@@ -24,12 +21,11 @@ namespace cmonitor.config
|
|||||||
|
|
||||||
public sealed class TunnelConfigServerInfo
|
public sealed class TunnelConfigServerInfo
|
||||||
{
|
{
|
||||||
public int ListenPort { get; set; } = 1804;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class TunnelCompactInfo
|
public sealed class TunnelCompactInfo
|
||||||
{
|
{
|
||||||
public string Type { get; set; }
|
public string Name { get; set; }
|
||||||
public string Host { get; set; }
|
public string Host { get; set; }
|
||||||
public bool Disabled { get; set; }
|
public bool Disabled { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
using cmonitor.plugins.tunnel.transport;
|
using cmonitor.plugins.tunnel.transport;
|
||||||
using cmonitor.server;
|
using cmonitor.server;
|
||||||
using common.libs;
|
using common.libs;
|
||||||
|
using common.libs.extends;
|
||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace cmonitor.plugins.tunnel.messenger
|
namespace cmonitor.plugins.tunnel.messenger
|
||||||
{
|
{
|
||||||
@@ -50,7 +52,6 @@ namespace cmonitor.plugins.tunnel.messenger
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public sealed class TunnelServerMessenger : IMessenger
|
public sealed class TunnelServerMessenger : IMessenger
|
||||||
{
|
{
|
||||||
private readonly MessengerSender messengerSender;
|
private readonly MessengerSender messengerSender;
|
||||||
@@ -90,7 +91,7 @@ namespace cmonitor.plugins.tunnel.messenger
|
|||||||
MessengerId = (ushort)TunnelMessengerIds.Info,
|
MessengerId = (ushort)TunnelMessengerIds.Info,
|
||||||
Payload = connection.ReceiveRequestWrap.Payload
|
Payload = connection.ReceiveRequestWrap.Payload
|
||||||
});
|
});
|
||||||
if (resp.Code == MessageResponeCodes.OK)
|
if (resp.Code == MessageResponeCodes.OK && resp.Data.Span.Length > 0)
|
||||||
{
|
{
|
||||||
connection.Write(MemoryPackSerializer.Serialize(MemoryPackSerializer.Deserialize<TunnelTransportExternalIPInfo>(resp.Data.Span)));
|
connection.Write(MemoryPackSerializer.Serialize(MemoryPackSerializer.Deserialize<TunnelTransportExternalIPInfo>(resp.Data.Span)));
|
||||||
}
|
}
|
||||||
@@ -111,5 +112,18 @@ namespace cmonitor.plugins.tunnel.messenger
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MessengerId((ushort)TunnelMessengerIds.ExternalIP)]
|
||||||
|
public void ExternalIP(IConnection connection)
|
||||||
|
{
|
||||||
|
connection.Write(MemoryPackSerializer.Serialize(new TunnelExternalIPInfo { ExternalIP = connection.Address }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[MemoryPackable]
|
||||||
|
public sealed partial class TunnelExternalIPInfo
|
||||||
|
{
|
||||||
|
[MemoryPackAllowSerialize]
|
||||||
|
public IPEndPoint ExternalIP { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
Fail = 2005,
|
Fail = 2005,
|
||||||
FailForward = 2006,
|
FailForward = 2006,
|
||||||
|
|
||||||
|
|
||||||
|
ExternalIP = 2007,
|
||||||
|
|
||||||
None = 2099
|
None = 2099
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,161 +0,0 @@
|
|||||||
using common.libs;
|
|
||||||
using common.libs.extends;
|
|
||||||
using MemoryPack;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
|
|
||||||
namespace cmonitor.plugins.tunnel.server
|
|
||||||
{
|
|
||||||
public sealed class TunnelExternalIPServer
|
|
||||||
{
|
|
||||||
private SocketAsyncEventArgs acceptEventArg;
|
|
||||||
private Socket socket;
|
|
||||||
private UdpClient socketUdp;
|
|
||||||
|
|
||||||
public void Start(int port)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Stop();
|
|
||||||
|
|
||||||
IPEndPoint localEndPoint = new IPEndPoint(NetworkHelper.IPv6Support ? IPAddress.IPv6Any : IPAddress.Any, port);
|
|
||||||
socket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
|
||||||
socket.IPv6Only(localEndPoint.AddressFamily, false);
|
|
||||||
socket.ReuseBind(localEndPoint);
|
|
||||||
socket.Listen(int.MaxValue);
|
|
||||||
|
|
||||||
acceptEventArg = new SocketAsyncEventArgs
|
|
||||||
{
|
|
||||||
UserToken = new AsyncUserToken
|
|
||||||
{
|
|
||||||
SourceSocket = socket
|
|
||||||
},
|
|
||||||
SocketFlags = SocketFlags.None,
|
|
||||||
};
|
|
||||||
|
|
||||||
acceptEventArg.Completed += IO_Completed;
|
|
||||||
StartAccept(acceptEventArg);
|
|
||||||
|
|
||||||
|
|
||||||
socketUdp = new UdpClient(new IPEndPoint(IPAddress.Any, port));
|
|
||||||
socketUdp.Client.EnableBroadcast = true;
|
|
||||||
socketUdp.Client.WindowsUdpBug();
|
|
||||||
IAsyncResult result = socketUdp.BeginReceive(ReceiveCallbackUdp, null);
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
SocketAsyncEventArgs receiveEventArg = new SocketAsyncEventArgs
|
|
||||||
{
|
|
||||||
UserToken = new AsyncUserToken
|
|
||||||
{
|
|
||||||
SourceSocket = e.AcceptSocket
|
|
||||||
},
|
|
||||||
SocketFlags = SocketFlags.None,
|
|
||||||
};
|
|
||||||
|
|
||||||
WriteExternalIP(receiveEventArg);
|
|
||||||
StartAccept(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private async void WriteExternalIP(SocketAsyncEventArgs e)
|
|
||||||
{
|
|
||||||
AsyncUserToken token = e.UserToken as AsyncUserToken;
|
|
||||||
if (token.SourceSocket != null)
|
|
||||||
{
|
|
||||||
IPEndPoint ep = token.SourceSocket.RemoteEndPoint as IPEndPoint;
|
|
||||||
Memory<byte> memory = MemoryPackSerializer.Serialize(new TunnelExternalIPInfo { ExternalIP = ep });
|
|
||||||
|
|
||||||
await token.SourceSocket.SendAsync(memory);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async void ReceiveCallbackUdp(IAsyncResult result)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IPEndPoint ep = new IPEndPoint(IPAddress.Any, IPEndPoint.MinPort);
|
|
||||||
byte[] _ = socketUdp.EndReceive(result, ref ep);
|
|
||||||
|
|
||||||
Memory<byte> memory = MemoryPackSerializer.Serialize(new TunnelExternalIPInfo { ExternalIP = ep });
|
|
||||||
|
|
||||||
await socketUdp.SendAsync(memory, ep);
|
|
||||||
|
|
||||||
result = socketUdp.BeginReceive(ReceiveCallbackUdp, null);
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CloseClientSocket(SocketAsyncEventArgs e)
|
|
||||||
{
|
|
||||||
if (e == null) return;
|
|
||||||
AsyncUserToken token = e.UserToken as AsyncUserToken;
|
|
||||||
if (token.SourceSocket != null)
|
|
||||||
{
|
|
||||||
token.Clear();
|
|
||||||
e.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void Stop()
|
|
||||||
{
|
|
||||||
CloseClientSocket(acceptEventArg);
|
|
||||||
socketUdp?.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed class AsyncUserToken
|
|
||||||
{
|
|
||||||
public Socket SourceSocket { get; set; }
|
|
||||||
|
|
||||||
public void Clear()
|
|
||||||
{
|
|
||||||
SourceSocket?.SafeClose();
|
|
||||||
SourceSocket = null;
|
|
||||||
|
|
||||||
GC.Collect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[MemoryPackable]
|
|
||||||
public sealed partial class TunnelExternalIPInfo
|
|
||||||
{
|
|
||||||
[MemoryPackAllowSerialize]
|
|
||||||
public IPEndPoint ExternalIP { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,7 +13,7 @@ namespace cmonitor.plugins.tunnel.transport
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发送连接信息
|
/// 发送连接信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Func<TunnelTransportInfo, Task> OnSendConnectBegin { get; set; }
|
public Func<TunnelTransportInfo, Task<bool>> OnSendConnectBegin { get; set; }
|
||||||
public Func<TunnelTransportInfo, Task> OnSendConnectFail { get; set; }
|
public Func<TunnelTransportInfo, Task> OnSendConnectFail { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 收到连接信息
|
/// 收到连接信息
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace cmonitor.plugins.tunnel.transport
|
|||||||
public string Name => "TcpNutssb";
|
public string Name => "TcpNutssb";
|
||||||
public ProtocolType Type => ProtocolType.Tcp;
|
public ProtocolType Type => ProtocolType.Tcp;
|
||||||
|
|
||||||
public Func<TunnelTransportInfo, Task> OnSendConnectBegin { get; set; } = async (info) => { await Task.CompletedTask; };
|
public Func<TunnelTransportInfo, Task<bool>> OnSendConnectBegin { get; set; } = async (info) => { return await Task.FromResult<bool>(false); };
|
||||||
public Func<TunnelTransportInfo, Task> OnSendConnectFail { get; set; } = async (info) => { await Task.CompletedTask; };
|
public Func<TunnelTransportInfo, Task> OnSendConnectFail { get; set; } = async (info) => { await Task.CompletedTask; };
|
||||||
public Action<TunnelTransportInfo> OnConnectBegin { get; set; } = (info) => { };
|
public Action<TunnelTransportInfo> OnConnectBegin { get; set; } = (info) => { };
|
||||||
public Action<TunnelTransportInfo> OnConnecting { get; set; }
|
public Action<TunnelTransportInfo> OnConnecting { get; set; }
|
||||||
@@ -22,7 +22,6 @@ namespace cmonitor.plugins.tunnel.transport
|
|||||||
|
|
||||||
|
|
||||||
private readonly TunnelBindServer tunnelBindServer;
|
private readonly TunnelBindServer tunnelBindServer;
|
||||||
|
|
||||||
public TransportTcpNutssb(TunnelBindServer tunnelBindServer)
|
public TransportTcpNutssb(TunnelBindServer tunnelBindServer)
|
||||||
{
|
{
|
||||||
this.tunnelBindServer = tunnelBindServer;
|
this.tunnelBindServer = tunnelBindServer;
|
||||||
@@ -34,26 +33,30 @@ namespace cmonitor.plugins.tunnel.transport
|
|||||||
{
|
{
|
||||||
OnConnecting(tunnelTransportInfo);
|
OnConnecting(tunnelTransportInfo);
|
||||||
|
|
||||||
|
//正向连接
|
||||||
tunnelTransportInfo.Direction = TunnelTransportDirection.Forward;
|
tunnelTransportInfo.Direction = TunnelTransportDirection.Forward;
|
||||||
await OnSendConnectBegin(tunnelTransportInfo);
|
if (await OnSendConnectBegin(tunnelTransportInfo) == false)
|
||||||
TunnelTransportState state = await ConnectForward(tunnelTransportInfo);
|
|
||||||
if (state != null)
|
|
||||||
{
|
{
|
||||||
return state;
|
OnConnectFail(tunnelTransportInfo.Remote.MachineName);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
TunnelTransportState state = await ConnectForward(tunnelTransportInfo);
|
||||||
|
if (state != null) return state;
|
||||||
|
|
||||||
|
//反向连接
|
||||||
TunnelTransportInfo tunnelTransportInfo1 = tunnelTransportInfo.ToJsonFormat().DeJson<TunnelTransportInfo>();
|
TunnelTransportInfo tunnelTransportInfo1 = tunnelTransportInfo.ToJsonFormat().DeJson<TunnelTransportInfo>();
|
||||||
tunnelTransportInfo1.Direction = TunnelTransportDirection.Reverse;
|
tunnelTransportInfo1.Direction = TunnelTransportDirection.Reverse;
|
||||||
tunnelBindServer.Bind(tunnelTransportInfo1.Local.Local, tunnelTransportInfo1);
|
tunnelBindServer.Bind(tunnelTransportInfo1.Local.Local, tunnelTransportInfo1);
|
||||||
BindAndTTL(tunnelTransportInfo1);
|
BindAndTTL(tunnelTransportInfo1);
|
||||||
await OnSendConnectBegin(tunnelTransportInfo1);
|
if (await OnSendConnectBegin(tunnelTransportInfo1) == false)
|
||||||
|
|
||||||
state = await WaitReverse(tunnelTransportInfo1);
|
|
||||||
if (state != null)
|
|
||||||
{
|
{
|
||||||
return state;
|
OnConnectFail(tunnelTransportInfo.Remote.MachineName);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
state = await WaitReverse(tunnelTransportInfo1);
|
||||||
|
if (state != null) return state;
|
||||||
|
|
||||||
|
//正向反向都失败
|
||||||
await OnSendConnectFail(tunnelTransportInfo);
|
await OnSendConnectFail(tunnelTransportInfo);
|
||||||
OnConnectFail(tunnelTransportInfo.Remote.MachineName);
|
OnConnectFail(tunnelTransportInfo.Remote.MachineName);
|
||||||
return null;
|
return null;
|
||||||
@@ -109,10 +112,10 @@ namespace cmonitor.plugins.tunnel.transport
|
|||||||
Socket targetSocket = new(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
Socket targetSocket = new(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
|
||||||
targetSocket.IPv6Only(ep.Address.AddressFamily, false);
|
targetSocket.IPv6Only(ep.Address.AddressFamily, false);
|
||||||
targetSocket.ReuseBind(new IPEndPoint(ep.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, tunnelTransportInfo.Local.Local.Port));
|
targetSocket.ReuseBind(new IPEndPoint(ep.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any, tunnelTransportInfo.Local.Local.Port));
|
||||||
|
|
||||||
IAsyncResult result = targetSocket.BeginConnect(ep, null, null);
|
IAsyncResult result = targetSocket.BeginConnect(ep, null, null);
|
||||||
|
|
||||||
for (int i = 0; i < 25; i++)
|
int times = ep.Address.Equals(tunnelTransportInfo.Remote.Remote.Address) ? 25 : 5;
|
||||||
|
for (int i = 0; i < times; i++)
|
||||||
{
|
{
|
||||||
if (result.IsCompleted)
|
if (result.IsCompleted)
|
||||||
{
|
{
|
||||||
@@ -120,6 +123,7 @@ namespace cmonitor.plugins.tunnel.transport
|
|||||||
}
|
}
|
||||||
await Task.Delay(20);
|
await Task.Delay(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (result.IsCompleted == false)
|
if (result.IsCompleted == false)
|
||||||
@@ -190,12 +194,20 @@ namespace cmonitor.plugins.tunnel.transport
|
|||||||
TaskCompletionSource<TunnelTransportState> tcs = new TaskCompletionSource<TunnelTransportState>();
|
TaskCompletionSource<TunnelTransportState> tcs = new TaskCompletionSource<TunnelTransportState>();
|
||||||
reverseDic.TryAdd(tunnelTransportInfo.Remote.MachineName, tcs);
|
reverseDic.TryAdd(tunnelTransportInfo.Remote.MachineName, tcs);
|
||||||
|
|
||||||
TunnelTransportState state = await tcs.Task.WaitAsync(TimeSpan.FromSeconds(3));
|
try
|
||||||
|
{
|
||||||
reverseDic.TryRemove(tunnelTransportInfo.Remote.MachineName, out _);
|
TunnelTransportState state = await tcs.Task.WaitAsync(TimeSpan.FromMilliseconds(3000));
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
reverseDic.TryRemove(tunnelTransportInfo.Remote.MachineName, out _);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void OnTcpConnected(object state, Socket socket)
|
private void OnTcpConnected(object state, Socket socket)
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ namespace cmonitor.server
|
|||||||
public IPEndPoint Address { get; }
|
public IPEndPoint Address { get; }
|
||||||
public IPEndPoint LocalAddress { get; }
|
public IPEndPoint LocalAddress { get; }
|
||||||
|
|
||||||
|
public Socket TcpSourceSocket { get; }
|
||||||
|
public Socket TcpTargetSocket { get; set; }
|
||||||
|
|
||||||
#region 接收数据
|
#region 接收数据
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 请求数据包装对象
|
/// 请求数据包装对象
|
||||||
@@ -41,14 +44,14 @@ namespace cmonitor.server
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task<bool> Send(ReadOnlyMemory<byte> data, bool unconnectedMessage = false);
|
public Task<bool> Send(ReadOnlyMemory<byte> data);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发送
|
/// 发送
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <param name="length"></param>
|
/// <param name="length"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public Task<bool> Send(byte[] data, int length, bool unconnectedMessage = false);
|
public Task<bool> Send(byte[] data, int length);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 销毁
|
/// 销毁
|
||||||
@@ -97,6 +100,9 @@ namespace cmonitor.server
|
|||||||
public IPEndPoint Address { get; protected set; }
|
public IPEndPoint Address { get; protected set; }
|
||||||
public IPEndPoint LocalAddress { get; protected set; }
|
public IPEndPoint LocalAddress { get; protected set; }
|
||||||
|
|
||||||
|
public Socket TcpSourceSocket { get; protected set; }
|
||||||
|
public Socket TcpTargetSocket { get; set; }
|
||||||
|
public bool Relayed { get; set; }
|
||||||
|
|
||||||
#region 接收数据
|
#region 接收数据
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -194,14 +200,14 @@ namespace cmonitor.server
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public abstract Task<bool> Send(ReadOnlyMemory<byte> data, bool logger = false);
|
public abstract Task<bool> Send(ReadOnlyMemory<byte> data);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发送
|
/// 发送
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <param name="length"></param>
|
/// <param name="length"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public abstract Task<bool> Send(byte[] data, int length, bool logger = false);
|
public abstract Task<bool> Send(byte[] data, int length);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 销毁
|
/// 销毁
|
||||||
@@ -218,16 +224,16 @@ namespace cmonitor.server
|
|||||||
{
|
{
|
||||||
public TcpConnection(Socket tcpSocket) : base()
|
public TcpConnection(Socket tcpSocket) : base()
|
||||||
{
|
{
|
||||||
TcpSocket = tcpSocket;
|
TcpSourceSocket = tcpSocket;
|
||||||
|
|
||||||
IPEndPoint address = TcpSocket.RemoteEndPoint as IPEndPoint ?? new IPEndPoint(IPAddress.Any, 0);
|
IPEndPoint address = TcpSourceSocket.RemoteEndPoint as IPEndPoint ?? new IPEndPoint(IPAddress.Any, 0);
|
||||||
if (address.Address.AddressFamily == AddressFamily.InterNetworkV6 && address.Address.IsIPv4MappedToIPv6)
|
if (address.Address.AddressFamily == AddressFamily.InterNetworkV6 && address.Address.IsIPv4MappedToIPv6)
|
||||||
{
|
{
|
||||||
address = new IPEndPoint(new IPAddress(address.Address.GetAddressBytes()[^4..]), address.Port);
|
address = new IPEndPoint(new IPAddress(address.Address.GetAddressBytes()[^4..]), address.Port);
|
||||||
}
|
}
|
||||||
Address = address;
|
Address = address;
|
||||||
|
|
||||||
IPEndPoint localaddress = TcpSocket.LocalEndPoint as IPEndPoint ?? new IPEndPoint(IPAddress.Any, 0);
|
IPEndPoint localaddress = TcpSourceSocket.LocalEndPoint as IPEndPoint ?? new IPEndPoint(IPAddress.Any, 0);
|
||||||
if (localaddress.Address.AddressFamily == AddressFamily.InterNetworkV6 && localaddress.Address.IsIPv4MappedToIPv6)
|
if (localaddress.Address.AddressFamily == AddressFamily.InterNetworkV6 && localaddress.Address.IsIPv4MappedToIPv6)
|
||||||
{
|
{
|
||||||
localaddress = new IPEndPoint(new IPAddress(localaddress.Address.GetAddressBytes()[^4..]), localaddress.Port);
|
localaddress = new IPEndPoint(new IPAddress(localaddress.Address.GetAddressBytes()[^4..]), localaddress.Port);
|
||||||
@@ -238,24 +244,20 @@ namespace cmonitor.server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 已连接
|
/// 已连接
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override bool Connected => TcpSocket != null && TcpSocket.Connected;
|
public override bool Connected => TcpSourceSocket != null && TcpSourceSocket.Connected;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// socket
|
|
||||||
/// </summary>
|
|
||||||
public Socket TcpSocket { get; private set; }
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 发送
|
/// 发送
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override async Task<bool> Send(ReadOnlyMemory<byte> data, bool unconnectedMessage = false)
|
public override async Task<bool> Send(ReadOnlyMemory<byte> data)
|
||||||
{
|
{
|
||||||
if (Connected)
|
if (Connected)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await TcpSocket.SendAsync(data, SocketFlags.None);
|
await TcpSourceSocket.SendAsync(data, SocketFlags.None);
|
||||||
//SentBytes += (ulong)data.Length;
|
//SentBytes += (ulong)data.Length;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -274,9 +276,9 @@ namespace cmonitor.server
|
|||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
/// <param name="length"></param>
|
/// <param name="length"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override async Task<bool> Send(byte[] data, int length, bool unconnectedMessage = false)
|
public override async Task<bool> Send(byte[] data, int length)
|
||||||
{
|
{
|
||||||
return await Send(data.AsMemory(0, length), unconnectedMessage);
|
return await Send(data.AsMemory(0, length));
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 销毁
|
/// 销毁
|
||||||
@@ -284,10 +286,13 @@ namespace cmonitor.server
|
|||||||
public override void Disponse()
|
public override void Disponse()
|
||||||
{
|
{
|
||||||
base.Disponse();
|
base.Disponse();
|
||||||
if (TcpSocket != null)
|
if (TcpSourceSocket != null)
|
||||||
{
|
{
|
||||||
TcpSocket.SafeClose();
|
TcpSourceSocket.SafeClose();
|
||||||
TcpSocket.Dispose();
|
TcpSourceSocket.Dispose();
|
||||||
|
|
||||||
|
TcpTargetSocket?.SafeClose();
|
||||||
|
TcpTargetSocket?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using cmonitor.config;
|
using cmonitor.config;
|
||||||
using common.libs;
|
using common.libs;
|
||||||
using common.libs.extends;
|
using common.libs.extends;
|
||||||
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace cmonitor.server
|
namespace cmonitor.server
|
||||||
{
|
{
|
||||||
@@ -12,6 +14,8 @@ namespace cmonitor.server
|
|||||||
private Socket socket;
|
private Socket socket;
|
||||||
private UdpClient socketUdp;
|
private UdpClient socketUdp;
|
||||||
private CancellationTokenSource cancellationTokenSource;
|
private CancellationTokenSource cancellationTokenSource;
|
||||||
|
private Memory<byte> relayFLagData = Encoding.UTF8.GetBytes("snltty.relay");
|
||||||
|
|
||||||
public Func<IConnection, Task> OnPacket { get; set; } = async (connection) => { await Task.CompletedTask; };
|
public Func<IConnection, Task> OnPacket { get; set; } = async (connection) => { await Task.CompletedTask; };
|
||||||
public Action<int> OnDisconnected { get; set; }
|
public Action<int> OnDisconnected { get; set; }
|
||||||
|
|
||||||
@@ -148,17 +152,17 @@ namespace cmonitor.server
|
|||||||
Connection = CreateConnection(socket)
|
Connection = CreateConnection(socket)
|
||||||
};
|
};
|
||||||
|
|
||||||
SocketAsyncEventArgs readEventArgs = new SocketAsyncEventArgs
|
SocketAsyncEventArgs saea = new SocketAsyncEventArgs
|
||||||
{
|
{
|
||||||
UserToken = userToken,
|
UserToken = userToken,
|
||||||
SocketFlags = SocketFlags.None,
|
SocketFlags = SocketFlags.None,
|
||||||
};
|
};
|
||||||
userToken.PoolBuffer = new byte[bufferSize];
|
userToken.PoolBuffer = new byte[bufferSize];
|
||||||
readEventArgs.SetBuffer(userToken.PoolBuffer, 0, bufferSize);
|
saea.SetBuffer(userToken.PoolBuffer, 0, bufferSize);
|
||||||
readEventArgs.Completed += IO_Completed;
|
saea.Completed += IO_Completed;
|
||||||
if (socket.ReceiveAsync(readEventArgs) == false)
|
if (socket.ReceiveAsync(saea) == false)
|
||||||
{
|
{
|
||||||
ProcessReceive(readEventArgs);
|
ProcessReceive(saea);
|
||||||
}
|
}
|
||||||
return userToken.Connection;
|
return userToken.Connection;
|
||||||
}
|
}
|
||||||
@@ -179,7 +183,9 @@ namespace cmonitor.server
|
|||||||
{
|
{
|
||||||
int offset = e.Offset;
|
int offset = e.Offset;
|
||||||
int length = e.BytesTransferred;
|
int length = e.BytesTransferred;
|
||||||
await ReadPacket(token, e.Buffer, offset, length);
|
|
||||||
|
bool res = await ReadPacket(token, e.Buffer, offset, length);
|
||||||
|
if (res == false) return;
|
||||||
|
|
||||||
if (token.Socket.Available > 0)
|
if (token.Socket.Available > 0)
|
||||||
{
|
{
|
||||||
@@ -188,7 +194,8 @@ namespace cmonitor.server
|
|||||||
length = token.Socket.Receive(e.Buffer);
|
length = token.Socket.Receive(e.Buffer);
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
await ReadPacket(token, e.Buffer, 0, length);
|
res = await ReadPacket(token, e.Buffer, 0, length);
|
||||||
|
if (res == false) return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -203,7 +210,6 @@ namespace cmonitor.server
|
|||||||
CloseClientSocket(e);
|
CloseClientSocket(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (token.Socket.ReceiveAsync(e) == false)
|
if (token.Socket.ReceiveAsync(e) == false)
|
||||||
{
|
{
|
||||||
ProcessReceive(e);
|
ProcessReceive(e);
|
||||||
@@ -222,7 +228,23 @@ namespace cmonitor.server
|
|||||||
CloseClientSocket(e);
|
CloseClientSocket(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async Task ReadPacket(AsyncUserToken token, byte[] data, int offset, int length)
|
private async Task<bool> ReadPacket(AsyncUserToken token, byte[] data, int offset, int length)
|
||||||
|
{
|
||||||
|
if (token.Connection.TcpTargetSocket != null)
|
||||||
|
{
|
||||||
|
if (token.DataBuffer.Size > 0)
|
||||||
|
{
|
||||||
|
await token.Connection.TcpTargetSocket.SendAsync(token.DataBuffer.Data.Slice(0, token.DataBuffer.Size), SocketFlags.None);
|
||||||
|
token.DataBuffer.Clear();
|
||||||
|
}
|
||||||
|
await token.Connection.TcpTargetSocket.SendAsync(data.AsMemory(offset, length), SocketFlags.None);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (length == relayFLagData.Length && data.AsSpan(offset, length).SequenceEqual(relayFLagData.Span))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//是一个完整的包
|
//是一个完整的包
|
||||||
if (token.DataBuffer.Size == 0 && length > 4)
|
if (token.DataBuffer.Size == 0 && length > 4)
|
||||||
@@ -233,7 +255,7 @@ namespace cmonitor.server
|
|||||||
{
|
{
|
||||||
token.Connection.ReceiveData = data.AsMemory(offset, packageLen + 4);
|
token.Connection.ReceiveData = data.AsMemory(offset, packageLen + 4);
|
||||||
await OnPacket(token.Connection);
|
await OnPacket(token.Connection);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,6 +274,8 @@ namespace cmonitor.server
|
|||||||
token.DataBuffer.RemoveRange(0, packageLen + 4);
|
token.DataBuffer.RemoveRange(0, packageLen + 4);
|
||||||
} while (token.DataBuffer.Size > 4);
|
} while (token.DataBuffer.Size > 4);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void CloseClientSocket(SocketAsyncEventArgs e)
|
private void CloseClientSocket(SocketAsyncEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -294,11 +318,14 @@ namespace cmonitor.server
|
|||||||
public Socket Socket { get; set; }
|
public Socket Socket { get; set; }
|
||||||
public ReceiveDataBuffer DataBuffer { get; set; } = new ReceiveDataBuffer();
|
public ReceiveDataBuffer DataBuffer { get; set; } = new ReceiveDataBuffer();
|
||||||
public byte[] PoolBuffer { get; set; }
|
public byte[] PoolBuffer { get; set; }
|
||||||
|
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
Socket?.SafeClose();
|
Connection?.Disponse();
|
||||||
Socket = null;
|
Socket = null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PoolBuffer = Helper.EmptyArray;
|
PoolBuffer = Helper.EmptyArray;
|
||||||
|
|
||||||
DataBuffer.Clear(true);
|
DataBuffer.Clear(true);
|
||||||
|
|||||||
@@ -7,6 +7,11 @@ call npm install
|
|||||||
call npm run build
|
call npm run build
|
||||||
cd ../
|
cd ../
|
||||||
|
|
||||||
|
cd cmonitor.web.client
|
||||||
|
call npm install
|
||||||
|
call npm run build
|
||||||
|
cd ../
|
||||||
|
|
||||||
dotnet publish ./cmonitor.sas.service -c release -f net8.0 -o public/extends/ -r win-x64 -p:PublishTrimmed=true -p:TrimMode=partial --self-contained true -p:TieredPGO=true -p:DebugType=none -p:DebugSymbols=false -p:PublishSingleFile=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
|
dotnet publish ./cmonitor.sas.service -c release -f net8.0 -o public/extends/ -r win-x64 -p:PublishTrimmed=true -p:TrimMode=partial --self-contained true -p:TieredPGO=true -p:DebugType=none -p:DebugSymbols=false -p:PublishSingleFile=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
|
||||||
dotnet publish ./cmonitor.install.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
dotnet publish ./cmonitor.install.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
||||||
dotnet publish ./cmonitor.snatch.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
dotnet publish ./cmonitor.snatch.win -c release -f net8.0-windows -r win-x64 -o public/extends/ -p:PublishSingleFile=true --self-contained false
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ for %%r in (win-x64,win-x64-any) do (
|
|||||||
|
|
||||||
for %%r in (linux-x64,linux-x64-any) do (
|
for %%r in (linux-x64,linux-x64-any) do (
|
||||||
echo F|xcopy "public\\extends\\web\\*" "public\\publish\\%%r\\web\\*" /s /f /h /y
|
echo F|xcopy "public\\extends\\web\\*" "public\\publish\\%%r\\web\\*" /s /f /h /y
|
||||||
|
echo F|xcopy "public\\extends\\web-client\\*" "public\\publish\\%%r\\web-client\\*" /s /f /h /y
|
||||||
echo F|del "public\\publish\\%%r\\plugins"
|
echo F|del "public\\publish\\%%r\\plugins"
|
||||||
rd /s /q "public\\publish\\%%r\\plugins"
|
rd /s /q "public\\publish\\%%r\\plugins"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user